import customtkinter as ctk
import requests
import pyautogui
import pyperclip
import time
import threading
from datetime import datetime
import keyboard

# --- إعدادات المظهر ---
ctk.set_appearance_mode("Dark")
ctk.set_default_color_theme("dark-blue")

# --- إعدادات الأمان ---
pyautogui.FAILSAFE = True

# --- الثوابت ---
ORDERS_API_URL = "http://152.53.237.169/api/get_orders_for_bot.php"
EXCEL_COLUMN_OFFSET = 9 

class OrderCard(ctk.CTkFrame):
    def __init__(self, master, order_data, writer_func):
        super().__init__(master, fg_color="#2b2b2b", corner_radius=10, border_width=1, border_color="#3a3a3a")
        self.order_data = order_data
        self.writer_func = writer_func
        
        # معالجة الوقت وتخزين وقت الإنشاء للمقارنة
        try:
            self.created_at_dt = datetime.strptime(str(order_data['created_at']), "%Y-%m-%d %H:%M:%S")
            time_str = self.created_at_dt.strftime("%I:%M %p")
        except:
            self.created_at_dt = datetime.now()
            time_str = str(order_data.get('created_at', ''))

        # استخراج البيانات
        self.brand_name = str(order_data.get('brand_name', 'Unknown'))
        self.cust_name = str(order_data.get('customer_name', 'Unknown'))
        self.cust_phone = str(order_data.get('customer_phone', ''))
        self.short_code = str(order_data.get('short_code', ''))
        amount = order_data.get('total_amount', 0)
        payment = str(order_data.get('payment_type', 'CASH')).upper()

        self.payment_color = "#2ecc71" if payment == "CASH" else "#3498db"

        # عناصر البطاقة
        self.lbl_brand = ctk.CTkLabel(self, text=f"{self.brand_name} ({self.short_code})", 
                                      font=("Segoe UI", 12, "bold"), text_color="#f1c40f")
        self.lbl_brand.pack(anchor="w", padx=10, pady=(5, 0))

        info_text = f"{self.cust_name}\n{amount} EGP | {payment}"
        self.lbl_info = ctk.CTkLabel(self, text=info_text, font=("Segoe UI", 12), justify="left", text_color="white")
        self.lbl_info.pack(anchor="w", padx=10, pady=0)

        self.lbl_time = ctk.CTkLabel(self, text=time_str, font=("Arial", 10), text_color="gray")
        self.lbl_time.pack(anchor="w", padx=10, pady=(0, 5))

        self.btn_write = ctk.CTkButton(self, text="⚡", width=40, height=30, 
                                       fg_color=self.payment_color, hover_color="#d35400", 
                                       font=("Segoe UI", 14, "bold"),
                                       command=self.on_write_click)
        self.btn_write.place(relx=0.95, rely=0.5, anchor="e")

    def on_write_click(self):
        self.btn_write.configure(state="disabled", fg_color="gray", text="⏳")
        threading.Thread(target=self.run_writer_safe).start()

    def run_writer_safe(self):
        try:
            self.writer_func(self.order_data)
        except Exception as e:
            print(f"Error writing: {e}")
        finally:
            self.after(0, self.reset_button)

    def reset_button(self):
        self.btn_write.configure(state="normal", fg_color=self.payment_color, text="⚡")


class MagicApp(ctk.CTk):
    def __init__(self):
        super().__init__()

        self.title("Magic Writer (Fixed V12.2)")
        self.geometry("380x650")
        self.attributes("-topmost", True)
        
        self.seen_orders = set() 
        self.first_load = True 
        self.all_cards = [] 

        # --- الهيدر ---
        self.header = ctk.CTkFrame(self, height=90, fg_color="#1a1a1a")
        self.header.pack(fill="x", padx=2, pady=2)
        
        self.top_frame = ctk.CTkFrame(self.header, fg_color="transparent")
        self.top_frame.pack(fill="x", padx=5, pady=5)

        self.lbl_title = ctk.CTkLabel(self.top_frame, text="Magic Bot 🤖", font=("Segoe UI", 14, "bold"))
        self.lbl_title.pack(side="left", padx=5)
        
        self.btn_refresh = ctk.CTkButton(self.top_frame, text="🔄", width=30, fg_color="#e74c3c", command=self.hard_refresh)
        self.btn_refresh.pack(side="right", padx=5)

        self.lbl_status = ctk.CTkLabel(self.top_frame, text="●", font=("Arial", 16), text_color="gray")
        self.lbl_status.pack(side="right", padx=5)

        self.search_var = ctk.StringVar()
        # تصحيح الخطأ: استخدام trace_add بدلاً من trace
        self.search_var.trace_add("write", lambda *args: self.filter_orders())
        
        self.entry_search = ctk.CTkEntry(self.header, placeholder_text="بحث...", textvariable=self.search_var, height=30)
        self.entry_search.pack(fill="x", padx=10, pady=(0, 10))

        # --- القائمة ---
        self.scroll_frame = ctk.CTkScrollableFrame(self, fg_color="transparent")
        self.scroll_frame.pack(fill="both", expand=True, padx=5, pady=5)
        
        self.lbl_placeholder = ctk.CTkLabel(self.scroll_frame, text="جاري الاتصال بالسيرفر...", font=("Arial", 14))
        self.lbl_placeholder.pack(pady=20)

        self.is_visible = True
        keyboard.add_hotkey('F8', self.toggle_visibility)

        self.start_auto_refresh()

    def toggle_visibility(self):
        if self.is_visible:
            self.withdraw()
            self.is_visible = False
        else:
            self.deiconify()
            self.is_visible = True

    def start_auto_refresh(self):
        threading.Thread(target=self.fetch_orders_thread, daemon=True).start()
        self.after(5000, self.start_auto_refresh)

    def fetch_orders_thread(self):
        try:
            self.after(0, lambda: self.lbl_status.configure(text_color="yellow"))
            response = requests.get(ORDERS_API_URL, timeout=10)
            
            if response.status_code == 200:
                orders = response.json()
                self.after(0, lambda: self.update_gui(orders))
                self.after(0, lambda: self.lbl_status.configure(text_color="#2ecc71"))
            else:
                self.after(0, lambda: self.lbl_status.configure(text_color="red"))
        except Exception as e:
            print(f"Connection Error: {e}")
            self.after(0, lambda: self.lbl_status.configure(text_color="red"))

    def update_gui(self, orders):
        if not orders:
            if self.first_load:
                 self.lbl_placeholder.configure(text="لا توجد طلبات حالياً 💤")
            return

        if self.first_load:
            if self.lbl_placeholder.winfo_exists():
                self.lbl_placeholder.destroy()
            self.first_load = False

        new_added = False
        for order in orders:
            uuid = order.get('order_uuid') or order.get('short_code')
            if uuid and uuid not in self.seen_orders:
                # إنشاء الكارت وإضافته للقائمة الداخلية فقط
                card = OrderCard(self.scroll_frame, order, self.write_sequence)
                self.all_cards.append(card)
                self.seen_orders.add(uuid)
                new_added = True
        
        if new_added:
            # إعادة ترتيب القائمة بحيث يكون الأحدث (أكبر تاريخ) في الأول
            self.all_cards.sort(key=lambda c: c.created_at_dt, reverse=True)
            # إعادة رسم الواجهة
            self.filter_orders()

    # تم إلغاء دالة create_and_insert_card القديمة واستبدالها بالمنطق أعلاه لتجنب خطأ الترتيب

    def filter_orders(self):
        # تصحيح الخطأ: بدلاً من محاولة الحشر (Insert Before) التي تسبب كراش
        # نقوم بإخفاء الجميع ثم إظهار المطلوبين بالترتيب الصحيح
        
        query = self.search_var.get().lower().strip()
        
        # 1. إخفاء جميع الكروت مؤقتاً (بدون حذفها)
        for child in self.scroll_frame.winfo_children():
            if isinstance(child, OrderCard):
                child.pack_forget()

        # 2. إظهار الكروت التي تطابق البحث بالترتيب الموجود في self.all_cards
        for card in self.all_cards:
            search_text = f"{card.short_code} {card.cust_name} {card.cust_phone}".lower()
            if not query or query in search_text:
                # الـ Pack هنا آمن لأنه يضيف للنهاية، وبما أن القائمة مرتبة فالنتيجة مرتبة
                card.pack(fill="x", padx=5, pady=5)

    def hard_refresh(self):
        self.seen_orders.clear()
        self.all_cards.clear()
        self.first_load = True
        
        for widget in self.scroll_frame.winfo_children():
            widget.destroy()
        
        self.lbl_placeholder = ctk.CTkLabel(self.scroll_frame, text="جاري التحديث...", font=("Arial", 14))
        self.lbl_placeholder.pack(pady=20)
        
        threading.Thread(target=self.fetch_orders_thread, daemon=True).start()

    # --- أدوات الكتابة ---
    def col_to_index(self, col_str):
        if not col_str: return 0
        num = 0
        for c in str(col_str):
            if c.isdigit(): return 0 
            num = num * 26 + (ord(c.upper()) - ord('A')) + 1
        return num

    def paste_text(self, text, wait=0.1):
        val = str(text).strip()
        if not val or val.lower() == 'none': return
        pyperclip.copy(val)
        time.sleep(wait) 
        pyautogui.hotkey('ctrl', 'v')
        time.sleep(wait)

    def write_sequence(self, order):
        pyautogui.hotkey('alt', 'tab')
        time.sleep(0.8) 

        payment_type = str(order.get('payment_type', '')).upper()
        target_col_letter = order.get('cash_column') if payment_type == 'CASH' else order.get('online_column')
        target_col_index = self.col_to_index(target_col_letter)
        total_amount = str(order.get('total_amount', '0'))

        pyautogui.press('tab') 
        self.paste_text(order.get('short_code'))
        
        pyautogui.press('tab') 
        self.paste_text(order.get('customer_name'))
        
        pyautogui.press('tab') 
        phone = str(order.get('customer_phone', ''))
        if phone: self.paste_text("'" + phone)
        
        pyautogui.press('tab') 
        self.paste_text(str(order.get('external_id')))
        
        pyautogui.press('tab') 
        if payment_type == 'CASH':
            self.paste_text(total_amount)
            
        pyautogui.press('tab') 
        self.paste_text("60")
        
        pyautogui.press('home') 
        time.sleep(0.3) 

        jumps_needed = (target_col_index - 1) - EXCEL_COLUMN_OFFSET
        if jumps_needed < 0: jumps_needed = 0

        if jumps_needed > 0:
            for _ in range(jumps_needed):
                pyautogui.press('tab')
            time.sleep(0.2) 
            self.paste_text(total_amount)
        
        pyautogui.press('enter')  
        pyautogui.press('home')   

if __name__ == "__main__":
    app = MagicApp()
    app.mainloop()