using Quasar.Server.Networking;
using Quasar.Server.Statistics;
using Quasar.Server.Utilities;
using Quasar.Server.Models;
using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace Quasar.Server.Controls
{
    public partial class StatisticsPanel : UserControl
    {
        private readonly QuasarServer _listenServer;
        private Timer _refreshTimer;
        private Func<MockClient[]> _getMockClients;

        public StatisticsPanel(QuasarServer listenServer)
        {
            _listenServer = listenServer;
            InitializeComponent();
            ApplyTheme();
            
            _refreshTimer = new Timer();
            _refreshTimer.Interval = 5000;
            _refreshTimer.Tick += RefreshTimer_Tick;
        }

        public void SetMockClientsProvider(Func<MockClient[]> getMockClients)
        {
            _getMockClients = getMockClients;
        }

        private void ApplyTheme()
        {
            // Always apply dark theme to match the UI
            this.BackColor = Color.FromArgb(32, 32, 36);
            this.ForeColor = Color.White;

            ApplyThemeToControls(this.Controls);

            if (chartOS != null)
            {
                chartOS.BackColor = Color.FromArgb(32, 32, 36);
                chartOS.ChartAreas[0].BackColor = Color.FromArgb(32, 32, 36);
                chartOS.ChartAreas[0].BorderColor = Color.FromArgb(70, 70, 78);
                chartOS.ChartAreas[0].BorderWidth = 1;
                chartOS.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;

                if (chartOS.Legends.Count > 0)
                {
                    chartOS.Legends[0].BackColor = Color.FromArgb(32, 32, 36);
                    chartOS.Legends[0].ForeColor = Color.White;
                }
            }
        }
        
        private void ApplyThemeToControls(Control.ControlCollection controls)
        {
            foreach (Control control in controls)
            {
                if (control is Label label)
                {
                    label.ForeColor = Color.White;
                }
                else if (control is Button button)
                {
                    button.BackColor = Color.FromArgb(37, 37, 38);
                    button.ForeColor = Color.White;
                    button.FlatStyle = FlatStyle.Flat;
                    button.FlatAppearance.BorderColor = Color.FromArgb(63, 63, 70);
                }
                else if (control is ListView listView)
                {
                    listView.BackColor = Color.FromArgb(32, 32, 36);
                    listView.ForeColor = Color.White;
                    listView.GridLines = false;
                    listView.BorderStyle = BorderStyle.FixedSingle;
                }
                else if (control is Panel panel)
                {
                    panel.BackColor = Color.FromArgb(32, 32, 36);
                }
                else if (control is GroupBox groupBox)
                {
                    groupBox.ForeColor = Color.White;
                }
                
                if (control.HasChildren)
                {
                    ApplyThemeToControls(control.Controls);
                }
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            RefreshStatistics();
            _refreshTimer.Start();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
                _refreshTimer?.Stop();
                _refreshTimer?.Dispose();
            }
            base.Dispose(disposing);
        }

        private void RefreshTimer_Tick(object sender, EventArgs e)
        {
            RefreshStatistics();
        }

        private void RefreshStatistics()
        {
            try
            {
                var clients = _listenServer.ConnectedClients;
                MockClient[] mockClients = null;
                
                // Get mock clients if provider is set
                if (_getMockClients != null)
                {
                    mockClients = _getMockClients();
                }
                
                var snapshot = ClientStatisticsService.CreateSnapshot(clients, mockClients);

                if (snapshot.HasError)
                {
                    return;
                }

                lblTotalValue.Text = snapshot.TotalClients.ToString();
                lblOnlineValue.Text = snapshot.OnlineClients.ToString();
                lblCountriesValue.Text = snapshot.ClientsByCountry.Count.ToString();

                UpdateCountryList(snapshot);
                UpdateOSChart(snapshot);
            }
            catch
            {
                // Silently handle errors
            }
        }

        private void UpdateCountryList(ClientStatisticsSnapshot snapshot)
        {
            lvCountries.Items.Clear();

            foreach (var country in snapshot.ClientsByCountry.Take(10))
            {
                var item = new ListViewItem(country.Label);
                item.SubItems.Add(country.Count.ToString());
                item.SubItems.Add(country.Share.ToString("P0"));
                lvCountries.Items.Add(item);
            }
        }

        private void UpdateOSChart(ClientStatisticsSnapshot snapshot)
        {
            chartOS.Series.Clear();
            chartOS.Titles.Clear();

            if (snapshot.ClientsByOperatingSystem.Count == 0)
            {
                var title = chartOS.Titles.Add("No Data Available");
                title.Font = new Font("Segoe UI", 10);
                title.ForeColor = Color.White;
                return;
            }

            var series = new Series("Operating Systems")
            {
                ChartType = SeriesChartType.Pie,
                IsValueShownAsLabel = true
            };

            series["PieLabelStyle"] = "Outside";
            series["PieLineColor"] = "White";

            foreach (var os in snapshot.ClientsByOperatingSystem.Take(6))
            {
                var point = series.Points.Add(os.Count);
                point.Label = $"{os.Count} ({os.Share:P0})";
                point.LegendText = os.Label.Length > 30 ? os.Label.Substring(0, 27) + "..." : os.Label;
                point.ToolTip = $"{os.Label}: {os.Count} clients ({os.Share:P0})";
                point.LabelForeColor = Color.White;
            }

            chartOS.Series.Add(series);
            
            var title2 = chartOS.Titles.Add("Operating Systems Distribution");
            title2.Font = new Font("Segoe UI", 11, FontStyle.Bold);
            title2.ForeColor = Color.White;
            
            chartOS.Legends[0].Enabled = true;
            chartOS.Legends[0].Docking = Docking.Right;
            chartOS.Legends[0].Font = new Font("Segoe UI", 9);
            chartOS.Legends[0].BackColor = Color.FromArgb(32, 32, 36);
            chartOS.Legends[0].ForeColor = Color.White;
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            RefreshStatistics();
        }

        private void chartOS_Click(object sender, EventArgs e)
        {

        }
    }
}
