from __future__ import annotations

from pathlib import Path

from PySide6.QtCore import Qt
from PySide6.QtGui import QGuiApplication
from PySide6.QtWidgets import (
    QDialog, QVBoxLayout, QLabel, QHBoxLayout, QPushButton, QFileDialog, QTextEdit, QMessageBox
)

from mi100.licensing.license_manager import LicenseManager, LicenseStatus


class ActivationDialog(QDialog):
    def __init__(self, license_manager: LicenseManager, parent=None):
        super().__init__(parent)
        self.license_manager = license_manager
        self.setWindowTitle('Активація програми')
        self.resize(640, 380)
        self._activated = False
        self._build_ui()

    @property
    def activated(self) -> bool:
        return self._activated

    def _build_ui(self) -> None:
        root = QVBoxLayout(self)
        title = QLabel('Активація Mi100 Studio Manager')
        title.setStyleSheet('font-size: 12pt; font-weight: 700;')
        root.addWidget(title)
        info = QLabel('Надішліть код пристрою продавцю програми та завантажте файл license.dat для активації повної ліцензії.')
        info.setWordWrap(True)
        root.addWidget(info)
        code_lbl = QLabel('Код пристрою')
        code_lbl.setStyleSheet('font-weight:700;')
        root.addWidget(code_lbl)
        self.code_box = QTextEdit()
        self.code_box.setReadOnly(True)
        self.code_box.setPlainText(self.license_manager.device_code)
        self.code_box.setMaximumHeight(76)
        root.addWidget(self.code_box)
        path_lbl = QLabel(f'Файл повної ліцензії буде збережено в: {self.license_manager.license_path}')
        path_lbl.setWordWrap(True)
        path_lbl.setTextInteractionFlags(Qt.TextSelectableByMouse | Qt.TextSelectableByKeyboard)
        root.addWidget(path_lbl)
        btns = QHBoxLayout()
        bcopy = QPushButton('Скопіювати код')
        bcopy.clicked.connect(lambda: QGuiApplication.clipboard().setText(self.license_manager.device_code))
        bsave = QPushButton('Зберегти код у файл')
        bsave.clicked.connect(self._save_code)
        bload = QPushButton('Завантажити файл ліцензії')
        bload.setObjectName('Primary')
        bload.clicked.connect(self._load_license)
        btns.addWidget(bcopy)
        btns.addWidget(bsave)
        btns.addStretch(1)
        btns.addWidget(bload)
        root.addLayout(btns)
        close_row = QHBoxLayout()
        close_row.addStretch(1)
        bclose = QPushButton('Закрити')
        bclose.clicked.connect(self.reject)
        close_row.addWidget(bclose)
        root.addLayout(close_row)

    def _save_code(self) -> None:
        path, _ = QFileDialog.getSaveFileName(self, 'Зберегти код пристрою', 'device_code.txt', 'Text (*.txt)')
        if path:
            Path(path).write_text(self.license_manager.device_code, encoding='utf-8')

    def _load_license(self) -> None:
        path, _ = QFileDialog.getOpenFileName(self, 'Оберіть файл ліцензії', '', 'License (*.dat *.json);;All files (*.*)')
        if not path:
            return
        status = self.license_manager.install_full_license_from_file(path)
        if status.valid:
            QMessageBox.information(self, 'Готово', 'Повна ліцензія успішно активована.')
            self._activated = True
            self.accept()
        else:
            QMessageBox.warning(self, 'Помилка', status.message)


class TrialStartDialog(QDialog):
    def __init__(self, license_manager: LicenseManager, status: LicenseStatus, parent=None):
        super().__init__(parent)
        self.license_manager = license_manager
        self.status = status
        self._allow_continue = False
        self.setWindowTitle('Пробна версія програми')
        self.resize(660, 340)
        self._build_ui()

    @property
    def allow_continue(self) -> bool:
        return self._allow_continue

    def _build_ui(self) -> None:
        root = QVBoxLayout(self)
        title = QLabel('Mi100 Studio Manager — Пробна версія')
        title.setStyleSheet('font-size: 12pt; font-weight: 700;')
        root.addWidget(title)

        if self.status.mode == 'expired':
            msg = 'Пробна версія Mi100 Studio Manager завершилась. Щоб продовжити користування програмою, активуйте повну ліцензію.'
        else:
            msg = self.status.message or 'Це пробна версія програми.'
        info = QLabel(msg)
        info.setWordWrap(True)
        style = 'font-size: 11pt;'
        if self.status.warning_level in ('warning', 'critical', 'expired'):
            style += ' color:#9A3412;' if self.status.warning_level == 'warning' else ' color:#991B1B;'
        info.setStyleSheet(style)
        root.addWidget(info)

        details = []
        if self.status.issued_at:
            details.append(f'Перший запуск: {self.status.issued_at}')
        if self.status.expires_at:
            details.append(f'Пробна версія діє до: {self.status.expires_at}')
        if details:
            det = QLabel(' | '.join(details))
            det.setWordWrap(True)
            root.addWidget(det)

        sub = QLabel('Код пристрою: ' + self.license_manager.device_code)
        sub.setTextInteractionFlags(Qt.TextSelectableByMouse | Qt.TextSelectableByKeyboard)
        root.addWidget(sub)
        root.addStretch(1)

        row = QHBoxLayout()
        if self.status.mode == 'trial' and self.status.valid:
            bcontinue = QPushButton('Продовжити')
            bcontinue.setObjectName('Primary')
            bcontinue.clicked.connect(self._continue)
            row.addWidget(bcontinue)
        bbuy = QPushButton('Придбати програму')
        bbuy.clicked.connect(self._activate)
        bact = QPushButton('Активувати ліцензію')
        bact.clicked.connect(self._activate)
        bexit = QPushButton('Вийти')
        bexit.clicked.connect(self.reject)
        row.addStretch(1)
        row.addWidget(bbuy)
        row.addWidget(bact)
        row.addWidget(bexit)
        root.addLayout(row)

    def _continue(self) -> None:
        self._allow_continue = True
        self.accept()

    def _activate(self) -> None:
        dlg = ActivationDialog(self.license_manager, self)
        if dlg.exec() and dlg.activated:
            self._allow_continue = True
            self.accept()
