using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Quasar.Server.Utilities
{
    public static class ThemeManager
    {
        // Dark theme colors
        private static readonly Color DarkBackground = Color.FromArgb(45, 45, 48);
        private static readonly Color DarkForeground = Color.White;
        private static readonly Color DarkControlBackground = Color.FromArgb(37, 37, 38);
        private static readonly Color DarkBorder = Color.FromArgb(63, 63, 70);
        private static readonly Color DarkMenuBackground = Color.FromArgb(37, 37, 38);
        private static readonly Color DarkMenuForeground = Color.White;

        public static bool DarkModeEnabled { get; set; }
        
        // Windows 10/11 dark mode for title bar
        [DllImport("dwmapi.dll")]
        private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
        
        private const int DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19;
        private const int DWMWA_USE_IMMERSIVE_DARK_MODE = 20;

        public static void ApplyTheme(Form form)
        {
            if (!DarkModeEnabled) return;

            form.BackColor = DarkBackground;
            form.ForeColor = DarkForeground;
            
            // Apply dark mode to title bar (Windows 10 build 17763+)
            ApplyDarkTitleBar(form);

            ApplyThemeToControls(form.Controls);
            
            // Apply to child forms if any
            foreach (Form childForm in form.OwnedForms)
            {
                ApplyTheme(childForm);
            }
        }
        
        private static void ApplyDarkTitleBar(Form form)
        {
            if (form.Handle == IntPtr.Zero) return;
            
            try
            {
                int useImmersiveDarkMode = 1;
                
                // Try Windows 11 / Windows 10 20H1+ attribute first
                if (DwmSetWindowAttribute(form.Handle, DWMWA_USE_IMMERSIVE_DARK_MODE, ref useImmersiveDarkMode, sizeof(int)) != 0)
                {
                    // Fall back to older Windows 10 attribute
                    DwmSetWindowAttribute(form.Handle, DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, ref useImmersiveDarkMode, sizeof(int));
                }
            }
            catch
            {
                // Ignore errors on older Windows versions
            }
        }
        
        public static void ApplyThemeToNewForm(Form form)
        {
            if (!DarkModeEnabled) return;
            ApplyTheme(form);
        }

        private static void ApplyThemeToControls(Control.ControlCollection controls)
        {
            foreach (Control control in controls)
            {
                // Apply theme based on control type
                switch (control)
                {
                    case MenuStrip menuStrip:
                        ApplyMenuStripTheme(menuStrip);
                        break;
                    case StatusStrip statusStrip:
                        ApplyStatusStripTheme(statusStrip);
                        break;
                    case ContextMenuStrip contextMenu:
                        ApplyContextMenuTheme(contextMenu);
                        break;
                    case ListView listView:
                        // Check if it's an AeroListView and enable dark mode
                        if (listView.GetType().Name == "AeroListView")
                        {
                            var enableMethod = listView.GetType().GetMethod("EnableDarkMode");
                            if (enableMethod != null)
                            {
                                enableMethod.Invoke(listView, null);
                            }
                        }
                        else
                        {
                            ApplyListViewTheme(listView);
                        }
                        // Apply theme to ListView's ContextMenuStrip if it has one
                        if (listView.ContextMenuStrip != null)
                            ApplyContextMenuTheme(listView.ContextMenuStrip);
                        break;
                    case ListBox listBox:
                        listBox.BackColor = DarkControlBackground;
                        listBox.ForeColor = DarkForeground;
                        break;
                    case TreeView treeView:
                        ApplyTreeViewTheme(treeView);
                        // Apply theme to TreeView's ContextMenuStrip if it has one
                        if (treeView.ContextMenuStrip != null)
                            ApplyContextMenuTheme(treeView.ContextMenuStrip);
                        break;
                    case TextBox textBox:
                        ApplyTextBoxTheme(textBox);
                        break;
                    case RichTextBox richTextBox:
                        ApplyRichTextBoxTheme(richTextBox);
                        break;
                    case Button button:
                        ApplyButtonTheme(button);
                        break;
                    case GroupBox groupBox:
                        ApplyGroupBoxTheme(groupBox);
                        break;
                    case Panel panel:
                        ApplyPanelTheme(panel);
                        break;
                    case TabControl tabControl:
                        // Don't apply custom drawing to DotNetBarTabControl
                        if (tabControl.GetType().Name != "DotNetBarTabControl")
                        {
                            ApplyTabControlTheme(tabControl);
                        }
                        break;
                    case Label label:
                        label.ForeColor = DarkForeground;
                        break;
                    case CheckBox checkBox:
                        checkBox.ForeColor = DarkForeground;
                        break;
                    case RadioButton radioButton:
                        radioButton.ForeColor = DarkForeground;
                        break;
                    case ComboBox comboBox:
                        comboBox.BackColor = DarkControlBackground;
                        comboBox.ForeColor = DarkForeground;
                        break;
                    case NumericUpDown numericUpDown:
                        numericUpDown.BackColor = DarkControlBackground;
                        numericUpDown.ForeColor = DarkForeground;
                        break;
                    case DataGridView dataGridView:
                        ApplyDataGridViewTheme(dataGridView);
                        break;
                }

                // Apply theme to control's ContextMenuStrip if it has one
                if (control.ContextMenuStrip != null)
                {
                    ApplyContextMenuTheme(control.ContextMenuStrip);
                }
                
                // Special handling for custom DotNetBarTabControl
                if (control.GetType().Name == "DotNetBarTabControl")
                {
                    control.BackColor = DarkBackground;
                    control.ForeColor = DarkForeground;
                    // Don't set DrawMode or add event handlers for DotNetBarTabControl
                    // It has its own custom painting logic
                    
                    // Apply theme to its tab pages
                    if (control is TabControl tabCtrl)
                    {
                        foreach (TabPage page in tabCtrl.TabPages)
                        {
                            page.BackColor = DarkBackground;
                            page.ForeColor = DarkForeground;
                            page.UseVisualStyleBackColor = false;
                        }
                    }
                    
                    // Force repaint
                    control.Invalidate();
                }
                
                // Special handling for Chart controls
                if (control.GetType().Name == "Chart")
                {
                    try
                    {
                        var chart = control as System.Windows.Forms.DataVisualization.Charting.Chart;
                        if (chart != null)
                        {
                            chart.BackColor = DarkControlBackground;
                            if (chart.ChartAreas.Count > 0)
                            {
                                chart.ChartAreas[0].BackColor = DarkControlBackground;
                                chart.ChartAreas[0].BorderColor = DarkBorder;
                            }
                            foreach (var legend in chart.Legends)
                            {
                                legend.BackColor = DarkControlBackground;
                                legend.ForeColor = DarkForeground;
                            }
                        }
                    }
                    catch { }
                }

                // Recursively apply to child controls
                if (control.HasChildren)
                {
                    ApplyThemeToControls(control.Controls);
                }
            }
        }

        private static void ApplyMenuStripTheme(MenuStrip menuStrip)
        {
            menuStrip.BackColor = DarkMenuBackground;
            menuStrip.ForeColor = DarkMenuForeground;
            menuStrip.Renderer = new DarkMenuRenderer();
        }

        private static void ApplyStatusStripTheme(StatusStrip statusStrip)
        {
            statusStrip.BackColor = DarkControlBackground;
            statusStrip.ForeColor = DarkForeground;
            statusStrip.Renderer = new DarkMenuRenderer();
        }

        private static void ApplyContextMenuTheme(ContextMenuStrip contextMenu)
        {
            contextMenu.BackColor = DarkMenuBackground;
            contextMenu.ForeColor = DarkMenuForeground;
            contextMenu.Renderer = new DarkMenuRenderer();
        }

        private static void ApplyListViewTheme(ListView listView)
        {
            listView.BackColor = DarkControlBackground;
            listView.ForeColor = DarkForeground;
            listView.GridLines = false;
            listView.BorderStyle = BorderStyle.FixedSingle;
            
            // Enable OwnerDraw for dark headers
            listView.OwnerDraw = true;
            listView.DrawColumnHeader -= ListView_DrawColumnHeader;
            listView.DrawColumnHeader += ListView_DrawColumnHeader;
            listView.DrawItem -= ListView_DrawItem;
            listView.DrawItem += ListView_DrawItem;
            listView.DrawSubItem -= ListView_DrawSubItem;
            listView.DrawSubItem += ListView_DrawSubItem;
        }
        
        private static void ListView_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
        {
            e.Graphics.FillRectangle(new SolidBrush(DarkBackground), e.Bounds);
            
            using (Pen pen = new Pen(DarkBorder))
            {
                e.Graphics.DrawRectangle(pen, e.Bounds.X, e.Bounds.Y, e.Bounds.Width - 1, e.Bounds.Height - 1);
            }
            
            TextRenderer.DrawText(e.Graphics, e.Header.Text, ((ListView)sender).Font, e.Bounds, DarkForeground,
                TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis);
        }

        private static void ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            e.DrawDefault = false;
        }

        private static void ListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
        {
            Color backColor;
            Color foreColor = DarkForeground;
            
            if (e.Item.Selected)
            {
                backColor = Color.FromArgb(62, 62, 64);
                foreColor = Color.White;
            }
            else
            {
                backColor = DarkControlBackground;
                
                // Preserve custom colors like red text
                if (e.Item.ForeColor != Color.Empty && 
                    e.Item.ForeColor != SystemColors.WindowText &&
                    e.Item.ForeColor != Color.Black &&
                    e.Item.ForeColor != DarkForeground)
                {
                    foreColor = e.Item.ForeColor;
                }
                else if (e.SubItem.ForeColor != Color.Empty && 
                         e.SubItem.ForeColor != SystemColors.WindowText &&
                         e.SubItem.ForeColor != Color.Black &&
                         e.SubItem.ForeColor != DarkForeground)
                {
                    foreColor = e.SubItem.ForeColor;
                }
            }
            
            using (SolidBrush brush = new SolidBrush(backColor))
            {
                e.Graphics.FillRectangle(brush, e.Bounds);
            }
            
            if (!string.IsNullOrEmpty(e.SubItem.Text))
            {
                TextRenderer.DrawText(e.Graphics, e.SubItem.Text, e.Item.Font, e.Bounds, foreColor,
                    TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis | TextFormatFlags.NoPrefix);
            }
        }

        private static void ApplyTreeViewTheme(TreeView treeView)
        {
            treeView.BackColor = DarkControlBackground;
            treeView.ForeColor = DarkForeground;
        }

        private static void ApplyTextBoxTheme(TextBox textBox)
        {
            textBox.BackColor = DarkControlBackground;
            textBox.ForeColor = DarkForeground;
            textBox.BorderStyle = BorderStyle.FixedSingle;
        }

        private static void ApplyRichTextBoxTheme(RichTextBox richTextBox)
        {
            richTextBox.BackColor = DarkControlBackground;
            richTextBox.ForeColor = DarkForeground;
            richTextBox.BorderStyle = BorderStyle.FixedSingle;
        }

        private static void ApplyButtonTheme(Button button)
        {
            button.BackColor = DarkControlBackground;
            button.ForeColor = DarkForeground;
            button.FlatStyle = FlatStyle.Flat;
            button.FlatAppearance.BorderColor = DarkBorder;
        }

        private static void ApplyGroupBoxTheme(GroupBox groupBox)
        {
            groupBox.ForeColor = DarkForeground;
        }

        private static void ApplyPanelTheme(Panel panel)
        {
            panel.BackColor = DarkBackground;
        }

        private static void ApplyTabControlTheme(TabControl tabControl)
        {
            tabControl.BackColor = DarkBackground;
            tabControl.DrawMode = TabDrawMode.OwnerDrawFixed;
            tabControl.DrawItem -= TabControl_DrawItem; // Remove old handler if exists
            tabControl.DrawItem += TabControl_DrawItem;
            
            // Set padding to reduce white space
            if (tabControl.Padding.X < 12)
                tabControl.Padding = new System.Drawing.Point(12, 3);
            
            foreach (TabPage page in tabControl.TabPages)
            {
                page.BackColor = DarkBackground;
                page.ForeColor = DarkForeground;
                page.UseVisualStyleBackColor = false;
            }
        }
        
        private static void TabControl_DrawItem(object sender, DrawItemEventArgs e)
        {
            TabControl tabControl = sender as TabControl;
            if (tabControl == null) return;
            
            Graphics g = e.Graphics;
            TabPage tabPage = tabControl.TabPages[e.Index];
            Rectangle tabBounds = tabControl.GetTabRect(e.Index);
            
            // Determine colors based on selection
            Color backColor = (e.State == DrawItemState.Selected) 
                ? DarkBackground 
                : Color.FromArgb(37, 37, 38);
            Color foreColor = DarkForeground;
            
            // Draw background - fill entire bounds including borders
            using (SolidBrush brush = new SolidBrush(backColor))
            {
                g.FillRectangle(brush, tabBounds);
            }
            
            // Draw a subtle border for unselected tabs
            if (e.State != DrawItemState.Selected)
            {
                using (Pen pen = new Pen(DarkBorder))
                {
                    g.DrawRectangle(pen, tabBounds.X, tabBounds.Y, tabBounds.Width - 1, tabBounds.Height - 1);
                }
            }
            
            // Draw text
            TextRenderer.DrawText(g, tabPage.Text, tabControl.Font, tabBounds, foreColor,
                TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
        }

        private static void ApplyDataGridViewTheme(DataGridView dataGridView)
        {
            dataGridView.BackgroundColor = DarkControlBackground;
            dataGridView.ForeColor = DarkForeground;
            dataGridView.GridColor = DarkBorder;
            dataGridView.DefaultCellStyle.BackColor = DarkControlBackground;
            dataGridView.DefaultCellStyle.ForeColor = DarkForeground;
            dataGridView.DefaultCellStyle.SelectionBackColor = Color.FromArgb(62, 62, 64);
            dataGridView.DefaultCellStyle.SelectionForeColor = DarkForeground;
            dataGridView.ColumnHeadersDefaultCellStyle.BackColor = DarkBackground;
            dataGridView.ColumnHeadersDefaultCellStyle.ForeColor = DarkForeground;
            dataGridView.RowHeadersDefaultCellStyle.BackColor = DarkBackground;
            dataGridView.RowHeadersDefaultCellStyle.ForeColor = DarkForeground;
            dataGridView.EnableHeadersVisualStyles = false;
            dataGridView.BorderStyle = BorderStyle.FixedSingle;
        }

        private class DarkMenuRenderer : ToolStripProfessionalRenderer
        {
            public DarkMenuRenderer() : base(new DarkColorTable()) { }

            protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
            {
                if (e.Item.Selected)
                {
                    e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(62, 62, 64)), e.Item.ContentRectangle);
                }
                else
                {
                    e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(37, 37, 38)), e.Item.ContentRectangle);
                }
            }

            protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
            {
                e.TextColor = Color.White;
                base.OnRenderItemText(e);
            }
        }

        private class DarkColorTable : ProfessionalColorTable
        {
            public override Color MenuItemSelected => Color.FromArgb(62, 62, 64);
            public override Color MenuItemSelectedGradientBegin => Color.FromArgb(62, 62, 64);
            public override Color MenuItemSelectedGradientEnd => Color.FromArgb(62, 62, 64);
            public override Color MenuItemBorder => Color.FromArgb(63, 63, 70);
            public override Color MenuBorder => Color.FromArgb(63, 63, 70);
            public override Color MenuItemPressedGradientBegin => Color.FromArgb(37, 37, 38);
            public override Color MenuItemPressedGradientEnd => Color.FromArgb(37, 37, 38);
            public override Color ToolStripDropDownBackground => Color.FromArgb(37, 37, 38);
            public override Color ImageMarginGradientBegin => Color.FromArgb(37, 37, 38);
            public override Color ImageMarginGradientMiddle => Color.FromArgb(37, 37, 38);
            public override Color ImageMarginGradientEnd => Color.FromArgb(37, 37, 38);
        }
    }
}
