"""
Decomposition Template API.
[AC-IDSMETA-21, AC-IDSMETA-22] 拆解模板管理接口，支持文本拆解为结构化数据。
"""

import logging
from typing import Annotated, Any

from fastapi import APIRouter, Depends, Query
from fastapi.responses import JSONResponse
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.database import get_session
from app.core.exceptions import MissingTenantIdException
from app.core.tenant import get_tenant_id
from app.models.entities import (
    DecompositionRequest,
    DecompositionTemplateCreate,
    DecompositionTemplateStatus,
    DecompositionTemplateUpdate,
)
from app.services.decomposition_template_service import DecompositionTemplateService

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/admin/decomposition-templates", tags=["DecompositionTemplates"])


def get_current_tenant_id() -> str:
    """Get current tenant ID from context."""
    tenant_id = get_tenant_id()
    if not tenant_id:
        raise MissingTenantIdException()
    return tenant_id


@router.get(
    "",
    operation_id="listDecompositionTemplates",
    summary="List decomposition templates",
    description="[AC-IDSMETA-22] 获取拆解模板列表，支持按状态过滤",
)
async def list_templates(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    status: Annotated[str | None, Query(
        description="按状态过滤: draft/published/archived"
    )] = None,
) -> JSONResponse:
    """
    [AC-IDSMETA-22] 列出拆解模板
    """
    logger.info(
        f"[AC-IDSMETA-22] Listing decomposition templates: "
        f"tenant={tenant_id}, status={status}"
    )
    
    if status and status not in [s.value for s in DecompositionTemplateStatus]:
        return JSONResponse(
            status_code=400,
            content={
                "code": "INVALID_STATUS",
                "message": f"Invalid status: {status}",
                "details": {
                    "valid_values": [s.value for s in DecompositionTemplateStatus]
                }
            }
        )
    
    service = DecompositionTemplateService(session)
    templates = await service.list_templates(tenant_id, status)
    
    return JSONResponse(
        content={
            "items": [
                {
                    "id": str(t.id),
                    "name": t.name,
                    "description": t.description,
                    "version": t.version,
                    "status": t.status,
                    "template_schema": t.template_schema,
                    "extraction_hints": t.extraction_hints,
                    "example_input": t.example_input,
                    "example_output": t.example_output,
                    "created_at": t.created_at.isoformat(),
                    "updated_at": t.updated_at.isoformat(),
                }
                for t in templates
            ]
        }
    )


@router.post(
    "",
    operation_id="createDecompositionTemplate",
    summary="Create decomposition template",
    description="[AC-IDSMETA-22] 创建新的拆解模板",
    status_code=201,
)
async def create_template(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    template_create: DecompositionTemplateCreate,
) -> JSONResponse:
    """
    [AC-IDSMETA-22] 创建拆解模板
    """
    logger.info(
        f"[AC-IDSMETA-22] Creating decomposition template: "
        f"tenant={tenant_id}, name={template_create.name}"
    )
    
    service = DecompositionTemplateService(session)
    template = await service.create_template(tenant_id, template_create)
    await session.commit()
    
    return JSONResponse(
        status_code=201,
        content={
            "id": str(template.id),
            "name": template.name,
            "description": template.description,
            "version": template.version,
            "status": template.status,
            "template_schema": template.template_schema,
            "extraction_hints": template.extraction_hints,
            "example_input": template.example_input,
            "example_output": template.example_output,
            "created_at": template.created_at.isoformat(),
            "updated_at": template.updated_at.isoformat(),
        }
    )


@router.get(
    "/latest",
    operation_id="getLatestPublishedTemplate",
    summary="Get latest published template",
    description="[AC-IDSMETA-22] 获取最近生效的发布版本模板",
)
async def get_latest_template(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
) -> JSONResponse:
    """
    [AC-IDSMETA-22] 获取最近生效的发布版本模板
    """
    logger.info(
        f"[AC-IDSMETA-22] Getting latest published template: tenant={tenant_id}"
    )
    
    service = DecompositionTemplateService(session)
    template = await service.get_latest_published_template(tenant_id)
    
    if not template:
        return JSONResponse(
            status_code=404,
            content={
                "code": "NOT_FOUND",
                "message": "No published template found",
            }
        )
    
    return JSONResponse(
        content={
            "id": str(template.id),
            "name": template.name,
            "description": template.description,
            "version": template.version,
            "status": template.status,
            "template_schema": template.template_schema,
            "extraction_hints": template.extraction_hints,
            "example_input": template.example_input,
            "example_output": template.example_output,
            "created_at": template.created_at.isoformat(),
            "updated_at": template.updated_at.isoformat(),
        }
    )


@router.put(
    "/{id}",
    operation_id="updateDecompositionTemplate",
    summary="Update decomposition template",
    description="[AC-IDSMETA-22] 更新拆解模板，支持状态切换",
)
async def update_template(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    id: str,
    template_update: DecompositionTemplateUpdate,
) -> JSONResponse:
    """
    [AC-IDSMETA-22] 更新拆解模板
    """
    logger.info(
        f"[AC-IDSMETA-22] Updating decomposition template: "
        f"tenant={tenant_id}, id={id}"
    )
    
    if template_update.status and template_update.status not in [s.value for s in DecompositionTemplateStatus]:
        return JSONResponse(
            status_code=400,
            content={
                "code": "INVALID_STATUS",
                "message": f"Invalid status: {template_update.status}",
                "details": {
                    "valid_values": [s.value for s in DecompositionTemplateStatus]
                }
            }
        )
    
    service = DecompositionTemplateService(session)
    template = await service.update_template(tenant_id, id, template_update)
    
    if not template:
        return JSONResponse(
            status_code=404,
            content={
                "code": "NOT_FOUND",
                "message": f"Template {id} not found",
            }
        )
    
    await session.commit()
    
    return JSONResponse(
        content={
            "id": str(template.id),
            "name": template.name,
            "description": template.description,
            "version": template.version,
            "status": template.status,
            "template_schema": template.template_schema,
            "extraction_hints": template.extraction_hints,
            "example_input": template.example_input,
            "example_output": template.example_output,
            "created_at": template.created_at.isoformat(),
            "updated_at": template.updated_at.isoformat(),
        }
    )


@router.post(
    "/decompose",
    operation_id="decomposeText",
    summary="Decompose text to structured data",
    description="[AC-IDSMETA-21] 将待录入文本拆解为固定模板输出",
)
async def decompose_text(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    request: DecompositionRequest,
) -> JSONResponse:
    """
    [AC-IDSMETA-21] 将待录入文本拆解为固定模板输出
    
    如果不指定 template_id，则使用最近生效的发布版本模板
    """
    logger.info(
        f"[AC-IDSMETA-21] Decomposing text: tenant={tenant_id}, "
        f"template_id={request.template_id}, text_length={len(request.text)}"
    )
    
    from app.services.llm import get_llm_client
    llm_client = get_llm_client()
    
    service = DecompositionTemplateService(session, llm_client)
    result = await service.decompose_text(tenant_id, request)
    
    if not result.success:
        return JSONResponse(
            status_code=400,
            content={
                "code": "DECOMPOSITION_FAILED",
                "message": result.error,
                "details": {
                    "template_id": result.template_id,
                    "template_version": result.template_version,
                    "latency_ms": result.latency_ms,
                }
            }
        )
    
    return JSONResponse(
        content={
            "success": result.success,
            "data": result.data,
            "template_id": result.template_id,
            "template_version": result.template_version,
            "confidence": result.confidence,
            "latency_ms": result.latency_ms,
        }
    )
