# Trinity Score: 95.0 (AI-Powered Diagram Generation)
"""
AI Diagram Generation Router (PH-SE-06.01)

텍스트 설명을 AI로 분석하여 자동으로 다이어그램을 생성하는 API 엔드포인트.
"""

from typing import Any, Literal

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field

from AFO.utils.standard_shield import shield
from services.diagram_generator import DiagramGenerator

router = APIRouter(prefix="/ai-diagram", tags=["AI Diagram Generation"])


# ============================================================================
# Request/Response Models
# ============================================================================


class DiagramGenerationRequest(BaseModel):
    """AI 다이어그램 생성 요청 모델."""

    description: str = Field(
        ...,
        description="다이어그램 설명 (자연어)",
        example="사용자 로그인 -> 인증 확인 -> 대시보드 표시 -> 로그아웃",
    )
    diagram_type: Literal["flow", "architecture", "erd", "sequence", "mindmap"] = Field(
        default="flow",
        description="다이어그램 유형",
        example="flow",
    )
    ai_model: Literal["claude", "gpt4", "local"] = Field(
        default="claude",
        description="사용할 AI 모델",
        example="claude",
    )
    title: str | None = Field(
        default=None,
        description="다이어그램 제목 (생략 시 AI가 자동 생성)",
        example="사용자 인증 플로우",
    )
    theme: Literal["dark", "light"] = Field(
        default="dark",
        description="색상 테마",
        example="dark",
    )


class DiagramGenerationResponse(BaseModel):
    """AI 다이어그램 생성 응답 모델."""

    success: bool = Field(..., description="생성 성공 여부")
    message: str = Field(..., description="응답 메시지")
    diagram_id: str | None = Field(None, description="생성된 다이어그램 ID")
    title: str | None = Field(None, description="다이어그램 제목")
    elements_count: int | None = Field(None, description="엘리먼트 개수")
    excalidraw_json: dict[str, Any] | None = Field(None, description="Excalidraw JSON 데이터")
    preview_url: str | None = Field(None, description="미리보기 URL")
    error: str | None = Field(None, description="에러 메시지")


class DiagramTypesResponse(BaseModel):
    """지원 다이어그램 유형 응답."""

    types: list[dict[str, Any]] = Field(
        ...,
        description="지원되는 다이어그램 유형 목록",
    )


# ============================================================================
# API Endpoints
# ============================================================================


@shield(pillar="眞")
@router.post("/generate", response_model=DiagramGenerationResponse)
async def generate_ai_diagram(request: DiagramGenerationRequest) -> DiagramGenerationResponse:
    """AI 기반 다이어그램 자동 생성.

    텍스트 설명을 AI로 분석하여 자동으로 다이어그램을 생성합니다.
    """
    try:
        # 다이어그램 생성기 초기화
        generator = DiagramGenerator()

        # AI 다이어그램 생성
        result = await generator.generate_ai_diagram(
            description=request.description,
            diagram_type=request.diagram_type,
            ai_model=request.ai_model,
        )

        if not result.success:
            return DiagramGenerationResponse(
                success=False,
                message="다이어그램 생성 실패",
                error=result.error or "알 수 없는 오류",
            )

        # 다이어그램 저장 (선택적)
        if result.excalidraw_json:
            # 파일명 생성 (타임스탬프 기반)
            import uuid

            diagram_id = str(uuid.uuid4())[:8]
            filename = f"ai_generated_{request.diagram_type}_{diagram_id}"

            saved_result = generator.save_diagram(result, filename)
            # file_path가 있으면 저장 성공 (diagram_id는 이미 설정됨)
            _ = saved_result.file_path

        # 응답 생성
        return DiagramGenerationResponse(
            success=True,
            message="다이어그램이 성공적으로 생성되었습니다",
            diagram_id=diagram_id if "diagram_id" in locals() else None,
            title=result.excalidraw_json.get("elements", [{}])[0].get("text")
            if result.excalidraw_json
            else request.title,
            elements_count=len(result.elements) if result.elements else 0,
            excalidraw_json=result.excalidraw_json,
            preview_url=f"/api/ai-diagram/preview/{diagram_id}"
            if "diagram_id" in locals()
            else None,
        )

    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"다이어그램 생성 중 오류 발생: {e!s}",
        )


@shield(pillar="眞")
@router.get("/types", response_model=DiagramTypesResponse)
async def get_supported_diagram_types() -> DiagramTypesResponse:
    """지원되는 다이어그램 유형 목록 조회."""
    types = [
        {
            "type": "flow",
            "name": "플로우 차트",
            "description": "프로세스 흐름을 나타내는 다이어그램",
            "examples": ["사용자 로그인 -> 인증 -> 대시보드", "주문 처리 -> 배송 -> 완료"],
        },
        {
            "type": "architecture",
            "name": "아키텍처 다이어그램",
            "description": "시스템 구성 요소와 관계를 나타내는 다이어그램",
            "examples": [
                "웹 서버 -> API 게이트웨이 -> 데이터베이스",
                "프론트엔드 -> 백엔드 -> 캐시",
            ],
        },
        {
            "type": "erd",
            "name": "엔티티 관계 다이어그램",
            "description": "데이터베이스 테이블 관계를 나타내는 다이어그램",
            "examples": ["사용자 - 주문 - 상품", "회사 - 부서 - 직원"],
        },
        {
            "type": "sequence",
            "name": "시퀀스 다이어그램",
            "description": "시간 순서에 따른 객체 간 상호작용",
            "examples": ["사용자 -> 시스템: 로그인", "클라이언트 -> 서버: 요청"],
        },
        {
            "type": "mindmap",
            "name": "마인드맵",
            "description": "중심 아이디어로부터 확장되는 개념도",
            "examples": [
                "프로젝트 관리 (중심) -> 계획, 실행, 모니터링",
                "학습 주제 -> 하위 개념들",
            ],
        },
    ]

    return DiagramTypesResponse(types=types)


@shield(pillar="眞")
@router.get("/preview/{diagram_id}")
async def get_diagram_preview(diagram_id: str) -> dict[str, Any]:
    """생성된 다이어그램 미리보기.

    저장된 Excalidraw 파일을 반환합니다.
    """
    try:
        # 다이어그램 파일 경로
        import os
        from pathlib import Path

        diagram_path = Path("docs/diagrams") / f"ai_generated_*_{diagram_id}.excalidraw"

        # 파일 찾기
        for file_path in Path("docs/diagrams").glob(f"ai_generated_*_{diagram_id}.excalidraw"):
            if file_path.exists():
                import json

                content = file_path.read_text(encoding="utf-8")
                data = json.loads(content)
                return data

        raise HTTPException(status_code=404, detail="다이어그램을 찾을 수 없습니다")

    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"미리보기 생성 중 오류 발생: {e!s}",
        )


@shield(pillar="眞")
@router.post("/validate")
async def validate_diagram_description(request: dict[str, str]) -> dict[str, Any]:
    """다이어그램 설명 유효성 검증.

    AI가 다이어그램을 생성할 수 있는지 미리 확인합니다.
    """
    description = request.get("description", "")
    diagram_type = request.get("diagram_type", "flow")

    if not description.strip():
        return {
            "valid": False,
            "message": "다이어그램 설명이 비어있습니다",
        }

    # 기본 유효성 검사
    word_count = len(description.split())
    if word_count < 3:
        return {
            "valid": False,
            "message": "설명이 너무 짧습니다 (최소 3단어 이상)",
        }

    if word_count > 200:
        return {
            "valid": False,
            "message": "설명이 너무 깁니다 (최대 200단어)",
        }

    # 다이어그램 유형별 검증
    type_checks = {
        "flow": "->" in description,
        "architecture": any(
            word in description.lower() for word in ["server", "database", "api", "client"]
        ),
        "erd": any(word in description.lower() for word in ["table", "entity", "relationship"]),
        "sequence": ":" in description or "->" in description,
        "mindmap": any(word in description.lower() for word in ["중심", "center", "main", "core"]),
    }

    is_type_appropriate = type_checks.get(diagram_type, True)

    return {
        "valid": True,
        "message": "설명이 유효합니다"
        + (
            ""
            if is_type_appropriate
            else f" (하지만 {diagram_type} 유형에 더 적합한 설명이 될 수 있습니다)"
        ),
        "word_count": word_count,
        "suggested_type": diagram_type if is_type_appropriate else "flow",
    }


@shield(pillar="眞")
@router.get("/examples")
async def get_diagram_examples() -> dict[str, list[str]]:
    """각 다이어그램 유형별 예제 설명."""
    return {
        "flow": [
            "사용자 로그인 -> 인증 확인 -> 대시보드 표시 -> 로그아웃",
            "주문 접수 -> 결제 처리 -> 상품 준비 -> 배송 시작 -> 배송 완료",
            "문제 보고 -> 분석 -> 해결 방안 수립 -> 구현 -> 테스트 -> 배포",
        ],
        "architecture": [
            "웹 브라우저 -> API 게이트웨이 -> 마이크로서비스 -> 데이터베이스",
            "프론트엔드 (React) -> 백엔드 (FastAPI) -> 캐시 (Redis) -> 데이터베이스 (PostgreSQL)",
            "사용자 -> 로드밸런서 -> 웹 서버 -> 애플리케이션 서버 -> 데이터베이스",
        ],
        "erd": [
            "사용자 - 주문 - 상품 (사용자가 주문을 하고 상품을 구매)",
            "회사 - 부서 - 직원 (회사가 부서를 가지고 부서가 직원을 가짐)",
            "학교 - 강의 - 학생 (학교가 강의를 제공하고 학생이 수강)",
        ],
        "sequence": [
            "사용자 -> 시스템: 로그인 요청\n시스템 -> 데이터베이스: 사용자 검증\n데이터베이스 -> 시스템: 검증 결과\n시스템 -> 사용자: 로그인 성공",
            "클라이언트 -> 서버: HTTP 요청\n서버 -> 서비스: 비즈니스 로직\n서비스 -> 데이터베이스: 데이터 조회\n데이터베이스 -> 서비스: 결과 반환",
        ],
        "mindmap": [
            "프로젝트 관리 (중심) -> 계획 (예산, 일정, 리소스) -> 실행 (개발, 테스트, 배포) -> 모니터링 (품질, 성과, 피드백)",
            "머신러닝 (중심) -> 지도학습 (분류, 회귀) -> 비지도학습 (군집화, 차원축소) -> 강화학습 (에이전트, 보상)",
            "건강한 삶 (중심) -> 영양 (균형잡힌 식단, 수분 섭취) -> 운동 (유산소, 근력, 유연성) -> 정신건강 (명상, 수면, 사회적 관계)",
        ],
    }
