using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Elfisa.UI.Theming;

namespace Elfisa.UI.Controls
{
    /// <summary>
    /// Системная шапка: заголовок + свернуть/развернуть/закрыть.
    /// Иконки рисуются геометрией (не глифы) — как в Win11, без «ломаных» кнопок.
    /// </summary>
    public sealed class ModernTitleBar : Panel
    {
        private const int ButtonWidth = 40;
        private enum ChromeKind { None, Minimize, Maximize, Close }

        private Form _owner;
        private ThemeColors _theme;
        private ChromeKind _hover = ChromeKind.None;
        private ChromeKind _pressed = ChromeKind.None;
        private bool _isMaximized;
        private readonly ToolTip _tip = new ToolTip { ShowAlways = false, AutoPopDelay = 2000 };

        public ModernTitleBar()
        {
            Height = 30;
            Dock = DockStyle.Top;
            Cursor = Cursors.Default;
            DoubleBuffered = true;
            SetStyle(ControlStyles.AllPaintingInWmPaint |
                     ControlStyles.UserPaint |
                     ControlStyles.OptimizedDoubleBuffer |
                     ControlStyles.ResizeRedraw |
                     ControlStyles.Selectable, true);
            TabStop = false;
            ApplyTheme(ThemeManager.Colors);
        }

        public void Attach(Form owner)
        {
            _owner = owner;
            if (_owner == null)
            {
                return;
            }

            _owner.TextChanged += (_, __) => Invalidate();
            _owner.Resize += (_, __) =>
            {
                _isMaximized = _owner.WindowState == FormWindowState.Maximized;
                Invalidate();
            };
            _isMaximized = _owner.WindowState == FormWindowState.Maximized;
            Invalidate();
        }

        public void ApplyTheme(ThemeColors theme)
        {
            _theme = theme ?? ThemeManager.Colors;
            BackColor = _theme.AccentPrimary;
            Invalidate();
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            var theme = _theme ?? ThemeManager.Colors;
            var g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;

            using (var fill = new SolidBrush(theme.AccentPrimary))
            {
                g.FillRectangle(fill, ClientRectangle);
            }

            DrawTitle(g, theme);
            DrawChromeButton(g, ChromeKind.Minimize, theme);
            DrawChromeButton(g, ChromeKind.Maximize, theme);
            DrawChromeButton(g, ChromeKind.Close, theme);
        }

        private void DrawTitle(Graphics g, ThemeColors theme)
        {
            var title = _owner == null || string.IsNullOrWhiteSpace(_owner.Text)
                ? "Электронная Фармация"
                : _owner.Text;
            var textRect = new Rectangle(12, 0, Math.Max(40, Width - ButtonWidth * 3 - 16), Height);
            using (var font = new Font("Segoe UI Semibold", 9f, FontStyle.Bold))
            {
                TextRenderer.DrawText(
                    g,
                    title,
                    font,
                    textRect,
                    theme.TextOnAccent,
                    TextFormatFlags.VerticalCenter | TextFormatFlags.Left | TextFormatFlags.EndEllipsis | TextFormatFlags.SingleLine);
            }
        }

        private Rectangle GetButtonRect(ChromeKind kind)
        {
            var index = kind == ChromeKind.Close ? 0 : kind == ChromeKind.Maximize ? 1 : 2;
            return new Rectangle(Width - ButtonWidth * (index + 1), 0, ButtonWidth, Height);
        }

        private void DrawChromeButton(Graphics g, ChromeKind kind, ThemeColors theme)
        {
            var rect = GetButtonRect(kind);
            var isHover = _hover == kind;
            var isPressed = _pressed == kind;

            if (isHover || isPressed)
            {
                Color hoverFill;
                if (kind == ChromeKind.Close)
                {
                    hoverFill = isPressed
                        ? Color.FromArgb(180, 32, 28)
                        : Color.FromArgb(232, 17, 35);
                }
                else
                {
                    var alpha = isPressed ? 55 : 38;
                    hoverFill = Color.FromArgb(alpha, 255, 255, 255);
                }

                using (var brush = new SolidBrush(hoverFill))
                {
                    g.FillRectangle(brush, rect);
                }
            }

            var iconColor = theme.TextOnAccent;
            var cx = rect.X + rect.Width / 2f;
            var cy = rect.Y + rect.Height / 2f;

            using (var pen = new Pen(iconColor, 1.15f))
            {
                pen.StartCap = LineCap.Round;
                pen.EndCap = LineCap.Round;
                pen.LineJoin = LineJoin.Round;

                switch (kind)
                {
                    case ChromeKind.Minimize:
                        g.DrawLine(pen, cx - 5f, cy, cx + 5f, cy);
                        break;

                    case ChromeKind.Maximize:
                        if (_isMaximized)
                        {
                            // restore: два смещённых квадрата
                            var back = new RectangleF(cx - 3.2f, cy - 5.2f, 8.5f, 8.5f);
                            var front = new RectangleF(cx - 5.2f, cy - 3.2f, 8.5f, 8.5f);
                            g.DrawRectangle(pen, back.X, back.Y, back.Width, back.Height);

                            // залить передний квадрат цветом шапки (с учётом hover), чтобы «обрезать» задний
                            var coverColor = theme.AccentPrimary;
                            if (isHover || isPressed)
                            {
                                coverColor = Color.FromArgb(
                                    255,
                                    BlendChannel(theme.AccentPrimary.R, 255, isPressed ? 0.22f : 0.15f),
                                    BlendChannel(theme.AccentPrimary.G, 255, isPressed ? 0.22f : 0.15f),
                                    BlendChannel(theme.AccentPrimary.B, 255, isPressed ? 0.22f : 0.15f));
                            }

                            using (var cover = new SolidBrush(coverColor))
                            {
                                g.FillRectangle(cover, Rectangle.Round(RectangleF.Inflate(front, 1f, 1f)));
                            }

                            g.DrawRectangle(pen, front.X, front.Y, front.Width, front.Height);
                        }
                        else
                        {
                            var box = new RectangleF(cx - 4.5f, cy - 4.5f, 9f, 9f);
                            g.DrawRectangle(pen, box.X, box.Y, box.Width, box.Height);
                        }
                        break;

                    case ChromeKind.Close:
                        g.DrawLine(pen, cx - 4.5f, cy - 4.5f, cx + 4.5f, cy + 4.5f);
                        g.DrawLine(pen, cx + 4.5f, cy - 4.5f, cx - 4.5f, cy + 4.5f);
                        break;
                }
            }
        }

        private ChromeKind HitTest(Point p)
        {
            if (GetButtonRect(ChromeKind.Close).Contains(p)) return ChromeKind.Close;
            if (GetButtonRect(ChromeKind.Maximize).Contains(p)) return ChromeKind.Maximize;
            if (GetButtonRect(ChromeKind.Minimize).Contains(p)) return ChromeKind.Minimize;
            return ChromeKind.None;
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            var hit = HitTest(e.Location);
            if (hit != _hover)
            {
                _hover = hit;
                Cursor = hit == ChromeKind.None ? Cursors.Default : Cursors.Hand;
                UpdateTip(hit);
                Invalidate();
            }

            base.OnMouseMove(e);
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            if (_hover != ChromeKind.None || _pressed != ChromeKind.None)
            {
                _hover = ChromeKind.None;
                _pressed = ChromeKind.None;
                Cursor = Cursors.Default;
                _tip.Hide(this);
                Invalidate();
            }

            base.OnMouseLeave(e);
        }

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

            var hit = HitTest(e.Location);
            if (hit != ChromeKind.None)
            {
                _pressed = hit;
                Invalidate();
                base.OnMouseDown(e);
                return;
            }

            if (e.Clicks >= 2)
            {
                ToggleMaximize();
            }
            else if (_owner != null)
            {
                ReleaseCapture();
                SendMessage(_owner.Handle, 0xA1, (IntPtr)2, IntPtr.Zero);
            }

            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && _pressed != ChromeKind.None)
            {
                var hit = HitTest(e.Location);
                var action = _pressed;
                _pressed = ChromeKind.None;
                Invalidate();

                if (hit == action)
                {
                    Execute(action);
                }
            }

            base.OnMouseUp(e);
        }

        private void Execute(ChromeKind kind)
        {
            if (_owner == null)
            {
                return;
            }

            switch (kind)
            {
                case ChromeKind.Minimize:
                    _owner.WindowState = FormWindowState.Minimized;
                    break;
                case ChromeKind.Maximize:
                    ToggleMaximize();
                    break;
                case ChromeKind.Close:
                    _owner.Close();
                    break;
            }
        }

        private void ToggleMaximize()
        {
            if (_owner == null)
            {
                return;
            }

            _owner.WindowState = _owner.WindowState == FormWindowState.Maximized
                ? FormWindowState.Normal
                : FormWindowState.Maximized;
            _isMaximized = _owner.WindowState == FormWindowState.Maximized;
            Invalidate();
        }

        private void UpdateTip(ChromeKind kind)
        {
            string text = null;
            switch (kind)
            {
                case ChromeKind.Minimize: text = "Свернуть"; break;
                case ChromeKind.Maximize: text = _isMaximized ? "Свернуть в окно" : "Развернуть"; break;
                case ChromeKind.Close: text = "Закрыть"; break;
            }

            if (text == null)
            {
                _tip.Hide(this);
                return;
            }

            var rect = GetButtonRect(kind);
            _tip.Show(text, this, rect.X + rect.Width / 2, Height + 2, 1500);
        }

        private static int BlendChannel(int from, int to, float amount)
        {
            return (int)(from + (to - from) * amount);
        }

        [DllImport("user32.dll")]
        private static extern bool ReleaseCapture();

        [DllImport("user32.dll")]
        private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
    }
}
