using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Fast.Models.Crude;

public class SosItem
{
    [Display(Name = "Supply CP", Description = "100")] public string SupplyCounterparty { get; set; } = "";
    [Display(Name = "Source Meter", Description = "100")] public string SourceMeter { get; set; } = "";
    [Display(Name = "Receipt Meter", Description = "100")] public string ReceiptMeter { get; set; } = "";
    [Display(Name = "Receipt Point", Description = "100")] public string ReceiptPoint { get; set; } = "";
    [Display(Name = "Supply Ticket", Description = "100")] public string SupplyTicket { get; set; } = "";
    [Display(Name = "Source Ticket", Description = "100")] public string SourceTicket { get; set; } = "";
    [Display(Name = "Activity #", Description = "100")] public string ActivityNum { get; set; } = "";
    [Display(Name = "Notes", Description = "100")] public string Notes { get; set; } = "";
    [Display(Name = "Source Notes", Description = "100")] public string SourceNotes { get; set; } = "";
    [Display(Name = "Deal Volume", Description = "100")] public double DealVolume { get; set; }
    [NotMapped][Display(Name = "Nom Receipt Volume", Description = "100")] public double NomReceiptVol { get; set; }
    [NotMapped] public double DeliveryVol { get; set; }
    [Display(Name = "P/L Contract", Description = "100")] public int? PipeContractId { get; set; }
    public string DealType { get; set; } = "";
    [NotMapped][Display(Name = "Delivery Point", Description = "100")] public string DeliveryPoint { get; set; } = "";
    [NotMapped] public int? TransferSumVol { get; set; }
    [NotMapped] public List<SosNom> Noms { get; set; } = new();
    [NotMapped] public HashSet<string> ModifiedProps { get; set; } = new();
    [NotMapped] public string Guid { get; set; } = System.Guid.NewGuid().ToString("N")[..8];
    public int? SupplyNomId { get; set; }
    public int? DealId { get; set; }
    public int? ReceiptPointId { get; set; }
    public int? ReceiptMeterId { get; set; }
    public int? TransferDealId { get; set; }
    public int? SourceMeterId { get; set; }
    [NotMapped] public List<int> SourceMeterIds { get; set; } = new();
    public int? SupplyCounterpartyId { get; set; }
    public double? SourceDealVolume { get; set; }
    public bool IsEnteredFromSos { get; set; }
    public bool IsHidden { get; set; }
    public bool IsTransferToTransfer { get; set; }
    [NotMapped] public bool IsSupplyClone { get; set; }
    public DateTime? CreatedTime { get; set; }
    public DateTime? SavedTime { get; set; }
    public int? SourceDealProduct { get; set; }

    public bool HasSupplyChanges()
    {
        var hasChanges = this.ModifiedProps.Count > 0;
        return hasChanges;
    }

    public bool HasNomChanges()
    {
        var hasChanges = Noms.Any(n => n.IsModified);
        return hasChanges;
    }

    public override string ToString()
    {
        return $"SupplyCounterparty: {SupplyCounterparty}, SourceMeter: {SourceMeter}, ReceiptMeter: {ReceiptMeter}, " +
               $"ReceiptPoint: {ReceiptPoint}, SupplyTicket: {SupplyTicket}, SourceTicket: {SourceTicket}, ActivityNum: {ActivityNum}, " +
               $"Notes: {Notes}, SourceNotes: {SourceNotes}, DealVolume: {DealVolume}, NomReceiptVol: {NomReceiptVol}, DeliveryVol: {DeliveryVol}, " +
               $"PipeContractId: {PipeContractId}, DealType: {DealType}, DeliveryPoint: {DeliveryPoint}, TransferSumVol: {TransferSumVol}, " +
               $"Noms: {string.Join(", ", Noms)}, ModifiedProps: {string.Join(", ", ModifiedProps)}, Guid: {Guid}, SupplyNomId: {SupplyNomId}, " +
               $"DealId: {DealId}, ReceiptPointId: {ReceiptPointId}, ReceiptMeterId: {ReceiptMeterId}, TransferDealId: {TransferDealId}, " +
               $"SourceMeterId: {SourceMeterId}, SourceMeterIds: {string.Join(", ", SourceMeterIds)}, SupplyCounterpartyId: {SupplyCounterpartyId}, " +
               $"SourceDealVolume: {SourceDealVolume}, IsEnteredFromSos: {IsEnteredFromSos}, IsHidden: {IsHidden}, IsTransferToTransfer: {IsTransferToTransfer}, " +
               $"IsSupplyClone: {IsSupplyClone}, CreatedTime: {CreatedTime}, SavedTime: {SavedTime}, SourceDealProduct: {SourceDealProduct}";
    }

    public override bool Equals(object? obj)
    {
        if (obj == null || GetType() != obj.GetType())
            return false;

        var other = (SosItem)obj;
        return SupplyCounterparty == other.SupplyCounterparty
            && SourceMeter == other.SourceMeter
            && ReceiptMeter == other.ReceiptMeter
            && ReceiptPoint == other.ReceiptPoint
            && SupplyTicket == other.SupplyTicket
            && SourceTicket == other.SourceTicket
            && ActivityNum == other.ActivityNum
            && Notes == other.Notes
            && SourceNotes == other.SourceNotes
            && DealVolume == other.DealVolume
            && NomReceiptVol == other.NomReceiptVol
            && DeliveryVol == other.DeliveryVol
            && PipeContractId == other.PipeContractId
            && DealType == other.DealType
            && DeliveryPoint == other.DeliveryPoint
            && TransferSumVol == other.TransferSumVol
            && Noms.SequenceEqual(other.Noms)
            && ModifiedProps.SetEquals(other.ModifiedProps)
            // && Guid == other.Guid // Exclude Guid from comparison
            && SupplyNomId == other.SupplyNomId
            && DealId == other.DealId
            && ReceiptPointId == other.ReceiptPointId
            && ReceiptMeterId == other.ReceiptMeterId
            && TransferDealId == other.TransferDealId
            && SourceMeterId == other.SourceMeterId
            && SourceMeterIds.SequenceEqual(other.SourceMeterIds)
            && SupplyCounterpartyId == other.SupplyCounterpartyId
            && SourceDealVolume == other.SourceDealVolume
            && IsEnteredFromSos == other.IsEnteredFromSos
            && IsHidden == other.IsHidden
            && IsTransferToTransfer == other.IsTransferToTransfer
            && IsSupplyClone == other.IsSupplyClone
            && CreatedTime == other.CreatedTime
            && SavedTime == other.SavedTime
            && SourceDealProduct == other.SourceDealProduct;
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(
            HashCode.Combine(SupplyCounterparty, SourceMeter, ReceiptMeter, ReceiptPoint, SupplyTicket, SourceTicket, ActivityNum),
            HashCode.Combine(Notes, SourceNotes, DealVolume, NomReceiptVol, DeliveryVol, PipeContractId, DealType),
            HashCode.Combine(DeliveryPoint, TransferSumVol, Noms, ModifiedProps, SourceMeterIds, SupplyCounterpartyId, SourceDealVolume),
            // Guid, // Exclude Guid from hash code calculation
            HashCode.Combine(IsEnteredFromSos, IsHidden, IsTransferToTransfer, IsSupplyClone, CreatedTime, SavedTime, SourceDealProduct)
        );
    }

}
