import os
import threading
import tkinter as tk

from core.config import ConfigManager, Profile
from core.robocopy_engine import RobocopySyncEngine
from core.sync_engine import SyncEngine
from ui import styles
from ui.path_panel import PathPanel
from ui.profile_bar import ProfileBar
from ui.status_bar import StatusBar
from ui.summary_panel import SummaryPanel
from ui.system_list import SystemList


class PocketSyncApp:
    def __init__(self, root: tk.Tk, config_manager: ConfigManager):
        self.root = root
        self.cm = config_manager
        self.engine: SyncEngine = RobocopySyncEngine()

        self._build_ui()
        self._load_profile(self.cm.active_profile)

    # ------------------------------------------------------------------
    #   Construcción de la UI
    # ------------------------------------------------------------------

    def _build_ui(self) -> None:
        self.root.title("PocketSync (© 2026 JailDesigner)")
        self.root.geometry(f"{styles.WINDOW_WIDTH}x{styles.WINDOW_HEIGHT}")
        self.root.configure(bg=styles.APP_BG)

        # --- Barra de perfiles ---
        self.profile_bar = ProfileBar(self.root, on_change=self._on_profile_change)
        self.profile_bar.pack(fill="x", padx=styles.PAD_X, pady=(8, 2))
        self.profile_bar.set_callbacks(
            on_new=self._on_new_profile,
            on_rename=self._on_rename_profile,
            on_delete=self._on_delete_profile,
        )
        self._refresh_profile_bar()

        # --- Rutas de origen ---
        self.src_panel = PathPanel(self.root, title="Rutas de origen")
        self.src_panel.pack(fill="x", padx=styles.PAD_X, pady=styles.PAD_Y)
        self.src_panel.set_roms_callback(self._on_roms_src_change)

        # --- Lista de sistemas ---
        self.system_list = SystemList(self.root)
        self.system_list.pack(fill="both", expand=True, padx=styles.PAD_X)

        # --- Rutas de destino ---
        self.dst_panel = PathPanel(self.root, title="Rutas de destino")
        self.dst_panel.pack(fill="x", padx=styles.PAD_X, pady=styles.PAD_Y)

        # --- Botón Sync ---
        tk.Button(
            self.root,
            text="Sincronizar",
            font=styles.FONT_BUTTON,
            command=self._run_sync,
        ).pack(pady=6)

        # --- Barra de estado ---
        self.status_bar = StatusBar(self.root)
        self.status_bar.pack(fill="x", padx=styles.PAD_X, pady=styles.PAD_Y)

        # --- Panel de resumen ---
        self.summary = SummaryPanel(self.root)
        self.summary.pack(fill="both", expand=True, padx=styles.PAD_X, pady=styles.PAD_Y)

        self.root.protocol("WM_DELETE_WINDOW", self._on_close)

    # ------------------------------------------------------------------
    #   Gestión de perfiles
    # ------------------------------------------------------------------

    def _refresh_profile_bar(self) -> None:
        self.profile_bar.refresh(self.cm.profile_names(), self.cm.active_profile_name)

    def _collect_ui_into_profile(self) -> None:
        """Escribe el estado actual de la UI en el perfil activo."""
        p = self.cm.active_profile
        p.esde_src = self.src_panel.get_esde()
        p.roms_src = self.src_panel.get_roms()
        p.esde_dst = self.dst_panel.get_esde()
        p.roms_dst = self.dst_panel.get_roms()
        p.selected = self.system_list.get_selected()

    def _load_profile(self, profile: Profile) -> None:
        self.src_panel.set_esde(profile.esde_src)
        self.src_panel.set_roms(profile.roms_src)
        self.dst_panel.set_esde(profile.esde_dst)
        self.dst_panel.set_roms(profile.roms_dst)

        if os.path.isdir(profile.roms_src):
            self.system_list.populate(profile.roms_src)
        else:
            self.system_list.populate("")

        self.system_list.set_selected(profile.selected)

    def _on_profile_change(self, name: str) -> None:
        self._collect_ui_into_profile()
        self.cm.active_profile_name = name
        self._load_profile(self.cm.active_profile)
        self._refresh_profile_bar()

    def _on_new_profile(self, name: str) -> bool:
        if self.cm.get_profile(name) is not None:
            return False
        self._collect_ui_into_profile()
        self.cm.add_profile(name)
        self.cm.active_profile_name = name
        self._load_profile(self.cm.active_profile)
        self._refresh_profile_bar()
        return True

    def _on_rename_profile(self, old: str, new: str) -> bool:
        ok = self.cm.rename_profile(old, new)
        if ok:
            self._refresh_profile_bar()
        return ok

    def _on_delete_profile(self, name: str) -> bool:
        ok = self.cm.delete_profile(name)
        if ok:
            self._load_profile(self.cm.active_profile)
            self._refresh_profile_bar()
        return ok

    # ------------------------------------------------------------------
    #   Callbacks de widgets
    # ------------------------------------------------------------------

    def _on_roms_src_change(self, path: str) -> None:
        self.system_list.populate(path)

    # ------------------------------------------------------------------
    #   Loop de sincronización
    # ------------------------------------------------------------------

    def _run_sync(self) -> None:
        thread = threading.Thread(target=self._sync_thread)
        thread.daemon = True
        thread.start()

    def _sync_thread(self) -> None:
        selected = self.system_list.get_selected()

        if not selected:
            self.summary.append("No hay sistemas seleccionados.")
            return

        esde_src = self.src_panel.get_esde()
        roms_src = self.src_panel.get_roms()
        esde_dst = self.dst_panel.get_esde()
        roms_dst = self.dst_panel.get_roms()

        if not all([esde_src, roms_src, esde_dst, roms_dst]):
            self.summary.append("ERROR: Debes configurar todas las rutas antes de continuar.")
            return

        self.summary.clear()
        self.summary.append("=" * 60)
        self.summary.append("INICIANDO PROCESO DE COPIA")
        self.summary.append(f"Total de sistemas a procesar: {len(selected)}")
        self.summary.append("=" * 60)

        total = len(selected)

        for idx, system in enumerate(selected, 1):
            self.status_bar.set_system(f"Sistema: {idx}/{total} - {system.upper()}")
            self.summary.append(f"\nSISTEMA [{idx}/{total}]: {system.upper()}")

            # Fase 1: ROMs
            self.status_bar.set_phase("Fase: [1/3] Copiando ROMs...")
            self.summary.append("  [1/3] Copiando ROMs...")
            self.engine.sync_folder(
                os.path.join(roms_src, system),
                os.path.join(roms_dst, system),
                on_file=self.status_bar.set_file,
                on_summary=self.summary.append,
            )

            # Fase 2: gamelists
            self.status_bar.set_phase("Fase: [2/3] Copiando gamelists...")
            self.summary.append("  [2/3] Copiando gamelists...")
            self.engine.sync_folder(
                os.path.join(esde_src, "gamelists", system),
                os.path.join(esde_dst, "gamelists", system),
                on_file=self.status_bar.set_file,
                on_summary=self.summary.append,
            )

            # Fase 3: media
            self.status_bar.set_phase("Fase: [3/3] Copiando media...")
            self.summary.append("  [3/3] Copiando media...")
            self.engine.sync_folder(
                os.path.join(esde_src, "downloaded_media", system),
                os.path.join(esde_dst, "downloaded_media", system),
                on_file=self.status_bar.set_file,
                on_summary=self.summary.append,
            )

            self.summary.append(f"  Sistema '{system}' completado\n")

        self.status_bar.reset()
        self.summary.append("=" * 60)
        self.summary.append("PROCESO COMPLETADO EXITOSAMENTE")
        self.summary.append("=" * 60)

    # ------------------------------------------------------------------
    #   Cierre
    # ------------------------------------------------------------------

    def _on_close(self) -> None:
        self._collect_ui_into_profile()
        self.cm.save()
        self.root.destroy()
