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

namespace View_by_Distance.Shared.Models;

public class MappingFromItem : Properties.IMappingFromItem
{

    public DateTime[] ContainerDateTimes { init; get; }
    public int Id { init; get; }
    public FileHolder ImageFileHolder { init; get; }
    public bool? IsWrongYear { init; get; }
    public DateTime MinimumDateTime { init; get; }
    public string RelativePath { init; get; }
    public FileHolder ResizedFileHolder { init; get; }

    [JsonConstructor]
    public MappingFromItem(DateTime[] containerDateTimes, int id, FileHolder imageFileHolder, bool? isWrongYear, DateTime minimumDateTime, string relativePath, FileHolder resizedFileHolder)
    {
        ContainerDateTimes = containerDateTimes;
        Id = id;
        ImageFileHolder = imageFileHolder;
        IsWrongYear = isWrongYear;
        MinimumDateTime = minimumDateTime;
        RelativePath = relativePath;
        ResizedFileHolder = resizedFileHolder;
    }

    public override string ToString()
    {
        string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
        return result;
    }

    internal static MappingFromItem GetMappingFromItem(DateTime[] containerDateTimes, Item item, FileHolder? resizedFileHolder)
    {
        MappingFromItem result;
        bool? isWrongYear;
        DateTime minimumDateTime;
        if (item.Property?.Id is null)
            throw new NotSupportedException();
        if (resizedFileHolder is null)
            throw new NotSupportedException();
        minimumDateTime = Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
        (isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder, minimumDateTime);
        result = new(containerDateTimes, item.Property.Id.Value, item.ImageFileHolder, isWrongYear, minimumDateTime, item.RelativePath, resizedFileHolder);
        return result;
    }

}

public class MappingFromLocation : Properties.IMappingFromLocation
{

    public int AreaPermille { init; get; }
    public int ConfidencePercent { init; get; }
    public string DeterministicHashCodeKey { init; get; }
    public int NormalizedRectangle { init; get; }

    [JsonConstructor]
    public MappingFromLocation(int areaPermille, int confidencePercent, string deterministicHashCodeKey, int normalizedRectangle)
    {
        AreaPermille = areaPermille;
        ConfidencePercent = confidencePercent;
        DeterministicHashCodeKey = deterministicHashCodeKey;
        NormalizedRectangle = normalizedRectangle;
    }

    public override string ToString()
    {
        string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
        return result;
    }

}

public class MappingFromPerson : Properties.IMappingFromPerson
{

    public int? ApproximateYears { init; get; }
    public string DisplayDirectoryName { init; get; }
    public PersonBirthday PersonBirthday { init; get; }
    public string SegmentB { init; get; }

    [JsonConstructor]
    public MappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB)
    {
        ApproximateYears = approximateYears;
        DisplayDirectoryName = displayDirectoryName;
        PersonBirthday = personBirthday;
        SegmentB = segmentB;
    }

    public override string ToString()
    {
        string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
        return result;
    }

}

public class Mapping : Properties.IMapping
{

    protected int? _By;
    protected MappingFromPerson? _MappingFromPerson;
    public string? _SegmentC;
    protected SortingContainer? _SortingContainer;
    public int? By => _By;
    public MappingFromItem MappingFromItem { init; get; }
    public MappingFromLocation MappingFromLocation { init; get; }
    public MappingFromPerson? MappingFromPerson => _MappingFromPerson;
    public string? SegmentC => _SegmentC;
    public SortingContainer? SortingContainer => _SortingContainer;

    [JsonConstructor]
    public Mapping(int? by, MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation, MappingFromPerson? mappingFromPerson, string? segmentC, SortingContainer? sortingContainer)
    {
        _By = by;
        _SegmentC = segmentC;
        MappingFromItem = mappingFromItem;
        MappingFromLocation = mappingFromLocation;
        _MappingFromPerson = mappingFromPerson;
        _SortingContainer = sortingContainer;
    }

    public Mapping(MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation) :
        this(null, mappingFromItem, mappingFromLocation, null, null, null)
    { }

    public override string ToString()
    {
        string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
        return result;
    }

    public void UpdateMappingFromUnknownPerson(int? by, SortingContainer sortingContainer)
    {
        _By = by;
        _SortingContainer = sortingContainer;
    }

    public void UpdateMappingFromPerson(int? approximateYears, int? by, string displayDirectoryName, PersonBirthday personBirthday, string segmentB)
    {
        _By = by;
        _SortingContainer = null;
        _MappingFromPerson = new(approximateYears, displayDirectoryName, personBirthday, segmentB);
    }

    public void UpdateMappingFromPerson(int? approximateYears, int? by, string displayDirectoryName, PersonBirthday personBirthday, string segmentB, string segmentC, SortingContainer sortingContainer)
    {
        _By = by;
        _SegmentC = segmentC;
        _SortingContainer = sortingContainer;
        _MappingFromPerson = new(approximateYears, displayDirectoryName, personBirthday, segmentB);
    }

}