using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;
using Tainikey.Mappers;

namespace Tainikey
{
    public partial class frmMain : Form
    {
        private KeyboardHook hook;
        private KeyboardEngine engine;
        private HotkeyWindow hotkeyWindow;

        private bool isTypingEnabled = true;
        private const string appName = "Tainikey";

        private NotifyIcon trayIcon;
        private ContextMenuStrip trayMenu;

        // Hotkeys
        private const int HOTKEY_TAIVIET = 1;
        private const int HOTKEY_TAIYO = 2;
        private const uint MOD_CONTROL = 0x0002;
        private const uint MOD_ALT = 0x0001;
        private const uint VK_X = 0x58;
        private const uint VK_J = 0x4A;

        [DllImport("user32.dll")]
        private static extern short GetKeyState(int keyCode);
        private const int VK_SHIFT = 0x10;

        //Đặt trạng thái Reset App hay không?
        private bool isResetting = false;

        public frmMain()
        {
            InitializeComponent();

            engine = new KeyboardEngine();

            LoadStartupStatus();
            this.KeyPreview = true;

            hook = new KeyboardHook();
            hook.OnKeyPressed += Hook_OnKeyPressed;
            hook.Start();

            trayMenu = new ContextMenuStrip();
            trayMenu.Items.Add("Mở Tainikey", null, (s, e) => ShowMainWindow());
            trayMenu.Items.Add("Thoát", null, (s, e) => ExitApp());

            trayIcon = new NotifyIcon();
            trayIcon.Icon = CreateTrayIcon("A");
            trayIcon.Text = "Tainikey - Gõ chữ thường";
            trayIcon.ContextMenuStrip = trayMenu;
            trayIcon.Visible = true;

            trayIcon.MouseClick += TrayIcon_MouseClick;
            // Thêm sự kiện double-click để mở nhanh cửa sổ chính
            trayIcon.DoubleClick += TrayIcon_DoubleClick;

            // Khởi tạo ToolTip
            ToolTip toolTip = new ToolTip();

            // Thiết lập thời gian hiển thị (tùy chọn)
            toolTip.AutoPopDelay = 5000; // Hiển thị trong 5 giây
            toolTip.InitialDelay = 500;  // Chờ 0.5 giây sau khi hover thì hiện
            toolTip.ReshowDelay = 500;   // Thời gian chờ giữa các lần hiện lại
            toolTip.ShowAlways = true;   // Luôn hiện kể cả khi Form không active

            // Gán nội dung chú thích cho từng Checkbox
            toolTip.SetToolTip(this.chkStartup, "Tự động mở Tainikey để có thể gõ chữ Thái ngay khi bạn bật máy tính.");
            toolTip.SetToolTip(this.chkSpecialMarks, "Cho phép gõ các dấu ngang, dấu móc \nbằng cách gõ phím gạch ngang (-), gạch dưới (_). \nVí dụ: a_ -> ā, a_ -> ǎ.");
        }

        private void TrayIcon_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
                ToggleInputMode();
        }
        private void TrayIcon_DoubleClick(object sender, EventArgs e)
        {
            ShowMainWindow();
        }

        // ========================= KEY PROCESSING ===============================

        private bool isProcessing = false; // Biến lính canh

        private bool Hook_OnKeyPressed(Keys key)
        {
            // Nếu đang trong quá trình tự gửi phím thì bỏ qua không xử lý
            if (isProcessing) return false;

            bool ctrl = (GetKeyState(0x11) & 0x8000) != 0;
            bool alt = (GetKeyState(0x12) & 0x8000) != 0;
            if (ctrl || alt) return false;

            bool shift = (GetKeyState(0x10) & 0x8000) != 0;
            string output;

            if (engine.ProcessKey(key, shift, out output))
            {
                isProcessing = true; // Bắt đầu chặn Hook
                try
                {
                    engine.FeedChar(output);
                    SendKeys.SendWait(output);
                }
                catch (Exception ex)
                {
                    // Xử lý lỗi Queue empty nếu có
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                }
                finally
                {
                    isProcessing = false; // Mở chặn để nhận phím tiếp theo từ người dùng
                }
                return true;
            }
            return false;
        }

        // ========================= MODE CONTROL ===============================

        private void SetMode(InputMode mode)
        {
            engine.Mode = mode;
            isTypingEnabled = (mode != InputMode.None);

            if (mode == InputMode.SueTai)
            {
                btnToggle.Text = "T";
                btnToggle.BackColor = Color.FromArgb(0, 64, 0);
            }
            else if (mode == InputMode.LaiTai)
            {
                btnToggle.Text = "L";
                btnToggle.BackColor = Color.Teal;
            }
            else
            {
                btnToggle.Text = "A";
                btnToggle.BackColor = Color.FromArgb(192, 0, 0);
            }

            UpdateTrayIcon();
        }

        private void ToggleInputMode()
        {
            if (engine.Mode == InputMode.SueTai)
                SetMode(InputMode.LaiTai);
            else if (engine.Mode == InputMode.LaiTai)
                SetMode(InputMode.None);
            else
                SetMode(InputMode.SueTai);
        }

        private void btnToggle_Click(object sender, EventArgs e)
        {
            ToggleInputMode();
        }

        // ========================= TRAY ICON ===============================

        private void UpdateTrayIcon()
        {
            string label = "A";
            string tooltip = "Tainikey - Gõ chữ thường";

            if (engine.Mode == InputMode.SueTai)
            {
                label = "T";
                tooltip = "Tainikey - Gõ chữ Tai Viet";
            }
            else if (engine.Mode == InputMode.LaiTai)
            {
                label = "L";
                tooltip = "Tainikey - Gõ chữ Tai Yo";
            }

            if (trayIcon.Icon != null)
                trayIcon.Icon.Dispose();

            trayIcon.Icon = CreateTrayIcon(label);
            trayIcon.Text = tooltip;
        }

        private Icon CreateTrayIcon(string text)
        {
            Bitmap bmp = new Bitmap(32, 32);
            Graphics g = Graphics.FromImage(bmp);

            Color bg = Color.Red;
            if (text == "T") bg = Color.FromArgb(0, 64, 0);
            else if (text == "L") bg = Color.Teal;

            g.FillRectangle(new SolidBrush(bg), 0, 0, 32, 32);
            g.DrawRectangle(new Pen(Color.White, 2), 1, 1, 30, 30);

            Font f = new Font("Arial", 18, FontStyle.Bold);
            Brush br = new SolidBrush(Color.White);
            StringFormat sf = new StringFormat();
            sf.LineAlignment = StringAlignment.Center;
            sf.Alignment = StringAlignment.Center;

            g.DrawString(text, f, br, new RectangleF(0, 0, 32, 32), sf);

            //return Icon.FromHandle(bmp.GetHicon());
            Icon icon = Icon.FromHandle(bmp.GetHicon());
            return icon;
        }

        // ========================= HOTKEY SYSTEM ===============================

        [DllImport("user32.dll")]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

        [DllImport("user32.dll")]
        public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        private void frmMain_Load(object sender, EventArgs e)
        {
            this.Text = "Tainikey " + Application.ProductVersion;

            // 1. Đăng ký Hotkey (Giữ nguyên của bạn)
            hotkeyWindow = new HotkeyWindow();
            hotkeyWindow.HotkeyPressed += HotkeyWindow_HotkeyPressed;
            RegisterHotKey(hotkeyWindow.Handle, HOTKEY_TAIVIET, MOD_CONTROL | MOD_ALT, VK_X);
            RegisterHotKey(hotkeyWindow.Handle, HOTKEY_TAIYO, MOD_CONTROL | MOD_ALT, VK_J);

            // 2. Load trạng thái từ Registry TRƯỚC
            bool isEnabled = LoadSpecialMarksStatus();

            // 3. Áp dụng vào Checkbox (Việc này sẽ kích hoạt chkSpecialMarks_CheckedChanged nếu bạn đã đăng ký sự kiện)
            chkSpecialMarks.Checked = isEnabled;

            // 4. Cập nhật biến static để Engine sử dụng ngay
            SpecialMarksEnabled = isEnabled;
        }
        //<Tạo cửa sổ ẩn để đăng ký hotkey cho Ctrl+Alt+X và Ctrl+Alt+J khi Ẩn main window>
        private void HotkeyWindow_HotkeyPressed(int id)
        {
            if (id == HOTKEY_TAIVIET)
            {
                if (engine.Mode == InputMode.SueTai)
                    SetMode(InputMode.None);
                else
                    SetMode(InputMode.SueTai);
            }
            else if (id == HOTKEY_TAIYO)
            {
                if (engine.Mode == InputMode.LaiTai)
                    SetMode(InputMode.None);
                else
                    SetMode(InputMode.LaiTai);
            }
        }
        //</Tạo cửa sổ ẩn để đăng ký hotkey cho Ctrl+Alt+X và Ctrl+Alt+J khi Ẩn main window>
        // ========================= UI & WINDOW ===============================

        private void btnHide_Click(object sender, EventArgs e)
        {
            this.Hide();
            this.ShowInTaskbar = false;
        }

        private void ShowMainWindow()
        {
            this.Show();
            this.ShowInTaskbar = true;
            this.WindowState = FormWindowState.Normal;
            this.Activate();
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            trayIcon.Visible = false;

            hook.Stop();
            UnregisterHotKey(hotkeyWindow.Handle, HOTKEY_TAIVIET);
            UnregisterHotKey(hotkeyWindow.Handle, HOTKEY_TAIYO);

            base.OnFormClosing(e);
        }

        // <========================= STARTUP WITH WINDOWS ===============================

        private void chkStartup_CheckedChanged(object sender, EventArgs e)
        {
            if (chkStartup.Checked)
                AddToStartup();
            else
                RemoveFromStartup();
        }

        private void LoadStartupStatus()
        {
            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", false);
            if (key != null)
            {
                chkStartup.Checked = key.GetValue(appName) != null;
            }
        }

        private void AddToStartup()
        {
            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
            key.SetValue(appName, Application.ExecutablePath);
        }

        private void RemoveFromStartup()
        {
            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
            if (key.GetValue(appName) != null)
                key.DeleteValue(appName);
        }
        // </========================= STARTUP WITH WINDOWS ===============================
        // <========================= REMEMBER SPIECIAL CHECK =============================
        private void SaveSpecialMarksStatus(bool enabled)
        {
            // Lưu trạng thái vào Registry của người dùng
            RegistryKey key = Registry.CurrentUser.CreateSubKey(@"Software\" + appName);
            key.SetValue("SpecialMarks", enabled ? 1 : 0);
        }

        private bool LoadSpecialMarksStatus()
        {
            // Đọc trạng thái từ Registry, mặc định là false (0) nếu chưa có
            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\" + appName);
            if (key != null)
            {
                object val = key.GetValue("SpecialMarks");
                if (val != null) return (int)val == 1;
            }
            return false;
        }
        // </========================= REMEMBER SPIECIAL CHECK =============================
        private void ExitApp()
        {
            try
            {
                trayIcon.Visible = false;
                trayIcon.Dispose();
            }
            catch { }

            try
            {
                hook.Stop();
            }
            catch { }

            try
            {
                UnregisterHotKey(hotkeyWindow.Handle, HOTKEY_TAIVIET);
                UnregisterHotKey(hotkeyWindow.Handle, HOTKEY_TAIYO);
                hotkeyWindow.DestroyHandle();
            }
            catch { }

            Application.Exit();
        }

        private void btnTaiVietKeyMap_Click(object sender, EventArgs e)
        {
            frmKM_TaiViet frm = new frmKM_TaiViet();
            frm.Show();
        }

        private void btnLaiTaiKeyMap_Click(object sender, EventArgs e)
        {
            frmKM_TaiYo frm = new frmKM_TaiYo();
            frm.Show();
        }
        private void btnHuongDan_Click(object sender, EventArgs e)
        {
            frmHuongDan frm = new frmHuongDan();
            frm.Show();
        }
        private void btnThongTin_Click(object sender, EventArgs e)
        {
            frmThongTin frm = new frmThongTin();
            frm.Show();

        }
        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            // Nếu đang trong quá trình reset thì không hiển thị hộp thoại xác nhận
            if (isResetting == false)
            {
                // Hiển thị hộp thoại xác nhận với người dùng
                DialogResult result = MessageBox.Show(
                    "Bạn chuẩn bị Thoát ứng dụng. Nếu Thoát ứng dụng Tainikey thì sẽ không thể gõ chữ Thái. Bạn có chắc chắn muốn thoát không?",
                    "Tainikey - Cảnh báo",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Warning
                );

                // Nếu người dùng chọn No thì hủy việc đóng ứng dụng
                if (result == DialogResult.No)
                {
                    e.Cancel = true;
                    return;
                }
            }
            
            // Nếu chọn Yes, thực hiện dọn dẹp hệ thống trước khi thoát
            try
            {
                trayIcon.Visible = false;
                trayIcon.Dispose();
                hook.Stop();
                UnregisterHotKey(hotkeyWindow.Handle, HOTKEY_TAIVIET);
                UnregisterHotKey(hotkeyWindow.Handle, HOTKEY_TAIYO);
            }
            catch { }
        }

        public static bool SpecialMarksEnabled = false;
        private void chkSpecialMarks_CheckedChanged(object sender, EventArgs e)
        {
            SpecialMarksEnabled = chkSpecialMarks.Checked;
            SaveSpecialMarksStatus(chkSpecialMarks.Checked);
        }

        //<Xử lý nút Reset để khởi động lại engine nếu có lỗi>
        private void ResetApp()
        {
            isResetting = true; // Đặt cờ để biết đang trong quá trình reset
            Application.Restart();
            Environment.Exit(0);
        }
        private void btnReset_Click(object sender, EventArgs e)
        {
            ResetApp();
        }

        //</Xử lý nút Reset để khởi động lại engine nếu có lỗi>
    }
}
