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

namespace Elfisa.UI.Helpers
{
    public static class WindowChromeHelper
    {
        private const int DwmwaUseImmersiveDarkMode = 20;
        private const int DwmwaUseImmersiveDarkModeLegacy = 19;
        private const int DwmwaCaptionColor = 35;
        private const int DwmwaTextColor = 36;

        private const uint SwpNomove = 0x0002;
        private const uint SwpNosize = 0x0001;
        private const uint SwpNozorder = 0x0004;
        private const uint SwpFramechanged = 0x0020;

        [DllImport("dwmapi.dll", PreserveSig = true)]
        private static extern int DwmSetWindowAttribute(IntPtr hwnd, int dwAttribute, ref int pvAttribute, int cbAttribute);

        [DllImport("dwmapi.dll", PreserveSig = true)]
        private static extern int DwmSetWindowAttribute(IntPtr hwnd, int dwAttribute, ref uint pvAttribute, int cbAttribute);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool SetWindowPos(
            IntPtr hWnd,
            IntPtr hWndInsertAfter,
            int x,
            int y,
            int cx,
            int cy,
            uint uFlags);

        public static void ApplyTitleBarTheme(Form form, ThemeColors theme)
        {
            if (form == null || theme == null || !form.IsHandleCreated)
            {
                return;
            }

            var isDark = theme.Mode == ThemeMode.Dark;
            var useDarkMode = isDark ? 1 : 0;
            TrySetInt(form.Handle, DwmwaUseImmersiveDarkMode, useDarkMode);
            TrySetInt(form.Handle, DwmwaUseImmersiveDarkModeLegacy, useDarkMode);

            var caption = theme.AccentPrimary;
            var text = IsLightCaption(caption) ? Color.Black : Color.White;

            TrySetUInt(form.Handle, DwmwaCaptionColor, ColorToDwm(caption));
            TrySetUInt(form.Handle, DwmwaTextColor, ColorToDwm(text));

            RefreshNonClientArea(form);
        }

        /// <summary>
        /// Обработка ресайза для FormBorderStyle.None (края окна).
        /// </summary>
        public static bool TryHandleNcHitTest(Form form, ref Message m, int border = 6)
        {
            const int wmNcHitTest = 0x84;
            if (m.Msg != wmNcHitTest || form == null)
            {
                return false;
            }

            var screen = new Point(m.LParam.ToInt32() & 0xFFFF, (m.LParam.ToInt32() >> 16) & 0xFFFF);
            // signed short for multi-monitor negative coords
            screen = new Point((short)(m.LParam.ToInt32() & 0xFFFF), (short)((m.LParam.ToInt32() >> 16) & 0xFFFF));
            var client = form.PointToClient(screen);
            var w = form.ClientSize.Width;
            var h = form.ClientSize.Height;

            var left = client.X <= border;
            var right = client.X >= w - border;
            var top = client.Y <= border;
            var bottom = client.Y >= h - border;

            if (top && left) { m.Result = (IntPtr)13; return true; }      // HTTOPLEFT
            if (top && right) { m.Result = (IntPtr)14; return true; }     // HTTOPRIGHT
            if (bottom && left) { m.Result = (IntPtr)16; return true; }   // HTBOTTOMLEFT
            if (bottom && right) { m.Result = (IntPtr)17; return true; }  // HTBOTTOMRIGHT
            if (left) { m.Result = (IntPtr)10; return true; }             // HTLEFT
            if (right) { m.Result = (IntPtr)11; return true; }            // HTRIGHT
            if (top) { m.Result = (IntPtr)12; return true; }              // HTTOP
            if (bottom) { m.Result = (IntPtr)15; return true; }           // HTBOTTOM

            return false;
        }

        public static void ApplyThemedDialogHeader(Panel headerPanel, Label headerLabel, ThemeColors theme)
        {
            if (theme == null)
            {
                return;
            }

            if (headerPanel != null)
            {
                headerPanel.BackColor = theme.TitleBarTop;
            }

            if (headerLabel != null)
            {
                headerLabel.ForeColor = IsLightCaption(theme.TitleBarTop) ? Color.Black : Color.White;
            }
        }

        private static bool IsLightCaption(Color color)
        {
            var luminance = (0.299 * color.R) + (0.587 * color.G) + (0.114 * color.B);
            return luminance > 180;
        }

        public static void ApplyDialogChrome(Form form, Panel headerPanel = null, Label headerLabel = null)
        {
            if (form == null)
            {
                return;
            }

            var theme = ThemeManager.Colors;
            ApplyThemedDialogHeader(headerPanel, headerLabel, theme);

            if (form.IsHandleCreated)
            {
                ApplyTitleBarTheme(form, theme);
            }
            else
            {
                form.HandleCreated += (_, __) => ApplyTitleBarTheme(form, ThemeManager.Colors);
            }
        }

        private static uint ColorToDwm(Color color)
        {
            return (uint)(color.R | (color.G << 8) | (color.B << 16));
        }

        private static void RefreshNonClientArea(Form form)
        {
            SetWindowPos(form.Handle, IntPtr.Zero, 0, 0, 0, 0, SwpNomove | SwpNosize | SwpNozorder | SwpFramechanged);
        }

        private static void TrySetInt(IntPtr handle, int attribute, int value)
        {
            DwmSetWindowAttribute(handle, attribute, ref value, sizeof(int));
        }

        private static void TrySetUInt(IntPtr handle, int attribute, uint value)
        {
            DwmSetWindowAttribute(handle, attribute, ref value, sizeof(uint));
        }
    }
}
