namespace HistoryView.Controls.Configs;

public partial class TempConfigComparision : UserControl
{
    public TempConfigComparision()
    {
        InitializeComponent();
        this.Comparision = [];
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        FindVisualChildren.Find<Expander>(this.Items).ForEach(t => t.IsExpanded = false);
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {

        FindVisualChildren.Find<Expander>(this.Items).ForEach(t => t.IsExpanded = true);
    }

    public TempConfig Source
    {
        get { return (TempConfig)GetValue(SourceProperty); }
        set { SetValue(SourceProperty, value); }
    }

    public static readonly DependencyProperty SourceProperty =
        DependencyProperty.Register("Source", typeof(TempConfig), typeof(TempConfigComparision), new PropertyMetadata(default, SourceChangedCallback));

    public TempConfig Target
    {
        get { return (TempConfig)GetValue(TargetProperty); }
        set { SetValue(TargetProperty, value); }
    }

    public static readonly DependencyProperty TargetProperty =
        DependencyProperty.Register("Target", typeof(TempConfig), typeof(TempConfigComparision), new PropertyMetadata(default, TargetChangedCallback));

    private static void SourceChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is not TempConfigComparision act)
            return;

        if (e.NewValue is not TempConfig config)
            return;

        if (config.Mini8sConfig is null)
            return;

        foreach (var mini8 in config.Mini8sConfig)
        {
            act.Comparision[mini8.Key] ??= new();
            act.Comparision[mini8.Key].Index = mini8.Key;
            act.Comparision[mini8.Key].Source = mini8.Value;
        }

        Compare(act);
    }
    private static void TargetChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is not TempConfigComparision act)
            return;

        if (e.NewValue is not TempConfig config)
            return;

        if (config.Mini8sConfig is null)
            return;

        foreach (var mini8 in config.Mini8sConfig)
        {
            act.Comparision[mini8.Key] ??= new();
            act.Comparision[mini8.Key].Index = mini8.Key;
            act.Comparision[mini8.Key].Target = mini8.Value;
        }

        Compare(act);
    }


    public ObservableDictionary<byte, TempConfigComparisonData> Comparision
    {
        get { return (ObservableDictionary<byte, TempConfigComparisonData>)GetValue(ComparisionProperty); }
        set { SetValue(ComparisionProperty, value); }
    }

    public static readonly DependencyProperty ComparisionProperty =
        DependencyProperty.Register("Comparision", typeof(ObservableDictionary<byte, TempConfigComparisonData>), typeof(TempConfigComparision), new PropertyMetadata(default));

    private static void Compare(TempConfigComparision act)
    {
        foreach (TempConfigComparisonData tempConfigComparisonData in act.Comparision.Values)
        {
            if (tempConfigComparisonData.Source is null || tempConfigComparisonData.Target is null)
            {
                tempConfigComparisonData.IsSame = null;
                return;
            }

            if (tempConfigComparisonData.Source.ChannelConfig.Count != tempConfigComparisonData.Target.ChannelConfig.Count)
            {
                tempConfigComparisonData.IsSame = false;
                continue;
            }


            foreach (var tempConfigSubMini8Source in tempConfigComparisonData.Source.ChannelConfig)
            {
                if (!tempConfigComparisonData.Target.ChannelConfig.TryGetValue(tempConfigSubMini8Source.Key, out var tempConfigSubMini8Target) || tempConfigSubMini8Target is null)
                {
                    tempConfigComparisonData.IsSame = false;
                    continue;
                }

                if (!CompareChannel(tempConfigSubMini8Source.Value, tempConfigSubMini8Target))
                {
                    tempConfigComparisonData.IsSame = false;
                    continue;
                }
                tempConfigComparisonData.IsSame = true;
            }

        }
    }

    private static bool CompareChannel(TempConfigSubChannel source, TempConfigSubChannel target)
    {
        if (source.SetPoint != target.SetPoint)
            return false;
        if (source.Caps != target.Caps)
            return false;
        if (source.Floor != target.Floor)
            return false;
        if (source.Running_P != target.Running_P)
            return false;
        if (source.Running_I != target.Running_I)
            return false;
        if (source.Running_D != target.Running_D)
            return false;
        if (source.SetpointUpRate != target.SetpointUpRate)
            return false;
        if (source.SetpointDownRate != target.SetpointDownRate)
            return false;
        return true;
    }

}

public partial class TempConfigComparisonData : ObservableObject
{
    [ObservableProperty]
    private byte _Index;
    [ObservableProperty]
    private bool? _IsSame;

    [ObservableProperty]
    private TempConfigSubMini8? _Source;
    [ObservableProperty]
    private TempConfigSubMini8? _Target;
}