import re
import time
import tkinter as tk
from datetime import date, datetime, timedelta
from tkinter import scrolledtext, messagebox

from core.storage import save_enterprise, save_notes, save_todos
from core.ui import create_button, create_card


class AIPage:
    def __init__(self, app, parent):
        self.app = app
        self.colors = app.colors
        self.frame = tk.Frame(parent, bg=self.colors["bg"])
        self._build()

    def _build(self):
        top = create_card(self.frame, self.colors, fill=tk.X, pady=(0, 14))
        inner = tk.Frame(top, bg=self.colors["card"])
        inner.pack(fill=tk.X, padx=20, pady=18)
        tk.Label(inner, text="AI", font=("Microsoft YaHei UI", 22, "bold"), fg="white", bg=self.colors["primary"], width=3).pack(side=tk.LEFT)
        title_box = tk.Frame(inner, bg=self.colors["card"])
        title_box.pack(side=tk.LEFT, padx=14)
        self.title = tk.Label(title_box, text=self.app.t("ai_title"), font=("Microsoft YaHei UI", 18, "bold"), fg=self.colors["text"], bg=self.colors["card"])
        self.title.pack(anchor="w")
        self.subtitle = tk.Label(title_box, text=self.app.t("ai_subtitle"), font=("Microsoft YaHei UI", 10), fg=self.colors["text_secondary"], bg=self.colors["card"])
        self.subtitle.pack(anchor="w")

        content = tk.Frame(self.frame, bg=self.colors["bg"])
        content.pack(fill=tk.BOTH, expand=True)

        left = create_card(content, self.colors)
        left.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        right = create_card(content, self.colors)
        right.pack(side=tk.RIGHT, fill=tk.BOTH, padx=(14, 0))
        right.configure(width=360)
        right.pack_propagate(False)

        input_box = tk.Frame(left, bg=self.colors["card"])
        input_box.pack(fill=tk.X, padx=18, pady=(18, 12))
        command_wrap = tk.Frame(input_box, bg=self.colors["bg"], highlightthickness=1, highlightbackground=self.colors["border"])
        command_wrap.pack(side=tk.LEFT, fill=tk.X, expand=True)
        tk.Frame(command_wrap, width=12, bg=self.colors["bg"]).pack(side=tk.LEFT)
        self.command_entry = tk.Entry(command_wrap, relief=tk.FLAT, bd=0, bg=self.colors["bg"], fg=self.colors["text_secondary"], font=("Microsoft YaHei UI", 11))
        self.command_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, ipady=11, pady=1)
        self.command_entry.insert(0, self.app.t("ai_input_placeholder"))
        self.command_entry.bind("<FocusIn>", self._focus_in)
        self.command_entry.bind("<KeyPress>", self._focus_in)
        self.command_entry.bind("<FocusOut>", self._focus_out)
        self.command_entry.bind("<Return>", lambda e: self.run_command())
        self.send_btn = create_button(input_box, self.app.t("ai_send"), self.run_command, self.colors, filled=True)
        self.send_btn.pack(side=tk.LEFT, padx=(10, 0))
        self.voice_btn = create_button(input_box, self.app.t("ai_voice"), self.voice_hint, self.colors)
        self.voice_btn.pack(side=tk.LEFT, padx=(8, 0))

        self.history = scrolledtext.ScrolledText(left, relief=tk.FLAT, bd=0, bg=self.colors["card"], fg=self.colors["text"], font=("Microsoft YaHei UI", 11), wrap=tk.WORD, padx=18, pady=18)
        self.history.pack(fill=tk.BOTH, expand=True, padx=8, pady=(0, 8))
        self._write("AI", self.app.t("ai_subtitle"))

        self.example_title = tk.Label(right, text=self.app.t("ai_examples"), font=("Microsoft YaHei UI", 15, "bold"), fg=self.colors["text"], bg=self.colors["card"])
        self.example_title.pack(anchor="w", padx=18, pady=(18, 10))
        self.examples_frame = tk.Frame(right, bg=self.colors["card"])
        self.examples_frame.pack(fill=tk.BOTH, expand=True, padx=14, pady=(0, 14))
        self._render_examples()

    def _focus_in(self, event=None):
        if self.command_entry.get() == self.app.t("ai_input_placeholder"):
            self.command_entry.delete(0, tk.END)
            self.command_entry.config(fg=self.colors["text"])

    def _focus_out(self, event=None):
        if not self.command_entry.get().strip():
            self.command_entry.insert(0, self.app.t("ai_input_placeholder"))
            self.command_entry.config(fg=self.colors["text_secondary"])

    def _render_examples(self):
        for child in self.examples_frame.winfo_children():
            child.destroy()
        examples = [
            ("明天提醒我开会", "remind me tomorrow for meeting", "ingatkan saya besok meeting"),
            ("下周一添加待办 准备周报", "add task next Monday prepare weekly report", "tambah tugas senin depan siapkan laporan"),
            ("3月7日加备注 拜访客户", "add note on Mar 7 visit client", "catatan 7 Maret kunjungi klien"),
            ("打开日历", "open calendar", "buka kalender"),
            ("打开云盘", "open drive", "buka drive"),
            ("查看印尼假期", "show Indonesia holidays", "lihat libur Indonesia"),
            ("查看中国假期", "show China holidays", "lihat libur China"),
            ("打开企业管理", "open enterprise", "buka perusahaan"),
            ("打开内部聊天", "open chat", "buka chat"),
        ]
        idx = 1 if self.app.lang_code == "en_US" else (2 if self.app.lang_code == "id_ID" else 0)
        for item in examples:
            text = item[idx]
            btn = tk.Button(self.examples_frame, text=text, anchor="w", command=lambda t=text: self._use_example(t), bg=self.colors["card_soft"], fg=self.colors["text"], activebackground=self.colors["primary_light"], activeforeground=self.colors["primary"], relief=tk.FLAT, bd=0, padx=12, pady=10, font=("Microsoft YaHei UI", 10), cursor="hand2")
            btn.pack(fill=tk.X, pady=4)

    def _use_example(self, text):
        self.command_entry.delete(0, tk.END)
        self.command_entry.insert(0, text)
        self.command_entry.config(fg=self.colors["text"])
        self.run_command()

    def _write(self, who, message):
        self.history.insert(tk.END, f"{who}: {message}\n\n")
        self.history.see(tk.END)

    def voice_hint(self):
        messagebox.showinfo(self.app.t("ai_voice"), self.app.t("ai_voice_hint"))
        self._write("AI", self.app.t("ai_voice_hint"))

    def run_command(self):
        cmd = self.command_entry.get().strip()
        if not cmd or cmd == self.app.t("ai_input_placeholder"):
            return
        self._write("You", cmd)
        result = self.handle_command(cmd)
        self._write("AI", result)
        self.command_entry.delete(0, tk.END)
        self._focus_out()

    def _parse_date(self, text):
        low = text.lower()
        today = date.today()
        if any(k in low for k in ["今天", "today", "hari ini"]):
            return today.strftime("%Y-%m-%d")
        if any(k in low for k in ["明天", "tomorrow", "besok"]):
            return (today + timedelta(days=1)).strftime("%Y-%m-%d")
        if any(k in low for k in ["后天", "day after tomorrow", "lusa"]):
            return (today + timedelta(days=2)).strftime("%Y-%m-%d")
        weekdays_zh = {"周一":0, "星期一":0, "下周一":0, "下星期一":0, "周二":1, "星期二":1, "下周二":1, "周三":2, "星期三":2, "下周三":2, "周四":3, "星期四":3, "下周四":3, "周五":4, "星期五":4, "下周五":4, "周六":5, "星期六":5, "下周六":5, "周日":6, "星期日":6, "周天":6, "下周日":6}
        for word, wd in weekdays_zh.items():
            if word in low:
                delta = (wd - today.weekday()) % 7
                if delta == 0 or word.startswith("下"):
                    delta += 7
                return (today + timedelta(days=delta)).strftime("%Y-%m-%d")
        weekdays_en = {"monday":0, "tuesday":1, "wednesday":2, "thursday":3, "friday":4, "saturday":5, "sunday":6}
        for word, wd in weekdays_en.items():
            if word in low:
                delta = (wd - today.weekday()) % 7
                if delta == 0 or "next" in low:
                    delta += 7
                return (today + timedelta(days=delta)).strftime("%Y-%m-%d")
        m = re.search(r"(20\d{2})[-/年.](\d{1,2})[-/月.](\d{1,2})", text)
        if m:
            y, mo, d = map(int, m.groups())
            try:
                return date(y, mo, d).strftime("%Y-%m-%d")
            except Exception:
                pass
        m = re.search(r"(\d{1,2})\s*月\s*(\d{1,2})\s*[日号]?", text)
        if m:
            mo, d = map(int, m.groups())
            y = today.year
            try:
                candidate = date(y, mo, d)
                if candidate < today:
                    candidate = date(y + 1, mo, d)
                return candidate.strftime("%Y-%m-%d")
            except Exception:
                pass
        m = re.search(r"\b(\d{1,2})/(\d{1,2})\b", text)
        if m:
            mo, d = map(int, m.groups())
            y = today.year
            try:
                candidate = date(y, mo, d)
                if candidate < today:
                    candidate = date(y + 1, mo, d)
                return candidate.strftime("%Y-%m-%d")
            except Exception:
                pass
        return today.strftime("%Y-%m-%d")

    def _extract_after_keywords(self, text, keywords):
        low = text.lower()
        best_pos = -1
        best_kw = ""
        for kw in keywords:
            pos = low.find(kw.lower())
            if pos >= 0 and (best_pos < 0 or pos < best_pos):
                best_pos, best_kw = pos, kw
        if best_pos >= 0:
            return text[best_pos + len(best_kw):].strip(" ：:，,.-的")
        return ""

    def _parse_time(self, text):
        m = re.search(r"(\d{1,2})[:点时](\d{1,2})?", text)
        if m:
            h = int(m.group(1))
            mi = int(m.group(2) or 0)
            if 0 <= h <= 23 and 0 <= mi <= 59:
                return f"{h:02d}:{mi:02d}"
        if re.search(r"(上午|morning|pagi)", text, re.I):
            return "09:00"
        if re.search(r"(下午|sore|afternoon)", text, re.I):
            return "14:00"
        if re.search(r"(晚上|malam|evening)", text, re.I):
            return "19:00"
        return datetime.now().strftime("%H:%M")

    def _clean_schedule_text(self, text):
        cleaned = self._clean_action_text(text)
        cleaned = re.sub(r"(日程|提醒|备注|schedule|reminder|note|jadwal|catatan|ingatkan)", "", cleaned, flags=re.I)
        cleaned = re.sub(r"(创建|新建|新增|添加|帮我|请|帮|create|new|add|buat|tambah)", "", cleaned, flags=re.I)
        cleaned = re.sub(r"(上午|下午|晚上|早上|中午|morning|afternoon|evening|pagi|siang|sore|malam)", "", cleaned, flags=re.I)
        cleaned = re.sub(r"(\d{1,2})[:点时](\d{1,2})?", "", cleaned)
        cleaned = re.sub(r"\s+", " ", cleaned).strip(" 的：:，,.- ")
        return cleaned or self.app.t("ai_default_schedule_title")

    def _clean_action_text(self, text):
        text = re.sub(r"(帮我|请|please|tolong|buatkan|给我)", "", text, flags=re.I)
        text = re.sub(r"(今天|明天|后天|today|tomorrow|besok|lusa)", "", text, flags=re.I)
        text = re.sub(r"(20\d{2}[-/年.]\d{1,2}[-/月.]\d{1,2}|\d{1,2}\s*月\s*\d{1,2}\s*[日号]?|\b\d{1,2}/\d{1,2}\b)", "", text)
        return text.strip(" ：:，,.-")

    def handle_command(self, cmd):
        low = cmd.lower().strip()

        # Open modules with loose matching
        module_rules = [
            (["日历", "calendar", "kalender"], "calendar", "tab_calendar"),
            (["文件", "file", "files", "berkas", "文档", "document"], "files", "tab_notepad"),
            (["聊天", "chat", "消息", "pesan"], "chat", "tab_chat"),
            (["云盘", "drive", "cloud"], "cloud", "tab_cloud"),
            (["企业", "enterprise", "perusahaan"], "enterprise", "tab_enterprise"),
            (["设置", "settings", "pengaturan"], "settings", "tab_settings"),
        ]
        if any(k in low for k in ["打开", "进入", "去", "open", "buka", "lihat"]):
            for keys, page, label_key in module_rules:
                if any(k in low for k in keys):
                    if hasattr(self.app, "is_page_available") and not self.app.is_page_available(page):
                        return self.app.t("personal_isolation_guard_desc") if "personal_isolation_guard_desc" in self.app.lang else "This module is not available in the current edition."
                    self.app.switch_page(page)
                    return f"{self.app.t('ai_opened')}: {self.app.t(label_key)}"

        # Create task: flexible keywords anywhere
        task_keys = ["待办", "任务", "todo", "task", "tugas", "kerjaan"]
        if any(k in low for k in task_keys):
            text = self._extract_after_keywords(cmd, ["待办", "任务", "todo", "task", "tugas", "kerjaan"])
            text = self._clean_action_text(text or cmd)
            text = re.sub(r"^(添加|新增|新建|创建|add|new|create|tambah|buat)\s*", "", text, flags=re.I).strip()
            if not text:
                text = cmd
            item = self.app.make_todo_item(text) if hasattr(self.app, "make_todo_item") else {"text": text, "done": False}
            if isinstance(item, dict):
                item.setdefault("scope", self.app.current_data_scope() if hasattr(self.app, "current_data_scope") else "personal")
            self.app.todos.setdefault("items", []).append(item)
            save_todos(self.app.todos)
            self.app.refresh_home()
            self.app.set_status("status_saved")
            return f"{self.app.t('ai_task_added')}: {text}"

        # Create schedule/note/reminder with flexible natural language:
        # examples: 创建7月7日的日程, 7月7日上午10点提醒开会, buat jadwal 7/7 meeting
        note_keys = ["备注", "日程", "提醒", "remind", "reminder", "schedule", "note", "catatan", "jadwal", "ingatkan", "meeting", "会议"]
        if any(k in low for k in note_keys) or re.search(r"(创建|新建|新增|添加).*(\d{1,2}\s*月\s*\d{1,2}|\d{1,2}/\d{1,2})", cmd):
            ds = self._parse_date(cmd)
            tm = self._parse_time(cmd)
            text = self._clean_schedule_text(cmd)
            self.app.notes[ds] = {"time": tm, "text": text}
            save_notes(self.app.notes)
            self.app.refresh_home()
            self.app.set_status("status_saved")
            return f"{self.app.t('ai_note_added')}: {ds} {tm} · {text}"

        if re.search(r"(今天|明天|后天|下周|星期|周\w|today|tomorrow|next|besok|lusa|\d{1,2}\s*月\s*\d{1,2}|\b\d{1,2}/\d{1,2}\b)", cmd, re.I):
            ds = self._parse_date(cmd)
            text = self._clean_action_text(cmd)
            if text:
                self.app.notes[ds] = {"time": datetime.now().strftime("%H:%M"), "text": text}
                save_notes(self.app.notes)
                self.app.refresh_home()
                self.app.set_status("status_saved")
                return f"{self.app.t('ai_note_added')}: {ds} · {text}"

        if any(k in low for k in ["共享文件", "文档", "文件", "document", "file", "dokumen", "berkas"]) and any(k in low for k in ["新建", "创建", "add", "create", "buat", "tambah"]):
            self.app.switch_page("files")
            try:
                (self.app.pages.get("files") or self.app.pages.get("notepad")).new_doc()
            except Exception:
                pass
            return self.app.t("ai_created_document")

        # Company management shortcuts
        if any(k in low for k in ["创建公司", "新建公司", "公司名称", "buat perusahaan", "create company"]):
            name = re.sub(r"(创建公司|新建公司|公司名称|帮我|请|设置|为|buat perusahaan|create company)", "", cmd, flags=re.I).strip(" ：:，,")
            if not name:
                return self.app.t("ai_company_name_needed")
            self.app.enterprise["company_name"] = name
            self.app.enterprise["company_created"] = True
            save_enterprise(self.app.enterprise)
            self.app.switch_page("enterprise")
            self.app.pages["enterprise"].refresh()
            self.app.set_status("company_saved")
            return self.app.t("ai_company_created").format(company=name)

        if any(k in low for k in ["添加员工", "新增员工", "add employee", "tambah karyawan"]):
            if not self.app.enterprise.get("company_created"):
                return self.app.t("company_required_hint")
            text = cmd
            email_match = re.search(r"[\w\.-]+@[\w\.-]+\.\w+", text)
            email = email_match.group(0) if email_match else ""
            name_match = re.search(r"(?:添加员工|新增员工|add employee|tambah karyawan)\s*([^\s，,]+)", text, re.I)
            name = name_match.group(1).strip() if name_match else ""
            pos_match = re.search(r"(?:职位|岗位|position|jabatan)\s*[:：]?\s*([^\s，,]+)", text, re.I)
            dept_match = re.search(r"(?:部门|department|dept|divisi)\s*[:：]?\s*([^\s，,]+)", text, re.I)
            position = pos_match.group(1).strip() if pos_match else self.app.t("employee_position")
            department = dept_match.group(1).strip() if dept_match else self.app.t("employee_department")
            is_admin = any(k in low for k in ["管理员", "admin"])
            if not name:
                return self.app.t("ai_employee_name_needed")
            self.app.enterprise.setdefault("employees", []).append({
                "id": f"emp-{int(time.time()*1000)}",
                "name": name,
                "position": position,
                "department": department,
                "email": email,
                "is_admin": is_admin,
                "status": "active",
            })
            save_enterprise(self.app.enterprise)
            self.app.switch_page("enterprise")
            self.app.pages["enterprise"].refresh()
            self.app.set_status("status_saved")
            return self.app.t("ai_employee_added").format(name=name)

        if any(k in low for k in ["holiday", "holidays", "假期", "节日", "libur"]):
            notices = self.app.get_upcoming_holiday_notifications(days=14)
            if not notices:
                return self.app.t("notification_empty")
            lines = [self.app.t("ai_upcoming_holidays")]
            for n in notices[:8]:
                lines.append(f"- {n['date']} · {n['title']}")
            return "\n".join(lines)

        if any(k in low for k in ["sync", "同步", "sinkron"]):
            self.app.switch_page("enterprise")
            return self.app.t("sync_desc")

        # If the user writes only module name, open it.
        for keys, page, label_key in module_rules:
            if any(k == low or k in low for k in keys):
                self.app.switch_page(page)
                return f"{self.app.t('ai_opened')}: {self.app.t(label_key)}"

        return self.app.t("ai_unknown") + "\n" + self.app.t("ai_help")

    def refresh(self):
        pass

    def update_language(self):
        self.title.config(text=self.app.t("ai_title"))
        self.subtitle.config(text=self.app.t("ai_subtitle"))
        self.send_btn.config(text=self.app.t("ai_send"))
        self.voice_btn.config(text=self.app.t("ai_voice"))
        self.example_title.config(text=self.app.t("ai_examples"))
        if not self.command_entry.get().strip() or self.command_entry.get() in self.app.all_values("ai_input_placeholder"):
            self.command_entry.delete(0, tk.END)
            self.command_entry.insert(0, self.app.t("ai_input_placeholder"))
            self.command_entry.config(fg=self.colors["text_secondary"])
        self._render_examples()
