from __future__ import annotations

import json
import re
import unicodedata
from pathlib import Path
from typing import Any


def strip_accents(text: str) -> str:
    return "".join(
        ch
        for ch in unicodedata.normalize("NFKD", text)
        if not unicodedata.combining(ch)
    )


def slugify(text: str) -> str:
    text = strip_accents(text).replace("đ", "d").replace("Đ", "D").lower()
    text = re.sub(r"[^a-z0-9]+", "-", text)
    return text.strip("-") or "chunk"


def compact_text(text: str) -> str:
    return " ".join(text.split())


def parse_decision_fields(file_name: str) -> tuple[str, str]:
    normalized = file_name.replace(":", "/")
    decision_match = re.search(
        r"(\d{1,3})\s*/\s*QĐ(?:-?KT)?", normalized, flags=re.IGNORECASE
    )
    date_match = re.search(r"(\d{2})/(\d{2})/(\d{4})", normalized)
    decision_no = ""
    issue_date = ""
    if decision_match:
        decision_no = f"{decision_match.group(1)}/{'QĐ-KT' if 'KT' in normalized.upper() else 'QĐ'}"
    if date_match:
        day, month, year = date_match.groups()
        issue_date = f"{year}-{month}-{day}"
    return decision_no, issue_date


def infer_folder_scope(relative_path: str) -> str:
    parts = Path(relative_path).parts
    if len(parts) >= 5:
        return parts[4]
    if len(parts) >= 4:
        return parts[3]
    return ""


def infer_section_title(file_name: str, document_type: str) -> str:
    stem = Path(file_name).stem
    if document_type == "hop_dong":
        return "Hợp đồng thi công Kênh xây"
    if document_type == "nghiem_thu":
        return "Nghiệm thu khối lượng hoàn thành"
    if document_type == "danh_muc_ho_so":
        return "Danh mục hồ sơ công trình Kênh xây"
    return stem


def load_schema(path: Path) -> dict[str, Any]:
    return json.loads(path.read_text(encoding="utf-8"))


def load_manifest(path: Path) -> list[dict[str, Any]]:
    data = json.loads(path.read_text(encoding="utf-8"))
    if not isinstance(data, list):
        raise ValueError("Manifest must be a list of file records")
    return data
