using PTMedicalInsurance.Variables;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PTMedicalInsurance.Common
{
    class HookApi
    {
        delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

        // 导入用户32位API函数
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        // 导入用户32位API函数
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern int GetWindowTextLength(IntPtr hWnd);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern bool IsWindowVisible(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);


        public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
        public  HookProc _hookProc;
        public  IntPtr _hHook;
        public  ManualResetEvent _windowCreatedEvent = new ManualResetEvent(false);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);



        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern uint GetLastError();



        public HookApi()
        {
            Global.writeLog("创建HookAPI");
            _hookProc = new HookProc(HookCallback);
            IntPtr hInstance = GetModuleHandle(null);
            Global.writeLog($"hInstance:{hInstance}");
            _hHook = SetWindowsHookEx(WH_CBT, _hookProc, hInstance, 0); // 设置全局钩子

            if (_hHook == IntPtr.Zero)
            {
                uint lastError = GetLastError();
                Global.writeLog($"Failed to set hook. Error code: {lastError}");
                return;
            }

            // 启动消息循环
            Application.Run(new Form()); // 使用一个空的Form来启动消息循环
        }

        const uint WM_KEYDOWN = 0x100;
        const uint WM_KEYUP = 0x101;
        const int VK_CONTROL = 0x11; // Ctrl键
        const int VK_A = 0x41;      // A键
        const int VK_R = 0x52;
        const int VK_P = 0x50;
        const int VK_S = 0x53;
        const int VK_F = 0x46;
        const int VK_C = 0x43;


        const int WH_CBT = 5;
        const int HCBT_CREATEWND = 3;
        const uint WM_CLOSE = 0x0010;


        public  int HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            Global.writeLog($"创建HookCallback:{nCode}" );
            if (nCode < 0)
            {
                return CallNextHookEx(_hHook, nCode, wParam, lParam);
            }

            if (nCode == HCBT_CREATEWND)
            {
                IntPtr hWnd = wParam;
                if (IsTargetWindow(hWnd))
                {
                    Global.writeLog("检测到身份识别窗口且成功获取句柄");
                    // 窗口创建成功,执行操作
                    OperateYHControl((int)hWnd, "身份识别");

                    // 设置事件,通知主线程窗口已创建
                    _windowCreatedEvent.Set();

                    // 可以选择关闭窗口
                    SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);

                    // 移除钩子
                    UnhookWindowsHookEx(_hHook);
                }
            }

            return CallNextHookEx(_hHook, nCode, wParam, lParam);
        }

        private bool IsTargetWindow(IntPtr hWnd)
        {
            // 根据窗口标题判断是否为目标窗口
            const string targetWindowTitle = "身份识别";
            StringBuilder sb = new StringBuilder(256);
            GetWindowText(hWnd, sb, sb.Capacity);
            return sb.ToString() == targetWindowTitle;

        }


        public void OperateYHControl(int key,string title)
        {
            //// 获取窗口句柄
            //IntPtr hWnd = FindWindow(null, title); // 替换为实际的窗口标题

            // 枚举所有顶级窗口
            IntPtr hWnd = FindWindowByPartialTitle(title); // 替换为实际的部分窗口标题

            if (hWnd != IntPtr.Zero)
            {
                Global.writeLog("找到了窗口,句柄: " + hWnd.ToString());
                // 发送单快捷键
                SendShortcutKey(hWnd, key);
            }
            else
            {
                Global.writeLog("未找到窗口" + title);
            }
        }

        private void SendShortcutKey(IntPtr hWnd,  int key)
        {

            // 按下A键
            PostMessage(hWnd, WM_KEYDOWN, (IntPtr)key, IntPtr.Zero);

            // 释放A键
            PostMessage(hWnd, WM_KEYUP, (IntPtr)key, IntPtr.Zero);

        }
        private void SendShortcutKey(IntPtr hWnd, int controlKey, int key)
        {
            // 按下Ctrl键
            PostMessage(hWnd, WM_KEYDOWN, (IntPtr)controlKey, IntPtr.Zero);

            // 按下A键
            PostMessage(hWnd, WM_KEYDOWN, (IntPtr)key, IntPtr.Zero);

            // 释放A键
            PostMessage(hWnd, WM_KEYUP, (IntPtr)key, IntPtr.Zero);

            // 释放Ctrl键
            PostMessage(hWnd, WM_KEYUP, (IntPtr)controlKey, IntPtr.Zero);
        }


        

        private IntPtr FindWindowByPartialTitle(string partialTitle)
        {
            IntPtr hWnd = IntPtr.Zero;
            EnumWindows((hWndIter, lParam) =>
            {
                if (IsWindowVisible(hWndIter))
                {
                    int length = GetWindowTextLength(hWndIter);
                    StringBuilder sb = new StringBuilder(length + 1);
                    GetWindowText(hWndIter, sb, sb.Capacity);
                    string windowText = sb.ToString();

                    if (windowText.Contains(partialTitle))
                    {
                        hWnd = hWndIter;
                        return false; // 停止枚举
                    }
                }
                return true; // 继续枚举
            }, IntPtr.Zero);

            return hWnd;
        }
    }
}