"""Scan module for models."""

from __future__ import annotations

from dataclasses import dataclass, field
from functools import cached_property
from pathlib import Path
from typing import Any, Literal

AnalyseStatusChoices = Literal["pending", "analysing", "completed", "error"]


@dataclass
class FileInfo:
    """表示目录中的单个文件信息."""

    id: int = 0  # 数据库 ID，插入时为 0
    root_path: str = ""
    file_path: str = ""
    file_type: str = ""
    file_size: int = 0
    creation_time: str | None = None
    modification_time: str | None = None
    is_skipped: int = 0  # 是否跳过 (0=否，1=是)
    skip_reason: str | None = None
    scan_status: str = "pending"  # pending, scanning, completed, error
    metadata: str = "{}"  # JSON 字符串

    # 分析结果
    file_level: int = 0
    filename_multi_level: int = 0
    file_content_level: int = 0
    matches: list[int] = field(default_factory=list)

    # 分析状态和性能指标
    processing_time_seconds: float = 0.0  # 处理耗时（秒）
    match_count: int = 0  # 匹配数量
    analyse_status: AnalyseStatusChoices = "pending"  # pending, analysing, completed, error

    @cached_property
    def full_path(self) -> Path:
        """获取文件的完整路径."""
        return Path(self.file_path)

    @cached_property
    def extension(self) -> str:
        """获取文件的扩展名."""
        return self.full_path.suffix.lower()

    @classmethod
    def columns(cls) -> list[str]:
        """获取数据表的列名列表."""
        return [
            "root_path",
            "file_path",
            "file_type",
            "file_size",
            "creation_time",
            "modification_time",
            "is_skipped",
            "skip_reason",
            "scan_status",
            "metadata",
            "file_level",
            "filename_multi_level",
            "file_content_level",
            "matches",
            "processing_time_seconds",
            "match_count",
            "analyse_status",
        ]

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> FileInfo:
        """从字典创建 DirFileInfo 实例."""
        return cls(
            id=data.get("id", 0),
            root_path=data.get("root_path", ""),
            file_path=data.get("file_path", ""),
            file_type=data.get("file_type", ""),
            file_size=data.get("file_size", 0),
            creation_time=data.get("creation_time"),
            modification_time=data.get("modification_time"),
            is_skipped=data.get("is_skipped", 0),
            skip_reason=data.get("skip_reason"),
            scan_status=data.get("scan_status", "pending"),
            metadata=data.get("metadata", "{}"),
            file_level=data.get("file_level", 0),
            filename_multi_level=data.get("filename_multi_level", 0),
            file_content_level=data.get("file_content_level", 0),
            matches=data.get("matches", []),
            processing_time_seconds=data.get("processing_time_seconds", 0.0),
            match_count=data.get("match_count", 0),
            analyse_status=data.get("analyse_status", "pending"),
        )


@dataclass
class MatchInfo:
    """表示单个文件匹配项."""

    id: int = 0
    file_id: int = 0  # 关联的 FileInfo ID
    rule_name: str = ""
    rule_description: str = ""
    match_type: str = "regex"  # "regex", "text", "filename", "zipfile"
    analysis_type: str = "content"  # "filename", "content", "zipfile"
    line_number: int = 0
    match_text: str = ""
    start_pos: int = -1
    end_pos: int = -1
    context_lines: list[str] = field(default_factory=list)
    is_skipped: int = 0
    skip_reason: str = ""
    metadata: str = "{}"  # JSON 字符串，用于存储额外信息（如压缩包内文件列表）

    @classmethod
    def columns(cls) -> list[str]:
        """获取数据表的列名列表."""
        return [
            "file_id",
            "rule_name",
            "rule_description",
            "match_type",
            "analysis_type",
            "line_number",
            "match_text",
            "start_pos",
            "end_pos",
            "context_lines",
            "is_skipped",
            "skip_reason",
            "metadata",
        ]

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> MatchInfo:
        """从字典创建 MatchInfo 实例."""
        import json

        return cls(
            id=data.get("id", 0),
            file_id=data.get("file_id", 0),
            rule_name=data.get("rule_name", ""),
            rule_description=data.get("rule_description", ""),
            match_type=data.get("match_type", "regex"),
            analysis_type=data.get("analysis_type", "content"),
            line_number=data.get("line_number", 0),
            match_text=data.get("match_text", ""),
            start_pos=data.get("start_pos", -1),
            end_pos=data.get("end_pos", -1),
            context_lines=data.get("context_lines", []),
            is_skipped=data.get("is_skipped", 0),
            skip_reason=data.get("skip_reason", ""),
            metadata=data.get("metadata", "{}")
            if isinstance(data.get("metadata"), str)
            else json.dumps(data.get("metadata", {})),
        )


@dataclass
class AnalyseResult:
    """表示单个文件的分析结果."""

    fileinfo: FileInfo  # 文件信息
    matches: list[MatchInfo] = field(default_factory=list)  # 匹配结果列表
    processing_time_seconds: float = 0.0  # 处理耗时（秒）
    status: str = "pending"  # pending, analysing, completed, error
    error_message: str = ""  # 错误消息（如果有）
