"""
SirAbody Easy Mode - أسهل واجهة برمجية في تاريخ البايثون!
=========================================================

كل اللي تحتاجه:
    >>> import sirabody
    >>> app = sirabody.App("My App")
    >>> app.add("Button Name", link="https://google.com")
    >>> app.run()

الوظائف المتاحة لكل زر:
─────────────────────────────────────────────────────────
  link        = فتح رابط في المتصفح
  message     = عرض رسالة منبثقة
  run         = تشغيل برنامج أو أمر
  file        = فتح ملف أو مجلد
  copy        = نسخ نص للحافظة
  hotkey      = ضغط اختصار لوحة مفاتيح (ماكرو)
  type_text   = كتابة نص تلقائي (ماكرو)
  close       = إغلاق البرنامج
  steps       = تنفيذ عدة أوامر متتالية (ماكرو متقدم)
  action      = ربط دالة بايثون مخصصة (متقدم)
─────────────────────────────────────────────────────────
"""

import os
import sys
import time
import webbrowser
import subprocess
import ctypes
import threading
from PySide6.QtWidgets import QApplication, QMessageBox
from PySide6.QtCore import Qt
from PySide6.QtGui import QFont, QIcon, QGuiApplication

from .window import SirAbodyWindow


# ═══════════════════════════════════════════════════════════════
#  Auto Colors
# ═══════════════════════════════════════════════════════════════

_AUTO_COLORS = [
    "#FFD700", "#FF6B6B", "#69F0AE", "#40C4FF",
    "#9B59B6", "#1ABC9C", "#FF9800", "#E91E63",
    "#00BCD4", "#8BC34A",
]


# ═══════════════════════════════════════════════════════════════
#  Keyboard Helper (Windows - ctypes)
# ═══════════════════════════════════════════════════════════════

# Virtual Key Codes (Windows)
_VK_CODES = {
    # حروف
    "a": 0x41, "b": 0x42, "c": 0x43, "d": 0x44, "e": 0x45, "f": 0x46,
    "g": 0x47, "h": 0x48, "i": 0x49, "j": 0x4A, "k": 0x4B, "l": 0x4C,
    "m": 0x4D, "n": 0x4E, "o": 0x4F, "p": 0x50, "q": 0x51, "r": 0x52,
    "s": 0x53, "t": 0x54, "u": 0x55, "v": 0x56, "w": 0x57, "x": 0x58,
    "y": 0x59, "z": 0x5A,
    # أرقام
    "0": 0x30, "1": 0x31, "2": 0x32, "3": 0x33, "4": 0x34,
    "5": 0x35, "6": 0x36, "7": 0x37, "8": 0x38, "9": 0x39,
    # مفاتيح خاصة
    "enter": 0x0D, "return": 0x0D,
    "tab": 0x09,
    "space": 0x20,
    "backspace": 0x08, "back": 0x08,
    "delete": 0x2E, "del": 0x2E,
    "escape": 0x1B, "esc": 0x1B,
    "up": 0x26, "down": 0x28, "left": 0x25, "right": 0x27,
    "home": 0x24, "end": 0x23,
    "pageup": 0x21, "pagedown": 0x22,
    "insert": 0x2D,
    "capslock": 0x14,
    "numlock": 0x90,
    "printscreen": 0x2C, "prtsc": 0x2C,
    # مفاتيح التعديل
    "ctrl": 0xA2, "control": 0xA2,
    "alt": 0xA4,
    "shift": 0xA0,
    "win": 0x5B, "windows": 0x5B, "super": 0x5B,
    # مفاتيح الوظائف
    "f1": 0x70, "f2": 0x71, "f3": 0x72, "f4": 0x73,
    "f5": 0x74, "f6": 0x75, "f7": 0x76, "f8": 0x77,
    "f9": 0x78, "f10": 0x79, "f11": 0x7A, "f12": 0x7B,
    # رموز
    "+": 0xBB, "-": 0xBD, "=": 0xBB,
    ",": 0xBC, ".": 0xBE,
    "/": 0xBF, "\\": 0xDC,
    ";": 0xBA, "'": 0xDE,
    "[": 0xDB, "]": 0xDD,
    "`": 0xC0,
}

# ctypes structures for SendInput
INPUT_KEYBOARD = 1
KEYEVENTF_KEYUP = 0x0002

class _KEYBDINPUT(ctypes.Structure):
    _fields_ = [
        ("wVk", ctypes.c_ushort),
        ("wScan", ctypes.c_ushort),
        ("dwFlags", ctypes.c_ulong),
        ("time", ctypes.c_ulong),
        ("dwExtraInfo", ctypes.POINTER(ctypes.c_ulong)),
    ]

class _INPUT(ctypes.Structure):
    class _INPUT_UNION(ctypes.Union):
        _fields_ = [("ki", _KEYBDINPUT)]
    _fields_ = [
        ("type", ctypes.c_ulong),
        ("union", _INPUT_UNION),
    ]


def _press_key(vk):
    """ضغط مفتاح واحد."""
    inp = _INPUT()
    inp.type = INPUT_KEYBOARD
    inp.union.ki.wVk = vk
    ctypes.windll.user32.SendInput(1, ctypes.byref(inp), ctypes.sizeof(inp))


def _release_key(vk):
    """رفع مفتاح واحد."""
    inp = _INPUT()
    inp.type = INPUT_KEYBOARD
    inp.union.ki.wVk = vk
    inp.union.ki.dwFlags = KEYEVENTF_KEYUP
    ctypes.windll.user32.SendInput(1, ctypes.byref(inp), ctypes.sizeof(inp))


def _send_hotkey(combo_string):
    """تنفيذ اختصار لوحة مفاتيح.

    Examples:
        _send_hotkey("ctrl+c")
        _send_hotkey("alt+f4")
        _send_hotkey("win+r")
        _send_hotkey("ctrl+shift+s")
    """
    keys = [k.strip().lower() for k in combo_string.split("+")]
    vk_list = []
    for k in keys:
        vk = _VK_CODES.get(k)
        if vk:
            vk_list.append(vk)

    # Press all keys
    for vk in vk_list:
        _press_key(vk)
    time.sleep(0.05)
    # Release all keys (reverse order)
    for vk in reversed(vk_list):
        _release_key(vk)


def _type_string(text):
    """كتابة نص حرف بحرف."""
    for char in text:
        vk = _VK_CODES.get(char.lower())
        if vk:
            if char.isupper():
                _press_key(_VK_CODES["shift"])
                _press_key(vk)
                time.sleep(0.02)
                _release_key(vk)
                _release_key(_VK_CODES["shift"])
            else:
                _press_key(vk)
                time.sleep(0.02)
                _release_key(vk)
        elif char == " ":
            _press_key(_VK_CODES["space"])
            time.sleep(0.02)
            _release_key(_VK_CODES["space"])
        time.sleep(0.03)


# ═══════════════════════════════════════════════════════════════
#  Step Executor (for macros)
# ═══════════════════════════════════════════════════════════════

def _execute_step(step):
    """تنفيذ خطوة واحدة من الماكرو."""
    if "link" in step:
        webbrowser.open(step["link"])
    elif "run" in step:
        subprocess.Popen(step["run"], shell=True)
    elif "hotkey" in step:
        _send_hotkey(step["hotkey"])
    elif "type_text" in step:
        _type_string(step["type_text"])
    elif "wait" in step:
        time.sleep(step["wait"])
    elif "copy" in step:
        _copy_to_clipboard(step["copy"])
    elif "file" in step:
        os.startfile(step["file"])


def _execute_steps(steps):
    """تنفيذ سلسلة خطوات (ماكرو) في thread منفصل."""
    def _run():
        for step in steps:
            _execute_step(step)
    thread = threading.Thread(target=_run, daemon=True)
    thread.start()


# ═══════════════════════════════════════════════════════════════
#  Clipboard Helper
# ═══════════════════════════════════════════════════════════════

def _copy_to_clipboard(text):
    """نسخ نص للحافظة."""
    clipboard = QGuiApplication.clipboard()
    if clipboard:
        clipboard.setText(text)


# ═══════════════════════════════════════════════════════════════
#  Message Box
# ═══════════════════════════════════════════════════════════════

def _show_message(title, text):
    """عرض رسالة منبثقة."""
    msg = QMessageBox()
    msg.setWindowTitle(title)
    msg.setText(text)
    msg.setStyleSheet("""
        QMessageBox { background-color: #1a1a1a; }
        QMessageBox QLabel { color: #fff; font-size: 14px; }
        QPushButton {
            background-color: #333; color: #fff;
            border: 1px solid #555; border-radius: 5px;
            padding: 5px 20px; min-width: 60px;
        }
        QPushButton:hover { background-color: #555; }
    """)
    msg.exec()


# ═══════════════════════════════════════════════════════════════
#  Main App Class
# ═══════════════════════════════════════════════════════════════

class App:
    """أسهل طريقة لإنشاء واجهة رسومية في بايثون!

    ══════════════════════════════════════════════
     الاستخدام الأساسي:
    ══════════════════════════════════════════════

        >>> import sirabody
        >>> app = sirabody.App("My App")
        >>> app.add("Google", link="https://google.com")
        >>> app.run()

    ══════════════════════════════════════════════
     جميع وظائف الأزرار المتاحة:
    ══════════════════════════════════════════════

     link = فتح رابط ──────────────────────────
        >>> app.add("Google", link="https://google.com")
        >>> app.add("YouTube", link="https://youtube.com")

     message = رسالة منبثقة ────────────────────
        >>> app.add("Say Hi", message="Hello World!")
        >>> app.add("Warning", message="Be careful!")

     run = تشغيل برنامج ───────────────────────
        >>> app.add("Notepad", run="notepad")
        >>> app.add("Calculator", run="calc")
        >>> app.add("CMD", run="cmd")
        >>> app.add("My Script", run="python my_script.py")

     file = فتح ملف أو مجلد ───────────────────
        >>> app.add("Desktop", file="C:/Users/Desktop")
        >>> app.add("My Doc", file="C:/Users/document.txt")

     copy = نسخ نص للحافظة ────────────────────
        >>> app.add("Copy Email", copy="me@email.com")
        >>> app.add("Copy Key", copy="XXXX-YYYY-ZZZZ")

     hotkey = اختصار لوحة مفاتيح (ماكرو) ─────
        >>> app.add("Screenshot", hotkey="win+shift+s")
        >>> app.add("Copy", hotkey="ctrl+c")
        >>> app.add("Paste", hotkey="ctrl+v")
        >>> app.add("Undo", hotkey="ctrl+z")
        >>> app.add("Save", hotkey="ctrl+s")
        >>> app.add("Select All", hotkey="ctrl+a")
        >>> app.add("Close Window", hotkey="alt+f4")
        >>> app.add("Task Manager", hotkey="ctrl+shift+escape")
        >>> app.add("Run Dialog", hotkey="win+r")
        >>> app.add("Desktop", hotkey="win+d")

     type_text = كتابة نص تلقائي (ماكرو) ─────
        >>> app.add("Write Hello", type_text="Hello World")
        >>> app.add("Write Email", type_text="me@email.com")

     close = إغلاق البرنامج ───────────────────
        >>> app.add("Exit", close=True)

     steps = ماكرو متعدد الخطوات ──────────────
        >>> app.add("Open Notepad and Write", steps=[
        ...     {"hotkey": "win+r"},        # افتح Run
        ...     {"wait": 0.5},              # انتظر نص ثانية
        ...     {"type_text": "notepad"},   # اكتب notepad
        ...     {"hotkey": "enter"},        # اضغط Enter
        ...     {"wait": 1},               # انتظر ثانية
        ...     {"type_text": "Hello!"},   # اكتب Hello!
        ... ])

     action = دالة بايثون مخصصة (متقدم) ──────
        >>> def my_function():
        ...     print("Custom action!")
        >>> app.add("Custom", action=my_function)

    ══════════════════════════════════════════════
     إعدادات الواجهة (اختياري):
    ══════════════════════════════════════════════

        >>> app.set(columns=3)          # 3 أعمدة بدل 2
        >>> app.set(rain=False)         # بدون مطر
        >>> app.set(title_color="#FF0000")  # عنوان أحمر
        >>> app.set(width=1200, height=800)  # حجم أكبر

    ══════════════════════════════════════════════
     المفاتيح المتاحة للـ hotkey:
    ══════════════════════════════════════════════

     حروف: a-z
     أرقام: 0-9
     تعديل: ctrl, alt, shift, win
     وظائف: f1-f12
     خاصة: enter, tab, space, backspace, delete,
            escape, up, down, left, right,
            home, end, pageup, pagedown,
            insert, capslock, printscreen

     الفاصل بين المفاتيح: + (مثل ctrl+c)
    """

    def __init__(self, title, subtitle=""):
        self._title = title
        self._subtitle = subtitle
        self._buttons = []
        self._settings = {}
        self._window = None

    def add(self, name, link=None, message=None, run=None, file=None,
            copy=None, hotkey=None, type_text=None, close=None,
            steps=None, action=None, color=None):
        """أضف زر جديد للواجهة.

        Args:
            name (str): اسم الزر

            link (str): رابط يفتح في المتصفح
                >>> app.add("Google", link="https://google.com")

            message (str): رسالة منبثقة
                >>> app.add("Hi", message="Hello World!")

            run (str): أمر أو برنامج يتم تشغيله
                >>> app.add("Notepad", run="notepad")
                >>> app.add("Script", run="python script.py")

            file (str): مسار ملف أو مجلد لفتحه
                >>> app.add("Desktop", file="C:/Users/Desktop")

            copy (str): نص يتم نسخه للحافظة
                >>> app.add("Copy Email", copy="me@email.com")

            hotkey (str): اختصار لوحة مفاتيح
                >>> app.add("Screenshot", hotkey="win+shift+s")
                >>> app.add("Copy", hotkey="ctrl+c")

            type_text (str): نص يكتب تلقائياً
                >>> app.add("Write", type_text="Hello World")

            close (bool): إغلاق البرنامج
                >>> app.add("Exit", close=True)

            steps (list[dict]): قائمة خطوات ماكرو
                >>> app.add("Macro", steps=[
                ...     {"hotkey": "win+r"},
                ...     {"wait": 0.5},
                ...     {"type_text": "notepad"},
                ...     {"hotkey": "enter"},
                ... ])

            action (callable): دالة مخصصة
                >>> app.add("Custom", action=my_function)

            color (str): لون الزر (اختياري، يتعين تلقائي)
                >>> app.add("Red Button", link="...", color="#FF0000")

        Returns:
            App: نفس الكائن (للربط المتسلسل)
        """
        auto_color = color or _AUTO_COLORS[len(self._buttons) % len(_AUTO_COLORS)]

        # Build callback based on what was provided
        callback = None

        if link:
            url = link
            callback = lambda: webbrowser.open(url)

        elif message:
            msg = message
            btn_name = name
            callback = lambda: _show_message(btn_name, msg)

        elif run:
            cmd = run
            callback = lambda: subprocess.Popen(cmd, shell=True)

        elif file:
            path = file
            callback = lambda: os.startfile(path)

        elif copy:
            txt = copy
            callback = lambda: _copy_to_clipboard(txt)

        elif hotkey:
            combo = hotkey
            callback = lambda: threading.Thread(
                target=_send_hotkey, args=(combo,), daemon=True
            ).start()

        elif type_text:
            text = type_text
            callback = lambda: threading.Thread(
                target=_type_string, args=(text,), daemon=True
            ).start()

        elif close:
            callback = lambda: sys.exit(0)

        elif steps:
            step_list = steps
            callback = lambda: _execute_steps(step_list)

        elif action:
            callback = action

        self._buttons.append({
            "text": name,
            "color": auto_color,
            "callback": callback,
        })

        return self

    def set(self, **kwargs):
        """غيّر إعدادات الواجهة (اختياري).

        الإعدادات المتاحة:
            >>> app.set(columns=3)                 # عدد أعمدة الأزرار
            >>> app.set(rain=False)                 # تعطيل المطر
            >>> app.set(title_color="#FF0000")       # لون العنوان
            >>> app.set(width=1200, height=800)     # حجم النافذة
            >>> app.set(opacity=200)                # شفافية (0-255)
            >>> app.set(version="v2.0")             # نص الإصدار
            >>> app.set(website_url="https://...")   # رابط الموقع
            >>> app.set(discord_url="https://...")   # رابط الديسكورد
            >>> app.set(icon="path/to/icon.ico")    # أيقونة النافذة

        Returns:
            App: نفس الكائن
        """
        self._settings.update(kwargs)
        return self

    def run(self):
        """شغّل التطبيق!

        هذا آخر سطر تكتبه. بعده تطلع الواجهة.

            >>> app.run()
        """
        QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
        qt_app = QApplication(sys.argv)

        icon = self._settings.get("icon")
        if icon and os.path.exists(icon):
            qt_app.setWindowIcon(QIcon(icon))

        qt_app.setFont(QFont("Segoe UI", 10))

        # Map simple names to SirAbodyWindow params
        window_kwargs = {
            "title": self._title,
            "subtitle": self._subtitle,
            "buttons": self._buttons,
        }

        _MAP = {
            "version": "version",
            "title_color": "title_color",
            "website_url": "website_url",
            "discord_url": "discord_url",
            "rain": "rain_enabled",
            "columns": "columns",
            "opacity": "bg_opacity",
            "width": "width",
            "height": "height",
            "rain_config": "rain_config",
            "status_text": "status_text",
            "status_color": "status_color",
        }

        for simple, real in _MAP.items():
            if simple in self._settings:
                window_kwargs[real] = self._settings[simple]

        self._window = SirAbodyWindow(**window_kwargs)
        self._window.show()
        sys.exit(qt_app.exec())
