namespace Fast.Logic.Valuation.Pairs;

public class DealIdDatePair
{
    public int DealId;
    public DateOnly Date;

    public DealIdDatePair()
    {
    }

    public DealIdDatePair(int DealId, DateOnly Date)
    {
        this.DealId = DealId;
        this.Date = Date;
    }
}

public class IndexDatePair
{
    public int IndexId;
    public DateOnly PriceDate;

    public IndexDatePair()
    {
    }

    public IndexDatePair(int IndexId, DateOnly PriceDate)
    {
        this.IndexId = IndexId;
        this.PriceDate = PriceDate;
    }
}

public class DoubleDatePair
{
    public double Double;
    public DateOnly Date;

    public DoubleDatePair()
    {
    }

    public DoubleDatePair(double Double, DateOnly Date)
    {
        this.Double = Double;
        this.Date = Date;
    }
}

public class IntegerDatePair : IEquatable<IntegerDatePair>
{
    public int Integer;
    public DateOnly Date;

    public IntegerDatePair()
    {
    }

    public IntegerDatePair(int integer, DateOnly date)
    {
        Integer = integer;
        Date = date;
    }

    public override bool Equals(object? obj)
    {
        return Equals(obj as IntegerDatePair);
    }

    public bool Equals(IntegerDatePair? other)
    {
        return Integer == other?.Integer &&
               Date == other?.Date;
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(Integer, Date);
    }

    public static bool operator ==(IntegerDatePair pair1, IntegerDatePair pair2)
    {
        return EqualityComparer<IntegerDatePair>.Default.Equals(pair1, pair2);
    }

    public static bool operator !=(IntegerDatePair pair1, IntegerDatePair pair2)
    {
        return !(pair1 == pair2);
    }
}

public class DealIdDateComparer : IEqualityComparer<DealIdDatePair>
{
    public bool Equals(DealIdDatePair? x, DealIdDatePair? y)
    {
        return x?.DealId == y?.DealId && x?.Date == y?.Date;
    }

    public int GetHashCode(DealIdDatePair obj)
    {
        return obj.DealId.GetHashCode() ^ obj.Date.GetHashCode();
    }
}

public class IndexDateComparer : IEqualityComparer<IndexDatePair>
{
    public bool Equals(IndexDatePair? x, IndexDatePair? y)
    {
        return x?.IndexId == y?.IndexId && x?.PriceDate == y?.PriceDate;
    }

    public int GetHashCode(IndexDatePair obj)
    {
        return obj.IndexId.GetHashCode() ^ obj.PriceDate.GetHashCode();
    }
}

public class IndexWithSuffixKey : IEquatable<IndexWithSuffixKey>
{
    public int IndexId;
    public string Suffix = "";
    public int ProductId;
    public DateOnly Date;

    public IndexWithSuffixKey()
    {

    }

    public IndexWithSuffixKey(int indexId, string suffix, int productId, DateOnly date)
    {
        IndexId = indexId;
        Suffix = suffix;
        ProductId = productId;
        Date = date;
    }

    public override bool Equals(object? obj)
    {
        return Equals(obj as IndexWithSuffixKey);
    }

    public bool Equals(IndexWithSuffixKey? other)
    {
        return IndexId == other?.IndexId &&
               Suffix == other?.Suffix &&
               ProductId == other?.ProductId &&
               Date == other?.Date;
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(IndexId, Suffix, ProductId);
    }

    public static bool operator ==(IndexWithSuffixKey pair1, IndexWithSuffixKey pair2)
    {
        return EqualityComparer<IndexWithSuffixKey>.Default.Equals(pair1, pair2);
    }

    public static bool operator !=(IndexWithSuffixKey pair1, IndexWithSuffixKey pair2)
    {
        return !(pair1 == pair2);
    }
}
