using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using VisionBuilder.UI.Common;
using VisionBuilder.UI.Common.ViewModel.Classes;

namespace VisionBuilder.UI.Windows.Components
{
    public partial class SingleCameraControl : UserControl
    {
        private SingleCameraVM _singleCameraVm;
        private readonly Dictionary<string, Control> _dynamicButtonControls = new();

        public void SetViewModel(SingleCameraVM singleCameraVm)
        {
            _singleCameraVm = singleCameraVm;
            singleCameraVm.SynchronizationContext = SynchronizationContext.Current;
            this.previewWindow1.SetViewModel(singleCameraVm.PreviewVm);
            this.errorPreview1.SetViewModel(singleCameraVm.ErrorsVm);
            this.stats1.SetViewModel(singleCameraVm.StatisticsVm);

            SetBindings();
            _singleCameraVm.PropertyChanged += SingleCameraVm_PropertyChanged;

            _singleCameraVm.DynamicButtons.CollectionChanged += DynamicButtons_CollectionChanged;
            foreach (var btn in _singleCameraVm.DynamicButtons)
                AddDynamicButton(btn);
        }

        private void SingleCameraVm_PropertyChanged(object? sender, PropertyChangedEventArgs e)
        {

        }

        private void SetBindings()
        {
            btnStart.Command=_singleCameraVm.StartCommand;
            btnStop.Command=_singleCameraVm.StopCommand;
            btnSelectRecipe.Command=_singleCameraVm.SelectRecipeCommand;
            btnPause.Command=_singleCameraVm.PauseCommand;
            btnResume.Command=_singleCameraVm.ResumeCommand;

            lblCameraName.DataBindings.Add("Text", _singleCameraVm, nameof(_singleCameraVm.CameraLabelAndStatus), true, DataSourceUpdateMode.OnPropertyChanged);
            btnSelectRecipe.DataBindings.Add("Text", _singleCameraVm, nameof(_singleCameraVm.CurrentRecipeName), true, DataSourceUpdateMode.OnPropertyChanged);
            btnStart.DataBindings.Add(nameof(btnStart.Visible), _singleCameraVm, nameof(_singleCameraVm.CanStart), true, DataSourceUpdateMode.OnPropertyChanged);
            btnStop.DataBindings.Add(nameof(btnStop.Visible), _singleCameraVm, nameof(_singleCameraVm.CanStop), true, DataSourceUpdateMode.OnPropertyChanged);
            btnSelectRecipe.DataBindings.Add(nameof(btnSelectRecipe.Primary), _singleCameraVm, nameof(_singleCameraVm.RecipeNotSelected), true, DataSourceUpdateMode.OnPropertyChanged);
            btnPause.DataBindings.Add(nameof(btnPause.Visible), _singleCameraVm, nameof(_singleCameraVm.CanPause), true, DataSourceUpdateMode.OnPropertyChanged);
            btnResume.DataBindings.Add(nameof(btnResume.Visible), _singleCameraVm, nameof(_singleCameraVm.CanResume), true, DataSourceUpdateMode.OnPropertyChanged);

            btnHotReload.Command = _singleCameraVm.HotReloadCommand;
            btnHotReload.DataBindings.Add(nameof(btnHotReload.Visible), _singleCameraVm, nameof(_singleCameraVm.CanHotReload), true, DataSourceUpdateMode.OnPropertyChanged);

        }

        private void DynamicButtons_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    foreach (ButtonDefinition btn in e.NewItems!)
                        AddDynamicButton(btn);
                    break;
                case NotifyCollectionChangedAction.Remove:
                    foreach (ButtonDefinition btn in e.OldItems!)
                        RemoveDynamicButton(btn);
                    break;
                case NotifyCollectionChangedAction.Reset:
                    foreach (var ctrl in _dynamicButtonControls.Values)
                        flowLayoutPanel2.Controls.Remove(ctrl);
                    _dynamicButtonControls.Clear();
                    break;
            }
        }

        private void AddDynamicButton(ButtonDefinition buttonDef)
        {
            var btn = new MaterialSkin.Controls.MaterialRaisedButton
            {
                Text = buttonDef.Title,
                Size = new Size(201, 85),
                Font = new Font("Segoe UI", 9F, FontStyle.Bold),
                DrawBorder = true,
                Primary = buttonDef.Type == EButtonType.Toggle && buttonDef.IsToggled,
                Visible = buttonDef.IsVisible
            };

            btn.Click += (_, _) =>
            {
                buttonDef.Execute();
                if (buttonDef.Type == EButtonType.Toggle)
                    btn.Primary = buttonDef.IsToggled;
            };

            buttonDef.PropertyChanged += (_, args) =>
            {
                if (args.PropertyName == nameof(ButtonDefinition.IsVisible))
                    btn.Visible = buttonDef.IsVisible;
                else if (args.PropertyName == nameof(ButtonDefinition.IsToggled))
                    btn.Primary = buttonDef.IsToggled;
            };

            flowLayoutPanel2.Controls.Add(btn);
            _dynamicButtonControls[buttonDef.Key] = btn;
        }

        private void RemoveDynamicButton(ButtonDefinition buttonDef)
        {
            if (_dynamicButtonControls.TryGetValue(buttonDef.Key, out var ctrl))
            {
                flowLayoutPanel2.Controls.Remove(ctrl);
                _dynamicButtonControls.Remove(buttonDef.Key);
            }
        }

        public SingleCameraControl()
        {

            InitializeComponent();
        }
    }
}
