"""
API Security mode runner.

Interface 모드와 동일한 에이전트 시스템을 사용하되,
API/인터페이스 관점의 보안 취약점 분석에 특화된 모드이다.
"""

import os
from pathlib import Path

from dotenv import load_dotenv

from common.context import ReviewFinding, ReviewMode, ReviewReport
from api_security.core.orchestrator import ReviewOrchestrator
from common.git_utils import get_staged_files, is_git_repository
from common.render import render_review_panel
from common.ui import console, finish_progress, start_progress, update_status


# API 보안 모드는 일반/보안 모드와 동일한 형식으로 렌더링한다.
API_SECURITY_SECTION_ORDER: list[tuple[str, str]] = [
    ("__file__", ""),
]


def _build_api_security_sections(report: ReviewReport) -> dict[str, list[tuple[str, str]]]:
    """ReviewReport를 파일 기반 섹션으로 변환한다.

    - mode != "interface"이므로 카테고리별 헤더 없이 파일별로만 그룹화된다.
    - render_review_panel의 파서가 이해할 수 있는 "path:symbol — message (anchor: ...)" 형식을 만든다.
    """
    sections: dict[str, list[tuple[str, str]]] = {key: [] for key, _label in API_SECURITY_SECTION_ORDER}

    for f in report.findings:
        # system 메시지는 패널에 섞지 않고, 별도 안내로 사용하도록 제외
        if isinstance(f, ReviewFinding) and f.category == "system":
            continue
        # API 보안 리뷰에서는 문법 오류(syntax_error)는 별도로 표시하지 않는다
        if isinstance(f, ReviewFinding) and f.category == "syntax_error":
            continue

        # 파일 경로
        if isinstance(f, ReviewFinding) and f.file:
            try:
                filename = os.path.relpath(f.file, os.getcwd())
            except ValueError:
                filename = str(f.file)
        else:
            filename = "unknown"

        # 앵커 토큰
        anchors: list[str] = []
        if isinstance(f, ReviewFinding) and isinstance(f.extra, dict):
            raw_anchors = f.extra.get("anchors")
            if isinstance(raw_anchors, list):
                anchors = [str(a).strip() for a in raw_anchors if str(a).strip()][:3]

        # 심볼: 앵커 첫 번째 또는 카테고리/기본값
        if anchors:
            symbol = anchors[0]
        elif isinstance(f, ReviewFinding) and f.category:
            symbol = f.category
        else:
            symbol = "항목"

        # 라인 정보
        location = f"{filename}:{symbol}"
        if isinstance(f, ReviewFinding) and f.line:
            location = f"{location} (line: {f.line})"

        # 메시지/제안
        message = getattr(f, "message", "") or ""
        suggestion = getattr(f, "suggestion", "") or ""
        if not message:
            continue

        # message 끝에 anchor 표기를 추가
        anchor_suffix = ""
        if anchors:
            anchor_suffix = f" (anchor: {', '.join(anchors)})"

        risk_line = f"{location} — {message}{anchor_suffix}"
        sections["__file__"].append((risk_line, suggestion or ""))

    return sections


def run(input_context: dict | None = None) -> int:
    """Execute API security analysis."""
    # .env 파일 로드 (보안/인터페이스 모드와 동일)
    load_dotenv()

    try:
        # Config 로드 (환경변수에서 직접 읽기)
        base_url = os.getenv("GAR_LLM_BASE_URL") or os.getenv("GAR_LLM_ENDPOINT")
        model = os.getenv("GAR_MODEL") or os.getenv("GAR_LLM_MODEL")

        # 파일 목록 결정 (input_context 우선)
        if input_context:
            file_list = input_context.get("selected_paths", [])
            file_list = [Path(p) for p in file_list]
            if not file_list:
                handle = input_context.get("_ui_handle") if input_context else start_progress(
                    "API 보안 분석 모드", total_files=0
                )
                update_status(handle, "결과 파싱/렌더링 중")
                finish_progress(handle)
                panel = render_review_panel(
                    mode="api_security",
                    file_summary="no files",
                    section_order=API_SECURITY_SECTION_ORDER,
                    sections={key: [] for key, _ in API_SECURITY_SECTION_ORDER},
                    title="API Security Review",
                    notice="리뷰 대상 파일이 없습니다.",
                )
                console.print(panel)
                return 1
        else:
            file_list = []
            if is_git_repository():
                staged_files = get_staged_files(python_only=True)
                if staged_files:
                    file_list = staged_files
                else:
                    from interface.cli import _expand_paths

                    file_list, _ = _expand_paths(["."])
            else:
                from interface.cli import _expand_paths

                file_list, _ = _expand_paths(["."])

        if not file_list:
            handle = start_progress("API 보안 분석 모드", total_files=0)
            update_status(handle, "결과 파싱/렌더링 중")
            finish_progress(handle)
            panel = render_review_panel(
                mode="api_security",
                file_summary="no files",
                section_order=API_SECURITY_SECTION_ORDER,
                sections={key: [] for key, _ in API_SECURITY_SECTION_ORDER},
                title="API Security Review",
                notice="리뷰 대상 파일이 없습니다.",
            )
            console.print(panel)
            return 1
        
        # progress handle 초기화 (파일 목록 결정 후)
        handle = input_context.get("_ui_handle") if input_context else start_progress(
            "API 보안 분석 모드", total_files=len(file_list)
        )
        if input_context:
            input_context["_ui_handle"] = handle

        if os.getenv("GAR_DEBUG") == "1":
            console.print(f"[dim]모델: {model or '자동 선택'}[/dim]\n")

        update_status(handle, "LLM 생성 중")
        orchestrator = ReviewOrchestrator(base_url=base_url)
        ctx = orchestrator.build_context(
            mode=ReviewMode.API_SECURITY,
            files=file_list,
            model=model or "default",
            temperature=float(os.getenv("GAR_TEMPERATURE", "0.2")),
            max_output_tokens=int(os.getenv("GAR_MAX_OUTPUT_TOKENS", "2048")),
            language=os.getenv("GAR_LANGUAGE", "Korean"),
            quiet=False,
            input_context=input_context,
        )

        report = orchestrator.run(ctx)

        # 결과 출력 - security/normal 모드와 동일한 파일별 그룹 형식 사용
        update_status(handle, "결과 파싱/렌더링 중")
        sections = _build_api_security_sections(report)

        # 파일 요약: 보고서에 포함된 파일명 기준
        files = [
            str(f.file)
            for f in report.findings
            if isinstance(f, ReviewFinding) and f.file
        ]
        if files:
            # 중복 제거 후 최대 3개까지 표시
            seen: dict[str, None] = {}
            for path in files:
                if path not in seen:
                    seen[path] = None
            unique_files = list(seen.keys())
            summary = ", ".join([Path(p).name for p in unique_files[:3]])
            if len(unique_files) > 3:
                summary += f" ... (+{len(unique_files) - 3})"
            file_summary = summary
        else:
            file_summary = "no files"

        panel = render_review_panel(
            mode="api_security",
            file_summary=file_summary,
            section_order=API_SECURITY_SECTION_ORDER,
            sections=sections,
            title="API Security Review",
        )
        finish_progress(handle)
        console.print(panel)

        # API 보안 모드에서는 정상 완료 시 항상 exit code 0 반환
        return 0

    except KeyboardInterrupt:
        finish_progress(handle)
        console.print("[yellow]API 보안 분석 모드 중단.[/yellow]")
        return 1
    except ValueError as e:
        # base_url이 None인 경우 등 설정 오류
        finish_progress(handle)
        if "base_url" in str(e).lower() or "llm" in str(e).lower():
            console.print("[red]❌ LLM 서버 주소가 설정되지 않았습니다.[/red]")
            console.print("[dim]💡 GAR_LLM_BASE_URL 환경변수를 설정하거나 'gar init'을 실행해주세요.[/dim]")
        else:
            console.print(f"[red]❌ 설정 오류: {e}[/red]")
        return 1
    except Exception as e:
        finish_progress(handle)
        console.print(
            f"\n[bold red]API 보안 분석 모드 실행 중 예상치 못한 오류 발생:[/bold red] [red]{e}[/red]"
        )
        import traceback

        traceback.print_exc()
        return 1

