using DryIoc;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ProximaAnalizer.Controls.GasPanel
{
    /// <summary>
    /// Interaction logic for GasPanelTIN.xaml
    /// </summary>
    public partial class GasPanelTIN : UserControl
    {
        public GasPanelTIN()
        {
            InitializeComponent();

            foreach (var item in this.GetChildObjects<Button>(this.CirButton))
                CRBs.TryAdd(item.Name, item);

        }
        public readonly Dictionary<string, Button> CRBs = [];
        public readonly Dictionary<string, Button> RTBs = [];
        private static Brush Open = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#93C572"));
        private static Brush Close = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#00ffffff"));


        private void BTN_Click(object sender, RoutedEventArgs e)
        {
            if (sender is not Button btn || btn is null)
                return;

            //btn.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#90ff3724"));
            MessageBox.Show(btn.Name);
        }

        public List<T> GetChildObjects<T>(DependencyObject obj, bool deeper = false) where T : FrameworkElement
        {
            List<T> childList = [];

            for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
            {
                if (VisualTreeHelper.GetChild(obj, i) is not T child)
                    continue;

                childList.Add(child);
                if (deeper)
                    childList.AddRange(GetChildObjects<T>(child));
            }
            return childList;
        }


        public object? DataSource
        {
            get { return (object?)GetValue(DataSourceProperty); }
            set { SetValue(DataSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DataSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataSourceProperty =
            DependencyProperty.Register("DataSource", typeof(object), typeof(GasPanelTIN), new System.Windows.PropertyMetadata(default, DataSourceChangedCallback));


        private static void DataSourceChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is not GasPanelTIN gasPanel)
                return;

            if (e.NewValue is not KeyValuePair<string, object> data)
                return;

            if (data.Value is not ObservableDictionary<string, ObservableDictionary<string, object>> doubleData)
                return;
            switch (data.Key)
            {
                case "MFC":
                    foreach (var item in doubleData)
                    {
                        if (!item.Value.TryGetValue("Feedback", out object? value) || value is not float feedback)
                            continue;

                        if (gasPanel.RecButton.FindName($"{item.Key}_Value") is not TextBlock textBlock)
                            continue;
                        textBlock.Text = feedback.ToString();
                    }
                    break;

                case "Valve":
                    foreach (var item in doubleData)
                    {
                        if (!item.Value.TryGetValue("Status", out object? open) || open is not bool isOpen)
                            continue;
                        if (!gasPanel.CRBs.TryGetValue(item.Key, out Button? button) || button is null)
                            continue;

                        button.Background = isOpen switch
                        {
                            true => Open,
                            false => Close,
                        };
                    }
                    break;
                case "Sensor":
                    foreach (var item in doubleData)
                    {
                        if (!item.Value.TryGetValue("Value", out object? value) || value is not bool enable)
                            continue;

                        if (gasPanel.CirBorder.FindName($"{item.Key}") is Border border && border is not null)
                        {
                            border.Background = enable switch
                            {
                                true => Open,
                                false => Close,
                            };
                            continue;
                        }

                        if (gasPanel.RecButton.FindName($"{item.Key}") is Button button && button is not null)
                        {
                            button.Background = enable switch
                            {
                                true => Open,
                                false => Close,
                            };
                            continue;
                        }
                        //Debug.WriteLine(item.Key);
                    }
                    break;
                default:
                    break;
            }
        }
    }
}
