"""File Scanner State Manager - 文件扫描器状态管理器."""

from __future__ import annotations

import typing
from enum import Enum
from typing import TYPE_CHECKING

from pytola_core import StateConfig, StateMachine

from ..models.logger import logger

if TYPE_CHECKING:
    from ..gui import FileScanner


class FileScannerState(str, Enum):
    """文件扫描器状态枚举.

    Attributes
    ----------
        INIT: 初始化状态
        LOADING_DB: 加载数据库中
        COUNTING: 文件计数中
        FINISH_COUNTING: 计数完成
        HAS_ANALYSIS_RESULTS: 已存在分析结果(可重新分析)
        SEARCHING: 搜索中
    """

    INIT = "init"
    LOADING_DB = "loading_db"
    COUNTING = "counting"
    FINISH_COUNTING = "finish_counting"
    HAS_ANALYSIS_RESULTS = "has_analysis_results"
    SEARCHING = "searching"


class FileScannerStateManager:
    """文件扫描器状态管理器 - 简化版状态机封装.

    职责:
    - 管理状态机生命周期
    - 注册状态配置
    - 提供状态转换方法
    - 管理组件启用/禁用状态
    """

    def __init__(self, parent: FileScanner) -> None:
        """初始化状态管理器.

        Args:
            parent: 父对象(FileScanner 实例)
        """
        self._parent = parent
        self._widget_map: dict[str, typing.Any] = {}

        # 初始化状态机并注册状态
        self._state_machine = StateMachine(
            initial_state=FileScannerState.INIT,
            on_state_change=self._on_state_changed_internal,
        )
        self._register_states()
        logger.debug("状态机已初始化并注册所有状态")

    def _register_states(self) -> None:
        """注册所有状态配置到状态机."""
        states_config: dict[FileScannerState, StateConfig] = {
            FileScannerState.INIT: StateConfig(
                enables={"open_button", "config_button", "view_db_button"},
                transitions={
                    "loading_db": FileScannerState.LOADING_DB,
                    "has_results": FileScannerState.HAS_ANALYSIS_RESULTS,
                },
            ),
            FileScannerState.LOADING_DB: StateConfig(
                enables=set(),
                transitions={
                    "db_loaded": FileScannerState.FINISH_COUNTING,
                    "db_not_found": FileScannerState.COUNTING,
                    "has_results": FileScannerState.HAS_ANALYSIS_RESULTS,
                },
            ),
            FileScannerState.COUNTING: StateConfig(
                enables={"stop_button", "config_button"},
                transitions={
                    "finish_counting": FileScannerState.FINISH_COUNTING,
                    "start_searching": FileScannerState.SEARCHING,
                },
            ),
            FileScannerState.FINISH_COUNTING: StateConfig(
                enables={"open_button", "analyse_button", "config_button", "view_db_button"},
                transitions={
                    "start_counting": FileScannerState.COUNTING,
                    "start_searching": FileScannerState.SEARCHING,
                    "has_results": FileScannerState.HAS_ANALYSIS_RESULTS,
                },
            ),
            FileScannerState.HAS_ANALYSIS_RESULTS: StateConfig(
                enables={"open_button", "reanalyse_button", "config_button", "view_db_button"},
                transitions={
                    "start_counting": FileScannerState.COUNTING,
                    "start_searching": FileScannerState.SEARCHING,
                    "no_results": FileScannerState.FINISH_COUNTING,
                },
            ),
            FileScannerState.SEARCHING: StateConfig(
                enables={"stop_button"},
                transitions={"finish_searching": FileScannerState.HAS_ANALYSIS_RESULTS},
            ),
        }

        # 批量注册状态
        self._state_machine.register_states(states_config)  # type: ignore[arg-type]
        logger.debug("状态机已初始化并注册所有状态")

    def _on_state_changed_internal(self, old_state: str, new_state: str) -> None:
        """内部状态变更处理.

        Args:
            old_state: 旧状态
            new_state: 新状态
        """
        logger.debug(f"状态变更:{old_state} -> {new_state}")
        # 自动更新组件的启用/禁用状态
        self._update_widgets_for_state(new_state)

    def set_widget_map(self, widget_map: dict[str, typing.Any]) -> None:
        """设置组件名称到实际组件的映射.

        Args:
            widget_map: 组件映射字典
        """
        self._widget_map = widget_map
        logger.debug(f"组件映射已设置:{list(widget_map.keys())}")

        # 应用初始状态的组件启用/禁用
        self._apply_current_state_widgets()

    def _apply_current_state_widgets(self) -> None:
        """应用当前状态的组件启用/禁用设置."""
        if not self._widget_map:
            return

        state_config = self._state_machine.state_config

        if state_config:
            # 增量更新:只处理启用的组件,其余保持禁用
            enabled_set = set(state_config.enables)

            for widget_name, widget in self._widget_map.items():
                if not hasattr(widget, "setEnabled"):
                    logger.warning(f"组件 '{widget_name}' 没有 setEnabled 方法,将被跳过")
                    continue

                # 根据是否在 enables 集合中设置启用状态
                should_enable = widget_name in enabled_set
                widget.setEnabled(should_enable)

        logger.debug(f"已应用状态 {self._state_machine.current_state} 的组件配置")

    def _update_widgets_for_state(self, state: str) -> None:
        """根据状态更新组件的启用/禁用状态.

        Args:
            state: 状态名称
        """
        if not self._widget_map:
            return

        try:
            # 直接从状态机内部获取状态配置,避免触发回调导致无限循环
            state_config = self._state_machine._states.get(state)

            if state_config:
                # 增量更新:只处理启用的组件,其余保持禁用
                enabled_set = set(state_config.enables)

                for widget_name, widget in self._widget_map.items():
                    if not hasattr(widget, "setEnabled"):
                        continue

                    # 根据是否在 enables 集合中设置启用状态
                    should_enable = widget_name in enabled_set
                    current_enabled = widget.isEnabled()

                    # 只在状态变化时更新,减少不必要的 UI 刷新
                    if should_enable != current_enabled:
                        widget.setEnabled(should_enable)

                logger.debug(f"状态 {state} 的组件已更新 (增量模式)")
        except (ValueError, AttributeError) as e:
            logger.warning(f"更新状态组件失败:{e}")

    def transition(self, event: str) -> bool:
        """执行状态转换.

        Args:
            event: 转换事件名称

        Returns
        -------
            是否转换成功
        """
        success = self._state_machine.transition(event)
        if not success:
            logger.warning(f"状态转换失败:{event}")
        return success

    def force_set_state(self, state: FileScannerState | str) -> None:
        """强制设置状态(不触发转换逻辑).

        Args:
            state: 目标状态
        """
        self._state_machine.force_set_state(state)
        logger.debug(f"强制设置状态:{state}")

    @property
    def current_state(self) -> str:
        """获取当前状态."""
        return self._state_machine.current_state

    @property
    def state_machine(self) -> StateMachine:
        """获取状态机实例."""
        return self._state_machine

    @property
    def is_in_analysis_mode(self) -> bool:
        """检查是否处于已分析结果模式."""
        return self.current_state == FileScannerState.HAS_ANALYSIS_RESULTS

    @property
    def is_searching(self) -> bool:
        """检查是否正在搜索."""
        return self.current_state == FileScannerState.SEARCHING
