"""Display utilities for performance mode output."""

import logging
import re
from pathlib import Path
from rich.panel import Panel

from common.render import render_review_panel, _resolve_existing_path



logger = logging.getLogger(__name__)

PERFORMANCE_SECTION_ORDER = [
    ("loop_io", "루프 내부 I/O"),
    ("nested_loop", "중첩 루프"),
    ("object_creation", "객체 재생성"),
    ("pandas_rowwise", "Pandas 행 단위 연산"),
    ("async_issues", "Async 컨텍스트 문제"),
    ("other", "기타 성능 이슈"),
]

def _infer_function_from_line(file_path: str, line: int) -> str:
    """파일과 라인 번호로부터 가장 가까운 함수/클래스명을 추정한다."""
    if not file_path or file_path == "unknown" or not line or line <= 0:
        return "항목"
    try:
        # 공통 렌더 유틸을 통해 실제 존재하는 경로 우선 해석
        resolved = _resolve_existing_path(file_path)
        if resolved:
            p = Path(resolved)
        else:
            p = Path(file_path)
            if not p.exists():
                # relative일 수 있음
                p = (Path.cwd() / file_path).resolve()

        if (not p.exists()) or (not p.is_file()):
            return "항목"

        lines = p.read_text(encoding="utf-8", errors="replace").splitlines()
        if line > len(lines):
            return "항목"

        # 위로 120줄까지 def/class 탐색 (조금 더 여유를 둔다)
        start = max(0, line - 1 - 120)
        for i in range(line - 1, start - 1, -1):
            s = lines[i]
            m = re.match(r"^\s*(?:async\s+)?def\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(", s)
            if m:
                return m.group(1)
            c = re.match(r"^\s*class\s+([A-Za-z_][A-Za-z0-9_]*)\s*[\(:]", s)
            if c:
                return c.group(1)
        return "항목"
    except Exception:
        return "항목"


def _map_performance_section(finding) -> str | None:
    """Map finding to performance section."""
    if not isinstance(finding, dict):
        return None
    
    issues = finding.get("issues", [])
    if not issues:
        return "other"
    
    first_type = issues[0].get("type", "")
    
    if "loop_io" in first_type:
        return "loop_io"
    elif "nested_loop" in first_type:
        return "nested_loop"
    elif "loop_object" in first_type:
        return "object_creation"
    elif "pandas" in first_type:
        return "pandas_rowwise"
    elif "async" in first_type or "sync_io" in first_type:
        return "async_issues"
    else:
        return "other"


def _build_performance_sections(findings: list) -> dict[str, list[tuple[str, str]]]:
    """Build sections from findings."""
    sections = {key: [] for key, _label in PERFORMANCE_SECTION_ORDER}
    
    for f in findings:
        if not isinstance(f, dict):
            continue
        
        section_key = _map_performance_section(f)
        if not section_key:
            continue
        
        file_path = f.get("file", "unknown")
        function = f.get("function", "unknown")
        line = f.get("line", 0)
        message = f.get("message", "")
        suggestion = f.get("suggestion", "")
        score = f.get("score", 0)
        
        if not message:
            continue
        
        file_short = _short_path(file_path)
        # function이 비어있거나 unknown이면 line 기준으로 함수명 추정
        if (not function) or function == "unknown":
            if line and line > 0:
                function = _infer_function_from_line(str(file_path), int(line))

        if function and function != "unknown" and function != "항목":
            location = f"{file_short}:{function}"
            if line and line > 0:
                location += f" (line: {line})"
        elif line and line > 0:
            location = f"{file_short}:항목 (line: {line})"
        else:
            location = file_short
        
        if message:
            lower_msg = message.lower()
            if "severity" in lower_msg and "message:" in lower_msg:
                idx = lower_msg.find("message:")
                if idx != -1:
                    message = message[idx + len("message:") :].strip()

            message = re.sub(r"^\d+\.\s*", "", message)
            message = re.sub(r"\([^)]*loop_[^)]+\)", "", message)
            message = re.sub(r"\([^)]*nested_[^)]+\)", "", message)
            message = re.sub(r"\([^)]*pandas_[^)]+\)", "", message)
            message = re.sub(r"\([^)]*\)", "", message)
            message = re.sub(r":\s*$", "", message)
            message = message.strip()
        
        if not message or message.startswith("#") or message.startswith("###"):
            if f.get("issues"):
                first_issue = f["issues"][0]
                desc = first_issue.get("description", "")
                desc = re.sub(r"\([^)]*\)", "", desc)
                desc = desc.strip()
                if desc:
                    message = desc
                else:
                    message = "성능 병목 가능성 감지"
            else:
                message = "성능 병목 가능성 감지"
        
        risk_line = f"{location} — {message}"
        fix = suggestion if suggestion else "수동 확인 필요"
        
        sections[section_key].append((risk_line, fix))
    
    return sections


def build_performance_panel(result: dict) -> Panel:
    """Build performance review panel."""
    files = result.get("files_analyzed", [])
    if files:
        summary = ", ".join([_short_path(str(p)) for p in files[:3]])
        if len(files) > 3:
            summary += f" ... (+{len(files) - 3})"
        header = f"{summary}"
    else:
        header = "no files"
    
    status = result.get("status", "unknown")
    findings = result.get("findings", [])
    
    suspicious_count = len(result.get("suspicious_regions", []))
    reviewed_count = len(result.get("reviewed_regions", []))
    
    if status == "success":
        notice = f"의심 구간 {suspicious_count}개 발견, {reviewed_count}개 검토 완료"
    else:
        notice = result.get("message") or "분석 결과를 생성하지 못했습니다."
    
    sections = _build_performance_sections(findings) if status == "success" else {k: [] for k, _ in PERFORMANCE_SECTION_ORDER}
    
    return render_review_panel(
        mode="performance",
        file_summary=header,
        section_order=PERFORMANCE_SECTION_ORDER,
        sections=sections,
        title="Performance Review",
        notice=notice,
    )


def _short_path(path: str) -> str:
    """Get short version of file path."""
    if not path:
        return "unknown"
    parts = path.split("/")
    if len(parts) > 3:
        return "/".join(parts[-3:])
    return path
