using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MaterialSkin.Controls
{
    public partial class MaterialLoader : MaterialForm
    {
        private static MaterialLoader _instance;
        private static Thread _loaderThread;
        private static ManualResetEvent _instanceReadyEvent = new ManualResetEvent(false);
        private readonly Dictionary<string, (MaterialProgressBar ProgressBar, Label Label)> _loadingProcesses;

        private MaterialLoader()
        {
            InitializeComponent();
            RemoveMessageFilter();
            _loadingProcesses = new Dictionary<string, (MaterialProgressBar, Label)>();
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.StartPosition = FormStartPosition.CenterScreen;
        }

        public static MaterialLoader Instance
        {
            get
            {
                if (_instance == null || _instance.IsDisposed)
                {
                    _instanceReadyEvent.Reset();
                    _loaderThread = new Thread(() =>
                    {
                        _instance = new MaterialLoader();
                        _instance.Shown += (_, _) =>
                        {
                            _instanceReadyEvent.Set();
                        };
                        Application.Run(_instance);
                    });
                    _loaderThread.SetApartmentState(ApartmentState.STA);
                    _loaderThread.Start();
                    _instanceReadyEvent.WaitOne();
                }
                return _instance;
            }
        }

        public void StartLoading(string title)
        {
            if (_instance == null || !_instance.Visible)
            {
                Instance.Invoke(new Action(() =>
                {
                    Instance.Show();
                    Instance.Visible= true;
                }));
            }

            Instance.Invoke(new Action(() =>
            {
                if (_loadingProcesses.ContainsKey(title))
                {
                    return; // Prevent duplicate loading processes with the same title
                }

                var progressBar = new MaterialProgressBar
                {
                    Width = Instance.ClientSize.Width - 20,
                    Height = 20,
                    Top = 50 + (_loadingProcesses.Count * 30),
                    Left = 10,
                    Style = ProgressBarStyle.Marquee,
                    MarqueeAnimationSpeed = 30,
                    Value = 50,
                    BackColor = Color.White
                };

                var label = new Label
                {
                    Text = title,
                    AutoSize = true,
                    Top = progressBar.Top - 20,
                    Left = progressBar.Left,
                    BackColor = Color.White
                };

                _loadingProcesses[title] = (progressBar, label);
                Instance.Controls.Add(label);
                Instance.Controls.Add(progressBar);
                Instance.Height = 50 + (_loadingProcesses.Count * 30);
                Instance.Refresh();
            }));
        }

        public void FinishLoading(string title)
        {
            if (_instance == null)
            {
                return;
            }

            Instance.Invoke(new Action(() =>
            {
                if (_loadingProcesses.TryGetValue(title, out var components))
                {
                    Instance.Controls.Remove(components.ProgressBar);
                    Instance.Controls.Remove(components.Label);
                    _loadingProcesses.Remove(title);
                    RearrangeProgressBarsAndLabels();
                }

                if (_loadingProcesses.Count == 0)
                {
                    Instance.Visible= false;
                }
            }));
        }

        private void RearrangeProgressBarsAndLabels()
        {
            int index = 0;
            foreach (var components in _loadingProcesses.Values)
            {
                components.ProgressBar.Top = 50 + (index * 30);
                components.Label.Top = components.ProgressBar.Top - 20;
                index++;
            }

            this.Height = 50 + (_loadingProcesses.Count * 30);
        }
    }
}
