from __future__ import annotations
from typing import Dict, Callable
import sqlite3
from pathlib import Path

from PySide6.QtCore import Qt
from PySide6.QtGui import QPixmap
from PySide6.QtWidgets import (
    QMainWindow, QWidget, QFrame, QLabel, QPushButton,
    QHBoxLayout, QVBoxLayout, QStackedWidget, QSplitter, QMessageBox
)

from mi100.pages.projects_page import ProjectsPage
from mi100.pages.clients_page import ClientsPage
from mi100.pages.actors_page import VoiceActorsPage
from mi100.repository import Repo
from mi100.ui.studio_settings_dialog import StudioSettingsDialog
from mi100.licensing.license_manager import LicenseManager
from mi100.services.backup_service import BackupService

class MainWindow(QMainWindow):
    def __init__(self, conn: sqlite3.Connection, paths: Dict[str, Path], license_manager: LicenseManager):
        super().__init__()
        self.conn = conn
        self.repo = Repo(conn)
        self.paths = paths
        self.license_manager = license_manager
        self.setMinimumSize(1700, 1000)
        self.backup_service = BackupService(conn, paths)
        self._skip_auto_backup = False
        self._build_ui()
        self.resize(1700, 1000)

    def _build_ui(self) -> None:
        root = QWidget()
        root_layout = QVBoxLayout(root)
        root_layout.setContentsMargins(10, 0, 10, 0)
        root_layout.setSpacing(8)

        root_layout.addWidget(self._build_header())
        root_layout.addWidget(self._build_body(), 1)
        self.setCentralWidget(root)

    def _build_header(self) -> QFrame:
        header = QFrame()
        header.setFixedHeight(70)
        header.setObjectName("Header")
        layout = QHBoxLayout(header)
        layout.setContentsMargins(10, 0, 10, 0)
        layout.setSpacing(12)

        self.header_logo = QLabel()
        self.header_logo.setFixedSize(40, 40)
        self.header_logo.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.header_title = QLabel("Mi100 Studio Manager")
        self.header_title.setStyleSheet("font-size: 12pt; font-weight: 700; color: #374151;")

        layout.addWidget(self.header_logo)
        layout.addWidget(self.header_title)
        layout.addStretch(1)

        settings_btn = QPushButton("Налаштування")
        settings_btn.clicked.connect(self._on_settings_clicked)
        layout.addWidget(settings_btn)

        self._refresh_branding()
        return header
    def _refresh_branding(self) -> None:
        branding = self.repo.get_studio_branding()
        title = branding.get("studio_title") or "Mi100 Studio Manager"
        logo_path = branding.get("studio_logo_path") or ""
        self.header_title.setText(title)
        self.setWindowTitle(title)
        if logo_path:
            pm = QPixmap(logo_path)
            if not pm.isNull():
                self.header_logo.setPixmap(pm.scaled(36, 36, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation))
                return
        self.header_logo.setPixmap(QPixmap())
        self.header_logo.setText("")

    def _build_body(self) -> QSplitter:
        outer = QSplitter(Qt.Horizontal)
        outer.setChildrenCollapsible(False)

        outer.addWidget(self._build_sidebar())

        self.main_split = QSplitter(Qt.Horizontal)
        self.main_split.setChildrenCollapsible(False)
        outer.addWidget(self.main_split)

        self.pages = QStackedWidget()
        self.projects_page = ProjectsPage(self.repo, self.open_right_panel)
        self.clients_page = ClientsPage(self.repo, self.open_right_panel)
        self.actors_page = VoiceActorsPage(self.repo, self.open_right_panel)
        self.pages.addWidget(self.projects_page)
        self.pages.addWidget(self.clients_page)
        self.pages.addWidget(self.actors_page)

        self.pages.setMinimumWidth(680)
        self.main_split.addWidget(self.pages)

        self.right_panel = QFrame()
        self._right_panel_min_width = 820
        self.right_panel.setMinimumWidth(self._right_panel_min_width)
        self.right_panel.setStyleSheet("background:#FFFFFF; border:1px solid #E5E7EA; border-radius:6px;")
        self.right_layout = QVBoxLayout(self.right_panel)
        self.right_layout.setContentsMargins(10, 0, 10, 0)
        self.right_layout.setSpacing(8)

        self.right_title = QLabel("")
        self.right_title.setStyleSheet("font-size: 18pt; font-weight: 700; background:transparent; border:none; padding:0; margin:0;")
        self.right_layout.addWidget(self.right_title)

        self.right_content = QFrame()
        # ВАЖЛИВО: права панель може бути «порожньою» (схованою) при старті/перемиканні вкладок.
        # Тому layout має існувати завжди, інакше close_right_panel() впаде, якщо жодну картку ще не відкривали.
        _rc_lay = QVBoxLayout(self.right_content)
        _rc_lay.setContentsMargins(0, 0, 0, 0)
        _rc_lay.setSpacing(10)
        self.right_layout.addWidget(self.right_content, 1)


        self.main_split.addWidget(self.right_panel)

        outer.setSizes([150, 1510])
        # За замовчуванням права панель має бути порожня/схована,
        # щоб при старті та при перемиканні вкладок не показувались «старі» картки.
        self.main_split.setStretchFactor(0, 1)
        self.main_split.setStretchFactor(1, 0)
        self.close_right_panel()

        return outer

    def _build_sidebar(self) -> QFrame:
        sidebar = QFrame()
        sidebar.setObjectName("Sidebar")
        sidebar.setMinimumWidth(130)
        sidebar.setMaximumWidth(160)

        layout = QVBoxLayout(sidebar)
        layout.setContentsMargins(10, 0, 10, 0)
        layout.setSpacing(8)

        self.nav_buttons = []
        self.nav_buttons.append(self._nav_button("Проєкти", 0))
        self.nav_buttons.append(self._nav_button("Замовники", 1))
        self.nav_buttons.append(self._nav_button("Підрядники", 2))

        for b in self.nav_buttons:
            layout.addWidget(b)
        layout.addStretch(1)

        self._set_active_nav(0)
        return sidebar

    def _nav_button(self, text: str, page_index: int) -> QPushButton:
        btn = QPushButton(text)
        btn.setObjectName("NavButton")
        btn.setProperty("active", False)
        btn.setCursor(Qt.PointingHandCursor)
        btn.clicked.connect(lambda: self._switch_page(page_index))
        return btn

    def _set_active_nav(self, idx: int) -> None:
        for i, b in enumerate(self.nav_buttons):
            b.setProperty("active", i == idx)
            b.style().unpolish(b); b.style().polish(b)


    def _can_replace_right_panel(self) -> bool:
        lay = self.right_content.layout()
        if lay is None or lay.count() == 0:
            return True
        item = lay.itemAt(0)
        w = item.widget() if item is not None else None
        if w is not None and hasattr(w, "can_close_panel"):
            try:
                return bool(w.can_close_panel())
            except Exception:
                return True
        return True

    def _switch_page(self, idx: int) -> None:
        if not self._can_replace_right_panel():
            return
        self.pages.setCurrentIndex(idx)
        self._set_active_nav(idx)
        self.close_right_panel()
        try:
            page = self.pages.widget(idx)
            if page is not None and hasattr(page, "refresh"):
                page.refresh()
        except Exception:
            pass

    def open_right_panel(self, widget: QWidget, title: str = "Деталі") -> None:
        if not self._can_replace_right_panel():
            return
        if self.right_content.layout() is None:
            lay = QVBoxLayout(self.right_content)
            lay.setContentsMargins(0, 0, 0, 0)
            lay.setSpacing(10)

        lay = self.right_content.layout()
        while lay.count():
            item = lay.takeAt(0)
            if item.widget():
                item.widget().deleteLater()

        self.right_title.setText(title or "")
        widget.setWindowFlags(Qt.Widget)
        widget.setParent(self.right_content)
        lay.addWidget(widget)

        self.right_panel.setMaximumWidth(16777215)
        self.right_panel.setMinimumWidth(self._right_panel_min_width)
        self.right_panel.show()
        widget.show()

        # Коли права панель відкрита, обидві частини мають бути видимими.
        total = max(self.main_split.width(), self.width() - 160)
        left = max(820, int(total * 0.50))
        right = max(self._right_panel_min_width, total - left)
        self.main_split.setSizes([left, right])
        self.main_split.setStretchFactor(0, 3)
        self.main_split.setStretchFactor(1, 4)

    def close_right_panel(self) -> None:
        if not self._can_replace_right_panel():
            return
        lay = self.right_content.layout()
        if lay is None:
            lay = QVBoxLayout(self.right_content)
            lay.setContentsMargins(0, 0, 0, 0)
            lay.setSpacing(10)

        while lay.count():
            item = lay.takeAt(0)
            w = item.widget()
            if w is not None:
                w.setParent(None)
                w.deleteLater()

        self.right_title.setText("")
        self.right_panel.hide()
        self.right_panel.setMinimumWidth(0)
        self.right_panel.setMaximumWidth(0)
        self.main_split.setSizes([1, 0])
        self.main_split.setStretchFactor(0, 1)
        self.main_split.setStretchFactor(1, 0)

    def closeEvent(self, event) -> None:
        if self._skip_auto_backup:
            return super().closeEvent(event)
        try:
            self.backup_service.create_auto_backup()
        except Exception:
            # Автобекап не повинен блокувати закриття програми.
            pass
        return super().closeEvent(event)

    def _on_settings_clicked(self, tab_key: str | None = None) -> None:
        dlg = StudioSettingsDialog(self.repo, self.license_manager, self.backup_service, self)
        if tab_key:
            mapping = {"email_templates": "Шаблони листів", "backup": "Резервні копії"}
            target = mapping.get(tab_key, tab_key)
            for i in range(dlg.tabs.count()):
                if dlg.tabs.tabText(i) == target:
                    dlg.tabs.setCurrentIndex(i)
                    break
        if dlg.exec():
            self._refresh_branding()
