"""配置对话框模块."""

from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path
from typing import TYPE_CHECKING

from PySide2.QtCore import QModelIndex, Signal
from PySide2.QtGui import QFont
from PySide2.QtWidgets import QDialog, QFileDialog, QListView, QMessageBox
from typing_extensions import Literal

from pytola_office.filescan.core.config import conf
from pytola_office.filescan.core.logger import logger

from .configdialog_ui import QStringListModel, Ui_ConfigDialog

if TYPE_CHECKING:
    from pytola_office.filescan.gui import FileScanner

from pytola_qtstyles import get_theme_files

ConfigTabName = Literal["styles", "fileTypes", "keywords", "ignoreDirs", "ignoreFileNames"]


@dataclass
class ConfigItem:
    """配置项."""

    name: ConfigTabName
    view: QListView
    model: QStringListModel


class ConfigDialog(QDialog, Ui_ConfigDialog):
    """配置对话框."""

    sig_value_changed = Signal()

    def __init__(self, parent: FileScanner | None = None) -> None:
        super().__init__(parent=parent)

        self.setupUi(self)

        self._parent: FileScanner | None = parent
        self._configs: list[ConfigItem] = [
            ConfigItem("styles", self.lvStyles, QStringListModel(conf.STYLE_NAMES)),
            ConfigItem("fileTypes", self.lvFileTypes, QStringListModel(conf.FILE_TYPES)),
            ConfigItem("keywords", self.lvKeywords, QStringListModel(conf.KEYWORDS)),
            ConfigItem("ignoreDirs", self.lvIgnoreDirs, QStringListModel(conf.IGNORE_DIRS)),
            ConfigItem("ignoreFileNames", self.lvIgnoreFileNames, QStringListModel(conf.IGNORE_FILE_NAMES)),
        ]
        self._load_settings()
        self._load_fonts()
        self._load_styles()

        self.tabWidget.setCurrentIndex(0)
        self.pbOpenDir.setEnabled(False)
        self.pbSave.setEnabled(False)

        self.pbAdd.clicked.connect(self.add)
        self.pbOpenDir.clicked.connect(self.open_directory)
        self.pbSave.clicked.connect(self.save_settings)
        self.tabWidget.currentChanged.connect(self.on_change_tab)
        self.sig_value_changed.connect(self.change_value)
        self.lvStyles.selectionModel().currentRowChanged.connect(self._on_apply_style)

    def save_settings(self) -> None:
        """保存设置."""
        conf.save_to_json()

    def add(self) -> None:
        """添加内容."""
        content = self.leContent.text().strip()
        if not content:
            QMessageBox.warning(self, "警告", "请输入内容!")
            return

        config = self._configs[self.tabWidget.currentIndex()]
        if not config:
            QMessageBox.warning(self, "警告", "请选择要添加的项")
            return

        index = config.view.currentIndex().row()
        current_list = config.model.stringList()
        if index == -1:
            current_list.append(content)
        else:
            current_list.insert(index, content)
        config.model.setStringList(current_list)

        self.leContent.clear()
        self.sig_value_changed.emit()

    def open_directory(self) -> None:
        """选择目录."""
        folder = QFileDialog.getExistingDirectory(self, "选择目录")
        if folder:
            self.leContent.setText(Path(folder).as_posix())

    def on_change_tab(self, index: int) -> None:
        """切换标签页时启用/禁用目录选择按钮."""
        logger.info(f"切换标签页：{index}")

        config = self._configs[self.tabWidget.currentIndex()]
        logger.info(f"当前配置：{config.name}, {config.model.stringList()}")

        if config.name == "ignoreDirs":
            self.pbOpenDir.setEnabled(True)
        else:
            self.pbOpenDir.setEnabled(False)

    def change_value(self) -> None:
        """值改变时启用保存按钮."""
        self.pbSave.setEnabled(True)

    def _load_settings(self) -> None:
        """加载设置."""
        for config in self._configs:
            config.view.setModel(config.model)

    def _load_styles(self) -> None:
        """加载样式."""
        theme_files = get_theme_files()
        style_names = list(theme_files.keys())
        conf.STYLE_NAMES = style_names
        self.lvStyles.setModel(QStringListModel(style_names))

        current_style = conf.DEFAULT_STYLE
        if current_style in style_names:
            index = self.lvStyles.model().index(style_names.index(current_style), 0)
            self.lvStyles.setCurrentIndex(index)
        else:
            logger.warning(f"当前样式 {current_style} 不存在")

    def _load_fonts(self) -> None:
        """加载字体."""
        font = QFont(conf.DEFAULT_FONT, conf.DEFAULT_FONT_SIZE)
        font.setBold(conf.FONT_BOLD)
        self.setFont(font)

        if self._parent:
            self._parent.setFont(font)

    def _on_apply_style(self, current: QModelIndex | None = None, previous: QModelIndex | None = None) -> None:  # noqa: ARG002
        """应用样式."""
        # 获取当前选中的索引
        index = self.lvStyles.currentIndex()
        logger.info(f"当前项：{index.data() if index.isValid() else 'None'}")
        style_name = index.data() if index.isValid() else None
        if not style_name:
            return

        conf.DEFAULT_STYLE = style_name
        if self._parent is not None:
            self._parent.load_style(style_name)
