using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;

namespace JobTrackerApi.Models;

// Phase 3: relational children of CareerProfile — the editable master career profile.
// See docs/architecture/career-profile-model.md.
//
// Design notes shared by all child entities:
//   - OwnerUserId is denormalized so the tenant global query filter applies directly (same pattern
//     as every other owned entity).
//   - ItemKey carries the stable item id from the StructuredCvProfile blob, so a row keeps its
//     identity across imports/edits and future CV variants can reference "this experience".
//   - SortOrder makes ordering explicit (the blob relied on array position).
//   - List fields persist as JSON string columns exposed via [NotMapped] accessors. Children are
//     replaced wholesale on save, so
//     fine-grained change tracking of the lists is not needed.

/// <summary>Base fields every CareerProfile child shares.</summary>
public abstract class CareerChildEntity
{
    public int Id { get; set; }
    public int CareerProfileId { get; set; }
    public CareerProfile? CareerProfile { get; set; }
    public string OwnerUserId { get; set; } = string.Empty;

    /// <summary>Stable identity carried from StructuredCvProfile so references survive edits.</summary>
    public string ItemKey { get; set; } = string.Empty;

    public int SortOrder { get; set; }
}

internal static class CareerJson
{
    public static readonly JsonSerializerOptions Options = new(JsonSerializerDefaults.Web);

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

    public static string WriteList(List<string> items) => JsonSerializer.Serialize(items ?? new(), Options);
}

public sealed class CareerExperience : CareerChildEntity
{
    public string? Title { get; set; }
    public string? Company { get; set; }
    public string? Location { get; set; }
    // Free-text period kept alongside best-effort "YYYY-MM" normalization; neither replaces the other.
    public string? Start { get; set; }
    public string? End { get; set; }
    public string? StartDate { get; set; }
    public string? EndDate { get; set; }
    public bool IsCurrent { get; set; }

    public string BulletsJson { get; set; } = "[]";
    public string SkillsJson { get; set; } = "[]";

    [NotMapped]
    public List<string> Bullets
    {
        get => CareerJson.ReadList(BulletsJson);
        set => BulletsJson = CareerJson.WriteList(value);
    }

    [NotMapped]
    public List<string> Skills
    {
        get => CareerJson.ReadList(SkillsJson);
        set => SkillsJson = CareerJson.WriteList(value);
    }
}

public sealed class CareerEducation : CareerChildEntity
{
    public string? Qualification { get; set; }
    public string? QualificationLevel { get; set; }
    public string? Institution { get; set; }
    public string? Location { get; set; }
    public string? Start { get; set; }
    public string? End { get; set; }
    public string? StartDate { get; set; }
    public string? EndDate { get; set; }

    public string DetailsJson { get; set; } = "[]";

    [NotMapped]
    public List<string> Details
    {
        get => CareerJson.ReadList(DetailsJson);
        set => DetailsJson = CareerJson.WriteList(value);
    }
}

public sealed class CareerSkill : CareerChildEntity
{
    public string? Name { get; set; }
    public string? Category { get; set; }
    public string? Proficiency { get; set; }
}

public sealed class CareerProject : CareerChildEntity
{
    public string? Name { get; set; }
    public string? Role { get; set; }
    public string? Location { get; set; }
    public string? Start { get; set; }
    public string? End { get; set; }
    public string? StartDate { get; set; }
    public string? EndDate { get; set; }

    public string BulletsJson { get; set; } = "[]";
    public string SkillsJson { get; set; } = "[]";
    public string LinksJson { get; set; } = "[]";

    [NotMapped]
    public List<string> Bullets
    {
        get => CareerJson.ReadList(BulletsJson);
        set => BulletsJson = CareerJson.WriteList(value);
    }

    [NotMapped]
    public List<string> Skills
    {
        get => CareerJson.ReadList(SkillsJson);
        set => SkillsJson = CareerJson.WriteList(value);
    }

    [NotMapped]
    public List<string> Links
    {
        get => CareerJson.ReadList(LinksJson);
        set => LinksJson = CareerJson.WriteList(value);
    }
}

public sealed class CareerCertification : CareerChildEntity
{
    public string? Name { get; set; }
    public string? Issuer { get; set; }
    public string? Location { get; set; }
    public string? Date { get; set; }
    public string? DateNormalized { get; set; }

    public string DetailsJson { get; set; } = "[]";

    [NotMapped]
    public List<string> Details
    {
        get => CareerJson.ReadList(DetailsJson);
        set => DetailsJson = CareerJson.WriteList(value);
    }
}

public sealed class CareerLanguage : CareerChildEntity
{
    public string? Name { get; set; }
    public string? Level { get; set; }
    public string? Notes { get; set; }
}
