using System.Text.Json; using System.Text.Json.Serialization; namespace JobTrackerApi.Models; // A reviewed snapshot, never a live link to profile or CV settings. public sealed class CoverLetterDocumentSettings { public int SchemaVersion { get; set; } = 1; [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public int? DesignVersion { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? HeadingFont { get; set; } public string Language { get; set; } = "en"; public string SenderName { get; set; } = ""; public string SenderTitle { get; set; } = ""; public string SenderEmail { get; set; } = ""; public string SenderPhone { get; set; } = ""; public string SenderLocation { get; set; } = ""; public string Recipient { get; set; } = ""; public string Subject { get; set; } = ""; public string Date { get; set; } = ""; public string ThemeId { get; set; } = "modern"; public string? AccentColor { get; set; } public string? BodyFont { get; set; } public double? BaseFontSizePt { get; set; } public double? LineHeight { get; set; } public double? PageMarginMm { get; set; } public string PageSize { get; set; } = "a4"; public int? SourceCvId { get; set; } } public static class CoverLetterDocumentSettingsJson { private static readonly JsonSerializerOptions Options = new(JsonSerializerDefaults.Web); public static string Serialize(CoverLetterDocumentSettings? settings) => JsonSerializer.Serialize(Normalize(settings), Options); public static CoverLetterDocumentSettings Deserialize(string? json) { try { return Normalize(string.IsNullOrWhiteSpace(json) ? null : JsonSerializer.Deserialize(json, Options)); } catch (JsonException) { return Normalize(null); } } public static CoverLetterDocumentSettings Normalize(CoverLetterDocumentSettings? value) { value ??= new(); var theme = CvThemeCatalog.Resolve(value.ThemeId, value.DesignVersion); var style = CvVariantSettingsJson.Normalize(new() { AccentColor = value.AccentColor, BodyFont = value.BodyFont, HeadingFont = value.HeadingFont, BaseFontSizePt = value.BaseFontSizePt, LineHeight = value.LineHeight, PageMarginMm = value.PageMarginMm, }); static string Text(string? text, int limit) => (text ?? "")[..Math.Min(text?.Length ?? 0, limit)]; return new() { SchemaVersion = 1, ThemeId = theme.Id, DesignVersion = value.DesignVersion is 1 or 2 ? value.DesignVersion : null, HeadingFont = value.DesignVersion == 2 ? style.HeadingFont ?? theme.HeadingFont : null, Language = value.Language?.Trim().ToLowerInvariant() is "nb" or "nb-no" ? "nb-NO" : "en", SenderName = Text(value.SenderName, 300), SenderTitle = Text(value.SenderTitle, 300), SenderEmail = Text(value.SenderEmail, 300), SenderPhone = Text(value.SenderPhone, 100), SenderLocation = Text(value.SenderLocation, 300), Recipient = Text(value.Recipient, 2000), Subject = Text(value.Subject, 500), Date = Text(value.Date, 100), AccentColor = style.AccentColor ?? theme.Accent, BodyFont = style.BodyFont ?? theme.BodyFont, BaseFontSizePt = style.BaseFontSizePt ?? theme.BodySizePt, LineHeight = style.LineHeight ?? theme.LineHeight, PageMarginMm = style.PageMarginMm ?? theme.PageMarginMm, PageSize = string.Equals(value.PageSize, "letter", StringComparison.OrdinalIgnoreCase) ? "letter" : "a4", SourceCvId = value.SourceCvId is > 0 ? value.SourceCvId : null, }; } }