"""
Metadata Schema API.
动态元数据模式管理接口。
"""

import logging
from typing import Annotated, Any

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

from app.core.database import get_session
from app.models.entities import (
    MetadataField,
    MetadataSchema,
    MetadataSchemaCreate,
    MetadataSchemaUpdate,
)
from app.services.metadata_schema_service import MetadataSchemaService

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/admin/metadata-schemas", tags=["Metadata Schemas"])


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


@router.get(
    "",
    operation_id="listMetadataSchemas",
    summary="List metadata schemas",
    description="获取租户所有元数据模式配置",
)
async def list_schemas(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    include_disabled: bool = False,
) -> JSONResponse:
    """
    列出租户所有元数据模式
    """
    service = MetadataSchemaService(session)
    schemas = await service.list_schemas(tenant_id, include_disabled)
    
    return JSONResponse(
        content={
            "schemas": [
                {
                    "id": str(s.id),
                    "name": s.name,
                    "description": s.description,
                    "fields": s.fields,
                    "isDefault": s.is_default,
                    "isEnabled": s.is_enabled,
                    "createdAt": s.created_at.isoformat(),
                    "updatedAt": s.updated_at.isoformat(),
                }
                for s in schemas
            ]
        }
    )


@router.get(
    "/default",
    operation_id="getDefaultMetadataSchema",
    summary="Get default metadata schema",
    description="获取租户默认的元数据模式配置",
)
async def get_default_schema(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
) -> JSONResponse:
    """
    获取租户默认的元数据模式
    """
    service = MetadataSchemaService(session)
    schema = await service.get_schema(tenant_id)
    
    if not schema:
        return JSONResponse(
            content={
                "schema": None,
                "message": "No default schema configured",
            }
        )
    
    return JSONResponse(
        content={
            "schema": {
                "id": str(schema.id),
                "name": schema.name,
                "description": schema.description,
                "fields": schema.fields,
                "isDefault": schema.is_default,
                "isEnabled": schema.is_enabled,
                "createdAt": schema.created_at.isoformat(),
                "updatedAt": schema.updated_at.isoformat(),
            }
        }
    )


@router.get(
    "/{schema_id}",
    operation_id="getMetadataSchema",
    summary="Get metadata schema by ID",
    description="根据 ID 获取元数据模式配置",
)
async def get_schema(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    schema_id: str,
) -> JSONResponse:
    """
    根据 ID 获取元数据模式
    """
    service = MetadataSchemaService(session)
    schema = await service.get_schema(tenant_id, schema_id)
    
    if not schema:
        raise HTTPException(status_code=404, detail="Schema not found")
    
    return JSONResponse(
        content={
            "schema": {
                "id": str(schema.id),
                "name": schema.name,
                "description": schema.description,
                "fields": schema.fields,
                "isDefault": schema.is_default,
                "isEnabled": schema.is_enabled,
                "createdAt": schema.created_at.isoformat(),
                "updatedAt": schema.updated_at.isoformat(),
            }
        }
    )


@router.post(
    "",
    operation_id="createMetadataSchema",
    summary="Create metadata schema",
    description="创建新的元数据模式配置",
)
async def create_schema(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    schema_create: MetadataSchemaCreate,
) -> JSONResponse:
    """
    创建元数据模式
    """
    service = MetadataSchemaService(session)
    
    for field in schema_create.fields:
        if isinstance(field, MetadataField):
            field_dict = field.model_dump()
        else:
            field_dict = field
        
        field_type = field_dict.get("field_type", "string")
        if field_type in ["select", "multi_select"]:
            if not field_dict.get("options"):
                raise HTTPException(
                    status_code=400,
                    detail=f"Field '{field_dict.get('name')}' is {field_type} type but has no options"
                )
    
    schema = await service.create_schema(tenant_id, schema_create)
    await session.commit()
    
    return JSONResponse(
        status_code=201,
        content={
            "id": str(schema.id),
            "name": schema.name,
            "description": schema.description,
            "fields": schema.fields,
            "isDefault": schema.is_default,
            "isEnabled": schema.is_enabled,
        }
    )


@router.put(
    "/{schema_id}",
    operation_id="updateMetadataSchema",
    summary="Update metadata schema",
    description="更新元数据模式配置",
)
async def update_schema(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    schema_id: str,
    schema_update: MetadataSchemaUpdate,
) -> JSONResponse:
    """
    更新元数据模式
    """
    service = MetadataSchemaService(session)
    schema = await service.update_schema(tenant_id, schema_id, schema_update)
    
    if not schema:
        raise HTTPException(status_code=404, detail="Schema not found")
    
    await session.commit()
    
    return JSONResponse(
        content={
            "id": str(schema.id),
            "name": schema.name,
            "description": schema.description,
            "fields": schema.fields,
            "isDefault": schema.is_default,
            "isEnabled": schema.is_enabled,
        }
    )


@router.delete(
    "/{schema_id}",
    operation_id="deleteMetadataSchema",
    summary="Delete metadata schema",
    description="删除元数据模式配置",
)
async def delete_schema(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    schema_id: str,
) -> JSONResponse:
    """
    删除元数据模式
    """
    service = MetadataSchemaService(session)
    success = await service.delete_schema(tenant_id, schema_id)
    
    if not success:
        raise HTTPException(
        status_code=400,
        detail="Cannot delete schema (not found or is default)"
    )
    
    await session.commit()
    
    return JSONResponse(
        content={
            "success": True,
            "message": "Schema deleted"
        }
    )


@router.get(
    "/default/field-definitions",
    operation_id="getFieldDefinitions",
    summary="Get field definitions",
    description="获取字段定义映射，用于前端动态渲染表单",
)
async def get_field_definitions(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    schema_id: str | None = None,
) -> JSONResponse:
    """
    获取字段定义映射
    """
    service = MetadataSchemaService(session)
    field_defs = await service.get_field_definitions(tenant_id, schema_id)
    
    return JSONResponse(
        content={
            "fieldDefinitions": field_defs
        }
    )


@router.post(
    "/default/validate",
    operation_id="validateMetadata",
    summary="Validate metadata",
    description="验证元数据是否符合模式定义",
)
async def validate_metadata(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    metadata: dict[str, Any],
    schema_id: str | None = None,
) -> JSONResponse:
    """
    验证元数据
    """
    service = MetadataSchemaService(session)
    is_valid, errors = await service.validate_metadata(tenant_id, metadata, schema_id)
    
    return JSONResponse(
        content={
            "isValid": is_valid,
            "errors": errors
        }
    )
