"""Extract case number (案件编号) from leaudit OcrResult.

Port of docauditai's ``extract_case_number_for_regex`` adapted for leaudit's
OcrResult model. Uses regex patterns first; falls back to LLM when available.
"""
from __future__ import annotations

import logging
import re
from typing import Any

from leaudit.ocr.models import OcrResult

log = logging.getLogger(__name__)

# Regex patterns for case number extraction
_PATTERNS: list[tuple[str, str]] = [
    # Direct match: "案件编号：梅烟专罚〔2024〕第XX号"
    (r"案件编号[:：]\s*(.*?)(?:\n|$)", "direct"),
    # From 卷宗/卷 宗 header: extract content between 卷宗 and 案由
    (r"卷\s*宗([\s\S]*?)案\s*由", "file_content"),
    # Standalone pattern: e.g. 梅烟专罚〔2024〕第001号
    (r"[\u4e00-\u9fa5]{2,8}[专罚处决][〔（\(\[]\d{4}[〕）\)\]][\u4e00-\u9fa5]*\d+号", "standalone"),
    # Dossier number: e.g. "2024 年度 郁烟 第 71 号"
    (r"\d{4}\s*年度\s*[\u4e00-\u9fa5]{1,6}\s*第\s*\d+\s*号", "dossier"),
]

# Chinese number format within 卷宗 extracted text
_YEAR_NUMBER_RE = re.compile(r"\d{4}[\u4e00-\u9fa5]+\d+号")


def extract_case_number(ocr_result: OcrResult) -> str | None:
    """Extract case number from OCR result using regex patterns.

    Searches across all pages but prioritizes early pages where case numbers
    typically appear (封面, 卷宗封面).

    Args:
        ocr_result: OCR result with pages containing text.

    Returns:
        Extracted case number string, or None if not found.
    """
    # Build text from first few pages (case numbers appear early)
    pages_to_check = ocr_result.pages[:5] if len(ocr_result.pages) > 5 else ocr_result.pages
    text = "\n".join(p.text for p in pages_to_check)

    if not text.strip():
        return None

    for pattern, ptype in _PATTERNS:
        match = re.search(pattern, text)
        if not match:
            continue

        if ptype == "direct":
            return match.group(1).strip()

        if ptype == "file_content":
            content = match.group(1).strip()
            num_match = _YEAR_NUMBER_RE.search(content)
            if num_match:
                return num_match.group()

        if ptype == "standalone":
            return match.group()

        if ptype == "dossier":
            return match.group()

    return None


async def extract_case_number_with_llm(
    ocr_result: OcrResult,
    llm_client: Any = None,
) -> str | None:
    """Extract case number using regex first, then LLM fallback.

    Args:
        ocr_result: OCR result with pages containing text.
        llm_client: Optional LLM client for fallback extraction.

    Returns:
        Extracted case number string, or None if not found.
    """
    # Try regex first (fast, no API call)
    result = extract_case_number(ocr_result)
    if result:
        return result

    # LLM fallback
    if llm_client is None:
        return None

    text = "\n".join(p.text for p in ocr_result.pages[:5])
    if not text.strip():
        return None

    try:
        from leaudit.llm.base import BaseLLMClient, LLMRequest, LLMMessage
        if not isinstance(llm_client, BaseLLMClient):
            return None

        prompt = (
            "请从以下法律文书文本中提取案件编号。"
            "案件编号通常格式如：梅烟专罚〔2024〕第001号。\n"
            "只返回JSON: {\"case_number\": \"案件编号\"}\n\n"
            f"文本:\n{text[:2000]}"
        )
        request = LLMRequest(
            messages=[LLMMessage(role="user", content=prompt)],
            response_format={"type": "json_object"},
            max_tokens=512,
        )
        response = await llm_client.complete(request)

        import json
        parsed = json.loads(response.content)
        case_number = parsed.get("case_number")
        if case_number and case_number != "未找到":
            if re.search(r"[\u4e00-\u9fa5]|[\d()]", case_number):
                return case_number

    except Exception as e:
        log.warning("LLM case number extraction failed: %s", e)

    return None
