using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;
using Elfisa.UI.Helpers;
using Elfisa.UI.Theming;

namespace Elfisa.UI.Controls
{
    public sealed class DocumentTabInfo
    {
        public string Id { get; set; }
        public string Title { get; set; }
        public string NavKey { get; set; }
    }

    /// <summary>
    /// Полоса вкладок как в оригинале: серые неактивные, белая активная.
    /// </summary>
    public sealed class ModernDocumentTabStrip : Panel
    {
        private readonly List<DocumentTabInfo> _tabs = new List<DocumentTabInfo>();
        private readonly Dictionary<string, Rectangle> _hitAreas = new Dictionary<string, Rectangle>();
        private readonly Dictionary<string, Rectangle> _closeHitAreas = new Dictionary<string, Rectangle>();
        private ThemeColors _theme;
        private string _activeTabId;
        private string _hoverTabId;
        private bool _themeToggleHover;
        private bool _isDarkTheme;
        private Rectangle _themeToggleRect = Rectangle.Empty;

        public event EventHandler<string> TabSelected;
        public event EventHandler<string> TabClosed;
        public event EventHandler TabCloseAllRequested;
        public event EventHandler ThemeToggleClicked;

        public bool IsDarkTheme
        {
            get => _isDarkTheme;
            set
            {
                if (_isDarkTheme == value)
                {
                    return;
                }

                _isDarkTheme = value;
                Invalidate(_themeToggleRect);
            }
        }

        private readonly ContextMenuStrip _contextMenu;
        private readonly ToolStripMenuItem _closeTabMenuItem;
        private readonly ToolStripMenuItem _closeAllTabsMenuItem;
        private string _contextMenuTabId;

        public ModernDocumentTabStrip()
        {
            Height = 40;
            Dock = DockStyle.Top;
            Cursor = Cursors.Hand;
            SetStyle(ControlStyles.AllPaintingInWmPaint |
                     ControlStyles.UserPaint |
                     ControlStyles.OptimizedDoubleBuffer |
                     ControlStyles.ResizeRedraw, true);

            _closeTabMenuItem = new ToolStripMenuItem("Закрыть вкладку");
            _closeTabMenuItem.Click += (_, __) =>
            {
                if (!string.IsNullOrEmpty(_contextMenuTabId))
                {
                    TabClosed?.Invoke(this, _contextMenuTabId);
                }
            };

            _closeAllTabsMenuItem = new ToolStripMenuItem("Закрыть все вкладки");
            _closeAllTabsMenuItem.Click += (_, __) => TabCloseAllRequested?.Invoke(this, EventArgs.Empty);

            _contextMenu = new ContextMenuStrip();
            _contextMenu.Items.Add(_closeTabMenuItem);
            _contextMenu.Items.Add(_closeAllTabsMenuItem);
            Resize += (_, __) => UpdateThemeToggleRect();
        }

        private void UpdateThemeToggleRect()
        {
            const int size = 26;
            _themeToggleRect = new Rectangle(Width - size - 10, (Height - size) / 2, size, size);
        }

        public IReadOnlyList<DocumentTabInfo> Tabs => _tabs;

        public string ActiveTabId => _activeTabId;

        public string AddTab(string title, string navKey)
        {
            var id = Guid.NewGuid().ToString("N");
            _tabs.Add(new DocumentTabInfo
            {
                Id = id,
                Title = title,
                NavKey = navKey
            });

            if (string.IsNullOrEmpty(_activeTabId))
            {
                SelectTab(id);
            }
            else
            {
                Invalidate();
            }

            return id;
        }

        public DocumentTabInfo FindByNavKey(string navKey)
        {
            return _tabs.FirstOrDefault(tab => tab.NavKey == navKey);
        }

        public void SelectTab(string tabId)
        {
            if (_tabs.All(tab => tab.Id != tabId))
            {
                return;
            }

            _activeTabId = tabId;
            Invalidate();
            TabSelected?.Invoke(this, tabId);
        }

        public bool RemoveTab(string tabId)
        {
            var tab = _tabs.FirstOrDefault(item => item.Id == tabId);
            if (tab == null)
            {
                return false;
            }

            _tabs.Remove(tab);
            if (_activeTabId == tabId)
            {
                _activeTabId = _tabs.Count > 0 ? _tabs[_tabs.Count - 1].Id : null;
                if (_activeTabId != null)
                {
                    TabSelected?.Invoke(this, _activeTabId);
                }
            }

            Invalidate();
            return true;
        }

        public void ClearTabs()
        {
            _tabs.Clear();
            _activeTabId = null;
            _hitAreas.Clear();
            Invalidate();
        }

        public void ApplyTheme(ThemeColors theme)
        {
            _theme = theme;
            UpdateThemeToggleRect();
            Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            var theme = _theme ?? ThemeManager.Colors;
            var g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

            // Та же «кожа», что у шапки/футера: лёгкий teal-тинт, не голый slate.
            var stripBg = GraphicsExtensions.Blend(theme.Surface, theme.AccentPrimarySoft, 0.55f);
            using (var bgBrush = new SolidBrush(stripBg))
            {
                g.FillRectangle(bgBrush, ClientRectangle);
            }

            using (var edge = new Pen(theme.AccentPrimaryBorder, 1f))
            {
                g.DrawLine(edge, 0, Height - 1, Width, Height - 1);
            }

            if (_tabs.Count == 0)
            {
                return;
            }

            _hitAreas.Clear();
            _closeHitAreas.Clear();
            var x = 10;
            const int tabHeight = 28;
            const int tabTop = 6;
            const int minTabWidth = 140;
            const int gap = 8;
            const int closeSize = 18;
            const int toggleReserve = 44;
            var maxTabRight = Math.Max(10, Width - toggleReserve);

            using (var closeFont = FluentFonts.CreateIconFont(10f))
            using (var textFont = theme.FontSemibold14 ?? new Font("Segoe UI", 10f, FontStyle.Bold))
            {
                foreach (var tab in _tabs)
                {
                    var textSize = TextRenderer.MeasureText(tab.Title, textFont);
                    var tabWidth = Math.Max(minTabWidth, textSize.Width + 48);
                    if (x + tabWidth > maxTabRight)
                    {
                        break;
                    }

                    var tabRect = new Rectangle(x, tabTop, tabWidth, tabHeight);
                    _hitAreas[tab.Id] = tabRect;

                    var isActive = tab.Id == _activeTabId;
                    var isHover = tab.Id == _hoverTabId;

                    var backColor = isActive
                        ? theme.SurfaceElevated
                        : GraphicsExtensions.Blend(theme.Surface, theme.AccentPrimarySoft, 0.35f);
                    if (!isActive && isHover)
                    {
                        backColor = GraphicsExtensions.Blend(backColor, theme.AccentPrimarySoft, 0.65f);
                    }

                    var foreColor = isActive ? theme.AccentPrimary : theme.TextMuted;
                    var borderColor = isActive ? theme.AccentPrimary : theme.AccentPrimaryBorder;

                    using (var brush = new SolidBrush(backColor))
                    {
                        GraphicsExtensions.FillRoundedRectangle(g, brush, tabRect, theme.CornerRadiusSmall);
                    }

                    using (var pen = new Pen(borderColor, isActive ? 1.4f : 1f))
                    {
                        GraphicsExtensions.DrawRoundedRectangle(g, pen, tabRect, theme.CornerRadiusSmall);
                    }

                    if (isActive)
                    {
                        using (var accent = new SolidBrush(theme.AccentPrimary))
                        {
                            g.FillRectangle(accent, tabRect.X + 10, tabRect.Bottom - 3, tabRect.Width - 20, 2);
                        }
                    }

                    var closeRect = new Rectangle(tabRect.Right - closeSize - 8, tabRect.Y + (tabRect.Height - closeSize) / 2, closeSize, closeSize);
                    _closeHitAreas[tab.Id] = closeRect;

                    var textRect = new Rectangle(tabRect.X + 12, tabRect.Y, Math.Max(0, closeRect.X - (tabRect.X + 12) - 6), tabRect.Height);
                    TextRenderer.DrawText(
                        g,
                        tab.Title,
                        textFont,
                        textRect,
                        foreColor,
                        TextFormatFlags.VerticalCenter | TextFormatFlags.Left | TextFormatFlags.EndEllipsis | TextFormatFlags.SingleLine);

                    var closeBack = isHover ? Color.FromArgb(36, theme.TextPrimary) : Color.Transparent;
                    using (var closeBrush = new SolidBrush(closeBack))
                    {
                        GraphicsExtensions.FillRoundedRectangle(g, closeBrush, closeRect, 6);
                    }

                    TextRenderer.DrawText(
                        g,
                        "\uE711", // close glyph
                        closeFont,
                        closeRect,
                        theme.TextMuted,
                        TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.SingleLine);

                    x += tabWidth + gap;
                }
            }

            DrawThemeToggle(g, theme);
        }

        private void DrawThemeToggle(Graphics g, ThemeColors theme)
        {
            if (_themeToggleRect.IsEmpty)
            {
                UpdateThemeToggleRect();
            }

            var fill = _themeToggleHover
                ? GraphicsExtensions.Blend(theme.SurfaceElevated, theme.AccentPrimarySoft, 0.45f)
                : theme.Surface;
            using (var fillBrush = new SolidBrush(fill))
            {
                GraphicsExtensions.FillRoundedRectangle(g, fillBrush, _themeToggleRect, theme.CornerRadiusSmall);
            }

            using (var pen = new Pen(_themeToggleHover ? theme.AccentPrimaryBorder : theme.Border, 1f))
            {
                GraphicsExtensions.DrawRoundedRectangle(g, pen, _themeToggleRect, theme.CornerRadiusSmall);
            }

            var glyph = _isDarkTheme ? "\uE706" : "\uE708";
            using (var iconFont = FluentFonts.CreateIconFont(12f))
            {
                TextRenderer.DrawText(
                    g,
                    glyph,
                    iconFont,
                    _themeToggleRect,
                    theme.TextSecondary,
                    TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.SingleLine);
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }

        protected override void OnMouseClick(MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
            {
                return;
            }

            if (_themeToggleRect.Contains(e.Location))
            {
                ThemeToggleClicked?.Invoke(this, EventArgs.Empty);
                return;
            }

            var tabId = HitTestClose(e.Location);
            if (!string.IsNullOrEmpty(tabId))
            {
                TabClosed?.Invoke(this, tabId);
                return;
            }

            tabId = HitTest(e.Location);
            if (!string.IsNullOrEmpty(tabId))
            {
                SelectTab(tabId);
            }

            base.OnMouseClick(e);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            var hovered = HitTest(e.Location);
            if (hovered != _hoverTabId)
            {
                _hoverTabId = hovered;
                Invalidate();
            }

            var toggleHover = _themeToggleRect.Contains(e.Location);
            if (toggleHover != _themeToggleHover)
            {
                _themeToggleHover = toggleHover;
                Invalidate(_themeToggleRect);
            }

            Cursor = toggleHover || !string.IsNullOrEmpty(hovered) ? Cursors.Hand : Cursors.Default;
            base.OnMouseMove(e);
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            _hoverTabId = null;
            _themeToggleHover = false;
            Invalidate(_themeToggleRect);
            Cursor = Cursors.Default;
            base.OnMouseLeave(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right && _tabs.Count > 0)
            {
                _contextMenuTabId = HitTest(e.Location) ?? _activeTabId;
                _closeTabMenuItem.Enabled = !string.IsNullOrEmpty(_contextMenuTabId);
                _closeAllTabsMenuItem.Enabled = _tabs.Count > 0;
                _contextMenu.Show(this, e.Location);
            }

            base.OnMouseUp(e);
        }

        private string HitTest(Point location)
        {
            foreach (var pair in _hitAreas)
            {
                if (pair.Value.Contains(location))
                {
                    return pair.Key;
                }
            }

            return null;
        }

        private string HitTestClose(Point location)
        {
            foreach (var pair in _closeHitAreas)
            {
                if (pair.Value.Contains(location))
                {
                    return pair.Key;
                }
            }

            return null;
        }
    }
}
