using System.Collections.ObjectModel;
using Microsoft.VisualBasic.Logging;
using System.Drawing.Drawing2D;
using OpenCvSharp.Extensions;
using VisionBuilder.UI.Common.ViewModel;
using VisionBuilder.UI.Common.ViewModel.Classes;
using System.Collections.Specialized;

namespace VisionBuilder.UI.Windows.Components
{
    public partial class ErrorPreview : UserControl
    {
        private ErrorsVM _errorPreviewVM;

        // Keep track of subscription to avoid duplicate handlers
        private ObservableCollection<ErrorData> _subscribedErrors;

        public void SetViewModel(ErrorsVM errorPreviewVm)
        {
            // Unsubscribe from previous Errors collection if needed
            if (_subscribedErrors != null)
                _subscribedErrors.CollectionChanged -= Errors_CollectionChanged;

            _errorPreviewVM = errorPreviewVm;

            if (_errorPreviewVM != null)
            {
                _subscribedErrors = _errorPreviewVM.Errors;
                _subscribedErrors.CollectionChanged += Errors_CollectionChanged;

                // Initial sync: clear and add all
                flowLayoutPanel1.Controls.Clear();
                foreach (var error in _subscribedErrors)
                {
                    AddErrorPreviewInternal(error);
                }
            }
        }

        public ErrorPreview()
        {
            InitializeComponent();
        }

        private Font _numberedFont = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular);
        private void AddErrorPreviewInternal(ErrorData errorData)
        {
            var pb = new PictureBox();
            var width = 293 / 1.6f;
            var height = 220 / 1.6f;
            pb.Size = new Size((int)width, (int)height + 20);
            pb.SizeMode = PictureBoxSizeMode.Zoom;
            pb.Margin = new Padding(5,0,5,5);

            var numberedImage = new Bitmap((int)width, (int)height + 20);
            var text = errorData.Title;

            using (Graphics g = Graphics.FromImage(numberedImage))
            {
                g.Clear(Color.White);

                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                try
                {
                    g.DrawImage(errorData.ImageAnalysis.ToBitmap(), 0, 0, width, height);
                }
                catch (Exception ex)
                {

                }

                var measure = g.MeasureString(text, _numberedFont);
                g.TranslateTransform(width / 2 - measure.Width / 2, height);

                g.DrawString(text, _numberedFont, Brushes.Black, 0, 0);
            }
            pb.Image = numberedImage;
            pb.SizeMode = PictureBoxSizeMode.Zoom;
            pb.Cursor = Cursors.Hand;
            pb.Click += (sender, args) =>
            {
                _errorPreviewVM.ShowImage(errorData);
            };
            var tag = (errorData, text);
            pb.Tag = tag;
            flowLayoutPanel1.Controls.Add(pb);
            flowLayoutPanel1.Controls.SetChildIndex(pb, 0);

            try
            {
                flowLayoutPanel1.Refresh();
            }
            catch
            {

            }
        }

        private void Errors_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new NotifyCollectionChangedEventHandler(Errors_CollectionChanged), sender, e);
                return;
            }

            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                foreach (ErrorData newError in e.NewItems)
                {
                    AddErrorPreviewInternal(newError);
                }
            }
            else if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                foreach (ErrorData oldError in e.OldItems)
                {
                    // Remove the PictureBox whose Tag contains the oldError
                    foreach (Control ctrl in flowLayoutPanel1.Controls)
                    {
                        if (ctrl is PictureBox pb && pb.Tag is ValueTuple<ErrorData, string> tag && tag.Item1 == oldError)
                        {
                            flowLayoutPanel1.Controls.Remove(pb);
                            pb.Dispose();
                            break;
                        }
                    }
                }
            }
            else if (e.Action == NotifyCollectionChangedAction.Reset)
            {
                flowLayoutPanel1.Controls.Clear();
            }
            
        }
    }
}
