"""Matched Previewer 模块 - 匹配详情预览组件."""

from __future__ import annotations

import tempfile
from pathlib import Path
from typing import TYPE_CHECKING, Callable

from PySide2.QtCore import QTimer, QUrl
from PySide2.QtGui import QDesktopServices
from PySide2.QtWidgets import (
    QDialog,
    QFileDialog,
    QHBoxLayout,
    QLabel,
    QMessageBox,
    QPushButton,
    QTextEdit,
    QVBoxLayout,
    QWidget,
)

if TYPE_CHECKING:
    from ..models.fileinfo import MatchInfo


from ..models.config import conf


class MatchPreviewDialog(QDialog):
    """匹配详情预览对话框 - 使用 HTML 渲染."""

    def __init__(self, parent: QWidget | None = None) -> None:
        super().__init__(parent=parent)
        self.setWindowTitle("📊 匹配详情")
        self.resize(*conf.WINDOW_SIZE)

        # 设置对话框样式
        self.setStyleSheet("""
            QDialog {
                background-color: #f5f6fa;
            }
        """)

        self._export_callback = None
        self._html_file_path: str | None = None
        self._setup_ui()

    def _setup_ui(self) -> None:
        """设置 UI 布局."""
        layout = QVBoxLayout(self)
        layout.setSpacing(10)
        layout.setContentsMargins(15, 15, 15, 15)

        # 统计信息标签
        self.info_label = QLabel()
        self.info_label.setStyleSheet("""
            QLabel {
                font-size: 12px;
                padding: 15px;
                background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                                          stop:0 #ecf0f1, stop:1 #ffffff);
                border: 2px solid #bdc3c7;
                border-radius: 8px;
                color: #2c3e50;
            }
        """)
        layout.addWidget(self.info_label)

        # HTML 内容显示区域
        self.details_text = QTextEdit()
        self.details_text.setReadOnly(True)
        self.details_text.setHtml("")
        self.details_text.setStyleSheet("""
            QTextEdit {
                font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
                font-size: 12px;
                border: 2px solid #bdc3c7;
                border-radius: 8px;
                padding: 10px;
                background-color: #ffffff;
                color: #2c3e50;
            }
            QTextEdit:hover {
                border: 2px solid #3498db;
            }
        """)
        layout.addWidget(self.details_text)

        # 按钮区域
        button_layout = QHBoxLayout()
        button_layout.setSpacing(10)

        # 在浏览器中打开按钮
        self.browser_btn = QPushButton("🌐 在浏览器中打开")
        self.browser_btn.setStyleSheet(
            """
            QPushButton {
                background-color: #27ae60;
                color: white;
                border: none;
                border-radius: 6px;
                padding: 10px 20px;
                font-size: 13px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #229954;
            }
            QPushButton:pressed {
                background-color: #1e8449;
            }
        """,
        )
        button_layout.addWidget(self.browser_btn)

        # 导出按钮
        self.export_btn = QPushButton("📥 导出为文本")
        self.export_btn.setStyleSheet("""
            QPushButton {
                background-color: #3498db;
                color: white;
                border: none;
                border-radius: 6px;
                padding: 10px 20px;
                font-size: 13px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #2980b9;
            }
            QPushButton:pressed {
                background-color: #21618c;
            }
        """)
        button_layout.addWidget(self.export_btn)

        # 关闭按钮
        close_btn = QPushButton("关闭")
        close_btn.clicked.connect(self.close)
        close_btn.setStyleSheet("""
            QPushButton {
                background-color: #95a5a6;
                color: white;
                border: none;
                border-radius: 6px;
                padding: 10px 20px;
                font-size: 13px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #7f8c8d;
            }
            QPushButton:pressed {
                background-color: #566573;
            }
        """)
        button_layout.addWidget(close_btn)

        # 添加弹性空间,使按钮靠右
        button_layout.addStretch()
        layout.addLayout(button_layout)

    def set_file_info(self, file_path: str, file_size: int, match_count: int, processing_time: float) -> None:
        """设置文件基本信息.

        Args:
            file_path: 文件路径
            file_size: 文件大小
            match_count: 匹配数量
            processing_time: 处理时间
        """
        self._file_path = file_path
        size_str = self._format_file_size(file_size)
        self.info_label.setText(
            f"📄 <b style='font-size: 13px; color: #2c3e50;'>文件:</b>"
            f"<span style='color: #34495e;'>{Path(file_path).name}</span><br>"
            f"📊 <b style='font-size: 13px; color: #2c3e50;'>大小:</b>"
            f"<span style='color: #7f8c8d;'>{size_str}</span><br>"
            f"🎯 <b style='font-size: 13px; color: #2c3e50;'>匹配数:</b>"
            f"<span style='color: #e74c3c; font-weight: bold; font-size: 16px;'>{match_count}</span><br>"
            f"⏱️ <b style='font-size: 13px; color: #2c3e50;'>处理时间:</b>"
            f"<span style='color: #95a5a6;'>{processing_time:.3f}秒</span>",
        )

    def show_matches(
        self,
        file_path: str,
        file_size: int,
        processing_time: float,
        matches: list[MatchInfo],
        export_callback: Callable | None = None,
    ) -> None:
        """显示匹配详情.

        Args:
            file_path: 文件路径
            file_size: 文件大小
            processing_time: 处理时间
            matches: 匹配信息列表
            export_callback: 导出回调函数
        """
        from .html_generator import MatchHTMLGenerator

        self._file_path = file_path
        self._export_callback = export_callback
        self._matches = matches
        self._file_size = file_size
        self._processing_time = processing_time

        # 设置文件信息
        self.set_file_info(file_path, file_size, len(matches), processing_time)

        # 生成并设置 HTML 内容
        html_content = MatchHTMLGenerator.generate_html(Path(file_path).name, matches, file_size, processing_time)
        self._html_content = html_content
        self.set_html_content(html_content)

        # 连接按钮信号
        self.browser_btn.clicked.connect(self._open_in_browser)
        if export_callback:
            self.export_btn.clicked.disconnect()
        self.export_btn.clicked.connect(self._on_export_clicked)

    def _on_export_clicked(self) -> None:
        """处理导出按钮点击."""
        if self._export_callback:
            self._export_callback(self.get_plain_text())
        else:
            # 默认导出行为
            self._export_to_file()

    def _open_in_browser(self) -> None:
        """在系统浏览器中打开 HTML 文件."""
        try:
            # 创建临时 HTML 文件
            with tempfile.NamedTemporaryFile(mode="w", suffix=".html", delete=False, encoding="utf-8") as temp_file:
                temp_file.write(self._html_content)
                temp_file_name = temp_file.name

            self._html_file_path = temp_file_name

            # 使用系统浏览器打开
            url = QUrl.fromLocalFile(temp_file_name)
            success = QDesktopServices.openUrl(url)

            if not success:
                QMessageBox.warning(self, "警告", "无法打开系统浏览器,请手动打开文件:\n" + temp_file_name)
            else:
                # 清理临时文件(延迟删除)
                QTimer.singleShot(5000, self._cleanup_temp_file)  # 5 秒后删除

        except (OSError, RuntimeError, ValueError) as e:
            QMessageBox.critical(self, "错误", f"打开浏览器失败:{e}")

    def _cleanup_temp_file(self) -> None:
        """清理临时 HTML 文件."""
        try:
            if self._html_file_path and Path(self._html_file_path).exists():
                Path(self._html_file_path).unlink()
                self._html_file_path = None
        except OSError:
            pass  # 忽略清理错误

    def _format_file_size(self, size: int) -> str:
        """格式化文件大小显示.

        Args:
            size: 字节数

        Returns
        -------
            格式化后的大小字符串
        """
        if size < 1024:
            return f"{size} B"
        if size < 1024 * 1024:
            return f"{size / 1024:.1f} KB"
        if size < 1024 * 1024 * 1024:
            return f"{size / (1024 * 1024):.1f} MB"
        return f"{size / (1024 * 1024 * 1024):.1f} GB"

    def set_html_content(self, html: str) -> None:
        """设置 HTML 内容.

        Args:
            html: HTML 格式的内容字符串
        """
        self.details_text.setHtml(html)

    def get_plain_text(self) -> str:
        """获取纯文本内容(用于导出).

        Returns
        -------
            纯文本内容
        """
        return self.details_text.toPlainText()

    def _export_to_file(self) -> None:
        """导出到文件."""
        parent_widget = self.parentWidget() or self
        if not parent_widget:
            QMessageBox.warning(self, "警告", "无法导出文件,请检查文件路径是否有效")
            return

        default_name = f"{Path(self._file_path).name}_matches.txt"
        file_path, _ = QFileDialog.getSaveFileName(
            parent_widget,
            "导出匹配详情",
            default_name,
            "文本文件 (*.txt);;所有文件 (*)",
        )

        if file_path:
            try:
                Path(file_path).write_text(self.get_plain_text(), encoding="utf-8")
                QMessageBox.information(parent_widget, "成功", f"已导出到:\n{file_path}")
            except OSError as e:
                QMessageBox.critical(parent_widget, "错误", f"导出失败:{e}")
