"""
Setup tab — one-click installation for Claude Code integration.
Includes configuration path management and backup/restore.
"""

import os
import threading
from tkinter import filedialog, messagebox
import customtkinter as ctk
from core.claude_setup import check_status, install_all, install_ssh_script, install_skill, generate_ssh_key
from core.i18n import t


class SetupTab(ctk.CTkFrame):
    def __init__(self, master, store):
        super().__init__(master, fg_color="transparent")
        self.store = store

        # Header
        self.header_label = ctk.CTkLabel(
            self, text=t("claude_integration"),
            font=ctk.CTkFont(size=20, weight="bold")
        )
        self.header_label.pack(padx=20, pady=(20, 5))

        self.desc_label = ctk.CTkLabel(
            self, text=t("claude_desc"),
            text_color="#9ca3af", justify="center"
        )
        self.desc_label.pack(padx=20, pady=(0, 15))

        # Status card
        self.status_frame = ctk.CTkFrame(self)
        self.status_frame.pack(fill="x", padx=20, pady=10)

        self.status_title = ctk.CTkLabel(
            self.status_frame, text=t("status"),
            font=ctk.CTkFont(size=14, weight="bold"), anchor="w"
        )
        self.status_title.pack(fill="x", padx=15, pady=(10, 5))

        self._status_labels: dict[str, ctk.CTkLabel] = {}
        self._status_text_labels: dict[str, ctk.CTkLabel] = {}
        status_items = [
            ("shared_dir", "status_shared_dir"),
            ("servers_json", "status_servers_json"),
            ("ssh_script", "status_ssh_script"),
            ("encryption", "status_encryption"),
            ("skill_installed", "status_skill"),
            ("ssh_key_exists", "status_ssh_key"),
        ]
        for key, i18n_key in status_items:
            row = ctk.CTkFrame(self.status_frame, fg_color="transparent")
            row.pack(fill="x", padx=15, pady=2)
            indicator = ctk.CTkLabel(row, text="\u25cf", width=20, text_color="#6b7280")
            indicator.pack(side="left")
            text_label = ctk.CTkLabel(row, text=t(i18n_key), anchor="w")
            text_label.pack(side="left", fill="x", expand=True)
            self._status_labels[key] = indicator
            self._status_text_labels[key] = (text_label, i18n_key)

        # Buttons
        btn_frame = ctk.CTkFrame(self, fg_color="transparent")
        btn_frame.pack(fill="x", padx=20, pady=15)

        self.install_all_btn = ctk.CTkButton(
            btn_frame, text=t("install_everything"),
            font=ctk.CTkFont(size=14, weight="bold"),
            height=40, fg_color="#22c55e", hover_color="#16a34a",
            command=self._install_all
        )
        self.install_all_btn.pack(fill="x", pady=(0, 10))

        # Individual buttons row
        ind_frame = ctk.CTkFrame(btn_frame, fg_color="transparent")
        ind_frame.pack(fill="x")

        self.ssh_py_btn = ctk.CTkButton(ind_frame, text=t("install_ssh_py"), width=100, fg_color="#6b7280",
                      command=self._install_script)
        self.ssh_py_btn.pack(side="left", padx=(0, 5))
        self.skill_btn = ctk.CTkButton(ind_frame, text=t("install_skill"), width=100, fg_color="#6b7280",
                      command=self._install_skill)
        self.skill_btn.pack(side="left", padx=5)
        self.ssh_key_btn = ctk.CTkButton(ind_frame, text=t("install_ssh_key"), width=100, fg_color="#6b7280",
                      command=self._gen_key)
        self.ssh_key_btn.pack(side="left", padx=5)
        self.refresh_btn = ctk.CTkButton(ind_frame, text=t("refresh"), width=80, fg_color="#3b82f6",
                      command=self._refresh_status)
        self.refresh_btn.pack(side="right")

        # ── Configuration section ─────────────────────
        config_frame = ctk.CTkFrame(self)
        config_frame.pack(fill="x", padx=20, pady=(5, 5))

        self.config_title = ctk.CTkLabel(
            config_frame, text=t("configuration"),
            font=ctk.CTkFont(size=14, weight="bold"), anchor="w"
        )
        self.config_title.pack(fill="x", padx=15, pady=(10, 5))

        # Config path row
        path_row = ctk.CTkFrame(config_frame, fg_color="transparent")
        path_row.pack(fill="x", padx=15, pady=5)

        self.config_label = ctk.CTkLabel(path_row, text=t("config_label"), anchor="w", width=60)
        self.config_label.pack(side="left")
        self._path_label = ctk.CTkLabel(
            path_row, text=store.get_config_path(),
            anchor="w", text_color="#9ca3af",
            font=ctk.CTkFont(family="Consolas", size=11)
        )
        self._path_label.pack(side="left", fill="x", expand=True, padx=(5, 10))
        self.change_path_btn = ctk.CTkButton(
            path_row, text=t("change_path"), width=100, fg_color="#6b7280",
            command=self._change_config_path
        )
        self.change_path_btn.pack(side="right")

        # Backup row
        backup_row = ctk.CTkFrame(config_frame, fg_color="transparent")
        backup_row.pack(fill="x", padx=15, pady=(5, 10))

        self.backup_btn = ctk.CTkButton(
            backup_row, text=t("backup_now"), width=100, fg_color="#3b82f6",
            command=self._backup_now
        )
        self.backup_btn.pack(side="left", padx=(0, 10))

        self._backup_var = ctk.StringVar(value=t("select_backup"))
        backups = store.list_backups()
        values = backups if backups else [t("no_backups")]
        self._backup_menu = ctk.CTkOptionMenu(
            backup_row, variable=self._backup_var,
            values=values, width=250
        )
        self._backup_menu.pack(side="left", padx=(0, 10))

        self.restore_btn = ctk.CTkButton(
            backup_row, text=t("restore"), width=80, fg_color="#ef4444", hover_color="#dc2626",
            command=self._restore_backup
        )
        self.restore_btn.pack(side="left")

        # Log
        self.log = ctk.CTkTextbox(self, height=150, font=ctk.CTkFont(family="Consolas", size=11), state="disabled")
        self.log.pack(fill="both", expand=True, padx=20, pady=(5, 20))

        # Initial status check
        self._refresh_status()

    def _log(self, text: str):
        self.log.configure(state="normal")
        self.log.insert("end", text + "\n")
        self.log.configure(state="disabled")
        self.log.see("end")

    def _refresh_status(self):
        status = check_status()
        for key, label in self._status_labels.items():
            if status.get(key, False):
                label.configure(text="\u25cf", text_color="#22c55e")  # green
            else:
                label.configure(text="\u25cf", text_color="#ef4444")  # red

    def _install_all(self):
        self.install_all_btn.configure(state="disabled", text=t("installing_all"))

        def _do():
            results = install_all()
            for msg in results:
                self.after(0, lambda m=msg: self._log(m))
            self.after(0, self._refresh_status)
            self.after(0, lambda: self._log("\n" + t("install_done")))
            self.after(0, lambda: self.install_all_btn.configure(state="normal", text=t("install_everything")))

        threading.Thread(target=_do, daemon=True).start()

    def _install_script(self):
        msg = install_ssh_script()
        self._log(msg)
        self._refresh_status()

    def _install_skill(self):
        msg = install_skill()
        self._log(msg)
        self._refresh_status()

    def _gen_key(self):
        msg = generate_ssh_key()
        self._log(msg)
        self._refresh_status()

    # ── Configuration methods ─────────────────────────

    def _change_config_path(self):
        path = filedialog.askopenfilename(
            title=t("select_servers_json"),
            filetypes=[("JSON files", "*.json"), ("All files", "*.*")],
            initialdir=os.path.dirname(self.store.get_config_path())
        )
        if path:
            self.store.set_config_path(path)
            self._path_label.configure(text=path)
            self._log(t("config_changed").format(path=path))

    def _backup_now(self):
        try:
            name = self.store.create_backup()
            self._log(t("backup_created").format(name=name))
            self._refresh_backups()
        except Exception as e:
            self._log(t("backup_failed").format(e=e))

    def _restore_backup(self):
        selected = self._backup_var.get()
        if not selected or selected in (t("select_backup"), t("no_backups")):
            self._log(t("no_backup_selected"))
            return
        if not messagebox.askyesno(t("restore_backup_title"), t("restore_confirm").format(name=selected)):
            return
        try:
            self.store.restore_backup(selected)
            self._log(t("restored").format(name=selected))
        except Exception as e:
            self._log(t("restore_failed").format(e=e))

    def _refresh_backups(self):
        backups = self.store.list_backups()
        if backups:
            self._backup_menu.configure(values=backups)
            self._backup_var.set(backups[0])
        else:
            self._backup_menu.configure(values=[t("no_backups")])
            self._backup_var.set(t("no_backups"))
