using System.Text.Json;
using System.Text.Json.Serialization;

namespace JobTrackerApi.Models;

// The "lens" a CvVariant stores. Deliberately all-optional + defaulted so an empty settings object
// renders a sensible default CV straight from the master profile. Overrides are keyed by the master
// profile's stable ItemKeys so career data is referenced, never copied.
public sealed class CvVariantSettings
{
    public string ThemeId { get; set; } = "modern";

    // Theme overrides (null => use the theme's own value).
    public string? AccentColor { get; set; }
    public string? HeadingFont { get; set; }
    public string? BodyFont { get; set; }
    public string? Density { get; set; }      // compact | balanced | roomy
    public string? PageSize { get; set; }     // a4 | letter
    public string? DateFormat { get; set; }   // display hint for the frontend; renderer uses source strings
    public string? Language { get; set; }
    public string? Headline { get; set; }     // override the contact headline for this variant

    public bool ShowPhoto { get; set; }
    public bool ShowPageNumbers { get; set; }
    public bool ShowIcons { get; set; } = true;

    // Section order + visibility + optional renamed heading. Empty => default order, all visible.
    public List<CvSectionSetting> Sections { get; set; } = new();

    // Per-item overrides keyed by ItemKey (job/education/project/certification stable id).
    public Dictionary<string, CvItemOverride> Overrides { get; set; } = new();

    // Extra sections unique to this variant (not in the master profile).
    public List<CvCustomSectionSetting> CustomSections { get; set; } = new();
}

public sealed class CvSectionSetting
{
    public string Key { get; set; } = string.Empty; // summary|skills|experience|education|projects|certifications|languages|interests|links|custom:<k>
    public bool Hidden { get; set; }
    public string? Title { get; set; } // renamed heading
    // Explicit entry order for this section, as a list of item ItemKeys. Entries not listed keep their
    // master order and come last. Null => master profile order. Lets a variant reorder entries without
    // touching the master profile.
    public List<string>? ItemOrder { get; set; }
}

public sealed class CvItemOverride
{
    public bool Hidden { get; set; }
    public string? Title { get; set; }
    public string? Subtitle { get; set; }
    public List<string>? Bullets { get; set; } // null => use master bullets; non-null => replace for this variant only
}

public sealed class CvCustomSectionSetting
{
    public string Key { get; set; } = string.Empty;
    public string? Title { get; set; }
    public List<string> Items { get; set; } = new();
    public bool Hidden { get; set; }
}

public static class CvVariantSettingsJson
{
    private static readonly JsonSerializerOptions Options = new(JsonSerializerDefaults.Web)
    {
        PropertyNameCaseInsensitive = true,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
    };

    public static string Serialize(CvVariantSettings? settings) =>
        JsonSerializer.Serialize(Normalize(settings), Options);

    public static CvVariantSettings Deserialize(string? json)
    {
        if (string.IsNullOrWhiteSpace(json)) return new CvVariantSettings();
        try { return Normalize(JsonSerializer.Deserialize<CvVariantSettings>(json, Options)); }
        catch { return new CvVariantSettings(); }
    }

    public static CvVariantSettings Normalize(CvVariantSettings? s)
    {
        s ??= new CvVariantSettings();
        s.ThemeId = string.IsNullOrWhiteSpace(s.ThemeId) ? "modern" : s.ThemeId.Trim().ToLowerInvariant();
        s.Sections ??= new();
        s.Overrides ??= new();
        s.CustomSections ??= new();
        return s;
    }
}
