using System.Text.Json.Serialization;

namespace GerbilManagerWebAPI.Import
{
    // ---- Source shapes (tools/import/output JSON, produced by extract.py) ----

    public sealed class SourceAnimal
    {
        public string Id { get; set; } = "";
        public string Name { get; set; } = "";
        public List<string> NameVariants { get; set; } = new();
        public string Dob { get; set; } = "";
        public string Death { get; set; } = "";
        public string? Gender { get; set; }
        public string Farbschlag { get; set; } = "";
        public List<string> FarbschlagVariants { get; set; } = new();
        public SourceGenotype Genotype { get; set; } = new();
        public string Zucht { get; set; } = "";
        public string ZuchtCanon { get; set; } = "";       // declension-folded Zucht key (residency rule a)
        public List<SourceParentRef> ParentRefs { get; set; } = new();
        public List<string> Photos { get; set; } = new();
        public List<string> SourceFiles { get; set; } = new();
        public bool Conflict { get; set; }
        public SourceLitterRef? LitterRef { get; set; }

        // GEN-3b normalization: hearing/deaf phenotype flag (null = not stated) and
        // provenance/breeding tags (WFNZ/RV/GV/DP) — neither is genotype.
        public bool? Deaf { get; set; }
        public List<string> Tags { get; set; } = new();

        // Set by extract.py when a human conflict-decision (conflict-decisions.json) un-quarantined
        // this animal (its genotype/farbschlag are then authoritative). For reporting.
        public bool ResolvedByDecision { get; set; }
    }

    public sealed class SourceGenotype
    {
        public Dictionary<string, List<string>> Mapped8locus { get; set; } = new();
        public string RawGenotype { get; set; } = "";
        public List<string> UnmappedTokens { get; set; } = new();
    }

    public sealed class SourceParentRef
    {
        public string Name { get; set; } = "";
        public string Dob { get; set; } = "";
        public string RoleGuess { get; set; } = "";       // "father" | "mother"
        public string Method { get; set; } = "";          // e.g. "chart-position"
        public string Confidence { get; set; } = "";       // "hoch" | "medium" | "niedrig"
    }

    public sealed class SourceLitterRef
    {
        public string LitterId { get; set; } = "";
        public string Method { get; set; } = "";
        public string Confidence { get; set; } = "";       // "hoch" | "niedrig" | (ambiguous => candidates)
        public List<string>? Candidates { get; set; }
    }

    public sealed class SourceLitter
    {
        public string Id { get; set; } = "";
        public string LitterId { get; set; } = "";
        public string Date { get; set; } = "";
        public string DamName { get; set; } = "";
        public string SireName { get; set; } = "";
        public int? TotalBorn { get; set; }
        public string Zuchtnummer { get; set; } = "";
        public string Note { get; set; } = "";
        public List<string> Warnings { get; set; } = new();
    }

    // ---- Report shapes (Julian-readable: counts per category + samples) ----

    public sealed record ImportReport(
        bool Executed,
        LitterSummary Litters,
        AnimalSummary Animals,
        PhotoSummary Photos,
        IReadOnlyList<string> Samples,
        IReadOnlyList<string> Notes,
        ResidencySummary? Residency = null);

    /// <summary>Bestand (resident) vs external pedigree ancestors; FlippedByParentRule = foreign-
    /// Zuchtname animals made resident because they parented a Clan offspring (rule b).
    /// HerkunftBackfilled = resident animals whose null OriginBreeder was filled (safe, no overwrite).
    /// FarbschlagWouldRebackfill = already-imported animals with a stale ColorVariety that the
    /// current extract would update (no-op counter until the safety mechanism is ratified).</summary>
    public sealed record ResidencySummary(int Resident, int External, int FlippedByParentRule,
        int HerkunftBackfilled = 0, int FarbschlagWouldRebackfill = 0);

    public sealed record LitterSummary(int InSource, int Created, int AlreadyImported,
        int DerivedFromChart = 0, int DerivedSkipped = 0, int ParentFksDropped = 0,
        int ParentFksBackfilled = 0, int WithoutDate = 0);

    public sealed record AnimalSummary(
        int InSource,
        int Created,
        int LinkedToLitter,
        int FarbschlagMatched,
        int FarbschlagUnmatched,
        int AlreadyImported,
        QuarantineSummary Quarantined,
        int ParentLinksFromChart = 0,
        int ConflictsResolvedByDecision = 0,
        int FarbschlagDerivedFromGenotype = 0);

    public sealed record QuarantineSummary(
        int Conflicts,
        int Stubs,
        int DateOnlyLinks,
        int AmbiguousLinks,
        int Total);

    public sealed record PhotoSummary(int Attached, int SourceFilesMissing);
}
