"""StatusLabel 模块 - 支持富文本和加载动画的状态栏标签."""

from __future__ import annotations

import re
from typing import ClassVar

from PySide2.QtCore import Qt, QTimer
from PySide2.QtWidgets import QLabel, QStatusBar


class StatusLabel(QLabel):
    """支持富文本颜色标记和加载动画的状态栏标签."""

    # 动画帧序列
    LOADING_FRAMES: ClassVar[list[str]] = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]

    def __init__(self, statusbar: QStatusBar | None = None) -> None:
        """初始化状态栏标签.

        Args:
            statusbar: 父状态栏对象（可选）
        """
        super().__init__()

        self._statusbar = statusbar
        self._loading_frame_index = 0
        self._is_loading = False
        self._loading_timer: QTimer | None = None

        # 预编译正则表达式模式（性能优化）
        self._color_patterns: dict[str, re.Pattern] = {
            color: re.compile(rf"<{color}>(.*?)</{color}>", re.DOTALL)
            for color in ["red", "green", "yellow", "blue", "orange"]
        }
        self._style_patterns: dict[str, re.Pattern] = {
            "error": re.compile(r"<error>(.*?)</error>", re.DOTALL),
            "warning": re.compile(r"<warning>(.*?)</warning>", re.DOTALL),
            "success": re.compile(r"<success>(.*?)</success>", re.DOTALL),
        }

    def set_status_text(self, text: str) -> None:
        """设置状态文本，支持颜色标记和自动加载动画.

        Args:
            text: 状态文本（可包含颜色标记）
        """
        # 检查是否需要显示加载动画
        if "正在保存" in text or "正在加载" in text:
            self._start_loading_animation()
        else:
            self._stop_loading_animation()

        # 如果在加载中，在文本前添加动画字符
        display_text = text
        if self._is_loading:
            display_text = f"{self.LOADING_FRAMES[self._loading_frame_index]} {display_text}"

        # 处理颜色标记
        processed_text = self._process_color_tags(display_text)

        # 启用富文本渲染
        self.setTextFormat(Qt.RichText)
        self.setText(processed_text)

    def _process_color_tags(self, text: str) -> str:
        """处理文本中的颜色标记.

        Args:
            text: 原始文本

        Returns
        -------
            处理后的富文本
        """
        # 颜色映射
        color_map = {"red": "#ff4444", "green": "#006633", "yellow": "#ffcc00", "blue": "#4488ff", "orange": "#ff9900"}

        # 替换颜色标签
        for color_name, color_value in color_map.items():
            pattern = self._color_patterns[color_name]
            replacement = f'<span style="color:{color_value};">' + r"\1" + "</span>"
            text = pattern.sub(replacement, text)

        # 替换样式标签
        text = self._style_patterns["error"].sub(r'<span style="color:#ff4444;font-weight:bold;">\1</span>', text)
        text = self._style_patterns["warning"].sub(r'<span style="color:#ff9900;">\1</span>', text)
        return self._style_patterns["success"].sub(r'<span style="color:#006633;">\1</span>', text)

    def _start_loading_animation(self) -> None:
        """启动加载动画."""
        if not self._is_loading:
            self._is_loading = True
            self._loading_frame_index = 0

            self._loading_timer = QTimer()
            self._loading_timer.timeout.connect(self._update_loading_frame)
            self._loading_timer.start(100)  # 每 100ms 更新一帧

    def _update_loading_frame(self) -> None:
        """更新加载动画帧."""
        self._loading_frame_index = (self._loading_frame_index + 1) % len(self.LOADING_FRAMES)

        # 重新获取当前文本并更新
        current_text = self.text()

        # 移除旧的动画字符
        for frame in self.LOADING_FRAMES:
            if current_text.startswith(frame + " "):
                current_text = current_text[len(frame) + 1 :]
                break

        # 添加新的动画字符
        self.setText(f"{self.LOADING_FRAMES[self._loading_frame_index]} {current_text}")

    def _stop_loading_animation(self) -> None:
        """停止加载动画."""
        if self._is_loading:
            if self._loading_timer is not None:
                self._loading_timer.stop()
                self._loading_timer = None

            self._is_loading = False

            # 移除状态文本前的动画字符
            current_text = self.text()
            for frame in self.LOADING_FRAMES:
                if current_text.startswith(frame + " "):
                    current_text = current_text[len(frame) + 1 :]
                    break

            self.setText(current_text)

    def clear_status(self) -> None:
        """清空状态文本并停止动画."""
        self._stop_loading_animation()
        self.clear()
