"""
Metadata Field Definition API.
[AC-IDSMETA-13, AC-IDSMETA-14] 元数据字段定义管理接口，支持字段级状态治理。
[AC-MRS-01,04,05,06,16] 支持字段角色分层配置和按角色查询。
"""

import logging
from typing import Annotated, Any

from fastapi import APIRouter, Depends, HTTPException, 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 (
    MetadataFieldDefinition,
    MetadataFieldDefinitionCreate,
    MetadataFieldDefinitionUpdate,
    MetadataFieldStatus,
)
from app.services.metadata_field_definition_service import MetadataFieldDefinitionService
from app.services.mid.role_based_field_provider import RoleBasedFieldProvider, InvalidRoleError
from app.schemas.metadata import VALID_FIELD_ROLES

logger = logging.getLogger(__name__)

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


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


def _field_to_dict(f: MetadataFieldDefinition) -> dict[str, Any]:
    """Convert field definition to dict with field_roles"""
    return {
        "id": str(f.id),
        "tenant_id": str(f.tenant_id),
        "field_key": f.field_key,
        "label": f.label,
        "type": f.type,
        "required": f.required,
        "options": f.options,
        "default_value": f.default_value,
        "scope": f.scope,
        "is_filterable": f.is_filterable,
        "is_rank_feature": f.is_rank_feature,
        "usage_description": f.usage_description,
        "field_roles": f.field_roles or [],
        "status": f.status,
        "version": f.version,
        "created_at": f.created_at.isoformat() if f.created_at else None,
        "updated_at": f.updated_at.isoformat() if f.updated_at else None,
    }


@router.get(
    "",
    operation_id="listMetadataSchemas",
    summary="List metadata schemas",
    description="[AC-IDSMETA-13] [AC-MRS-06] 获取元数据字段定义列表，支持按状态、范围、角色过滤",
)
async def list_schemas(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    status: Annotated[str | None, Query(
        description="按状态过滤: draft/active/deprecated"
    )] = None,
    scope: Annotated[str | None, Query(
        description="按适用范围过滤: kb_document/intent_rule/script_flow/prompt_template"
    )] = None,
    field_role: Annotated[str | None, Query(
        description="[AC-MRS-06] 按字段角色过滤: resource_filter/slot/prompt_var/routing_signal"
    )] = None,
    include_deprecated: Annotated[bool, Query(
        description="是否包含已废弃的字段"
    )] = False,
) -> JSONResponse:
    """
    [AC-IDSMETA-13] [AC-MRS-06] 列出元数据字段定义
    
    Args:
        status: 按状态过滤
        scope: 按适用范围过滤
        field_role: [AC-MRS-06] 按字段角色过滤
        include_deprecated: 是否包含已废弃的字段（当 status 未指定时生效）
    """
    logger.info(
        f"[AC-IDSMETA-13] [AC-MRS-06] Listing metadata field definitions: "
        f"tenant={tenant_id}, status={status}, scope={scope}, field_role={field_role}"
    )
    
    if status and status not in [s.value for s in MetadataFieldStatus]:
        return JSONResponse(
            status_code=400,
            content={
                "error_code": "INVALID_STATUS",
                "message": f"Invalid status: {status}",
                "details": {
                    "valid_values": [s.value for s in MetadataFieldStatus]
                }
            }
        )
    
    if field_role and field_role not in VALID_FIELD_ROLES:
        return JSONResponse(
            status_code=400,
            content={
                "error_code": "INVALID_ROLE",
                "message": f"Invalid role '{field_role}'. Valid roles are: {', '.join(VALID_FIELD_ROLES)}",
                "details": {
                    "valid_roles": VALID_FIELD_ROLES
                }
            }
        )
    
    service = MetadataFieldDefinitionService(session)
    
    if include_deprecated and not status:
        fields = await service.get_field_definitions_for_read(tenant_id, scope)
        if field_role:
            fields = [f for f in fields if field_role in (f.field_roles or [])]
    else:
        fields = await service.list_field_definitions(tenant_id, status, scope, field_role)
    
    return JSONResponse(
        content=[_field_to_dict(f) for f in fields]
    )


@router.post(
    "",
    operation_id="createMetadataSchema",
    summary="Create metadata schema",
    description="[AC-IDSMETA-13] [AC-MRS-01,02,03] 创建新的元数据字段定义，支持 field_roles 多选配置",
    status_code=201,
)
async def create_schema(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    field_create: MetadataFieldDefinitionCreate,
) -> JSONResponse:
    """
    [AC-IDSMETA-13] [AC-MRS-01,02,03] 创建元数据字段定义
    """
    logger.info(
        f"[AC-IDSMETA-13] [AC-MRS-01] Creating metadata field definition: "
        f"tenant={tenant_id}, field_key={field_create.field_key}, field_roles={field_create.field_roles}"
    )
    
    service = MetadataFieldDefinitionService(session)
    
    try:
        field = await service.create_field_definition(tenant_id, field_create)
        await session.commit()
    except ValueError as e:
        return JSONResponse(
            status_code=400,
            content={
                "error_code": "VALIDATION_ERROR",
                "message": str(e),
            }
        )
    
    return JSONResponse(
        status_code=201,
        content=_field_to_dict(field)
    )


@router.get(
    "/by-role",
    operation_id="getMetadataSchemasByRole",
    summary="Get metadata schemas by role",
    description="[AC-MRS-04,05] 按指定角色查询所有包含该角色的活跃字段定义",
)
async def get_schemas_by_role(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    role: Annotated[str, Query(
        description="[AC-MRS-04] 字段角色: resource_filter/slot/prompt_var/routing_signal"
    )],
    include_deprecated: Annotated[bool, Query(
        description="是否包含已废弃字段"
    )] = False,
) -> JSONResponse:
    """
    [AC-MRS-04,05] 按角色查询字段定义
    
    Args:
        role: 字段角色
        include_deprecated: 是否包含已废弃字段
    """
    logger.info(
        f"[AC-MRS-04] Getting metadata schemas by role: "
        f"tenant={tenant_id}, role={role}, include_deprecated={include_deprecated}"
    )
    
    provider = RoleBasedFieldProvider(session)
    
    try:
        fields = await provider.get_fields_by_role(tenant_id, role, include_deprecated)
    except InvalidRoleError as e:
        return JSONResponse(
            status_code=400,
            content={
                "error_code": "INVALID_ROLE",
                "message": str(e),
                "details": {
                    "valid_roles": e.valid_roles
                }
            }
        )
    
    return JSONResponse(
        content=[_field_to_dict(f) for f in fields]
    )


@router.get(
    "/{id}",
    operation_id="getMetadataSchema",
    summary="Get metadata schema by ID",
    description="获取单个元数据字段定义",
)
async def get_schema(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    id: str,
) -> JSONResponse:
    """
    获取单个元数据字段定义
    """
    logger.info(
        f"Getting metadata field definition: tenant={tenant_id}, id={id}"
    )
    
    service = MetadataFieldDefinitionService(session)
    field = await service.get_field_definition(tenant_id, id)
    
    if not field:
        return JSONResponse(
            status_code=404,
            content={
                "error_code": "NOT_FOUND",
                "message": f"Field definition {id} not found",
            }
        )
    
    return JSONResponse(content=_field_to_dict(field))


@router.put(
    "/{id}",
    operation_id="updateMetadataSchema",
    summary="Update metadata schema",
    description="[AC-IDSMETA-14] [AC-MRS-01] 更新元数据字段定义，支持修改 field_roles",
)
async def update_schema(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    id: str,
    field_update: MetadataFieldDefinitionUpdate,
) -> JSONResponse:
    """
    [AC-IDSMETA-14] [AC-MRS-01] 更新元数据字段定义
    """
    logger.info(
        f"[AC-IDSMETA-14] [AC-MRS-01] Updating metadata field definition: "
        f"tenant={tenant_id}, id={id}, field_roles={field_update.field_roles}"
    )
    
    if field_update.status and field_update.status not in [s.value for s in MetadataFieldStatus]:
        return JSONResponse(
            status_code=400,
            content={
                "error_code": "INVALID_STATUS",
                "message": f"Invalid status: {field_update.status}",
                "details": {
                    "valid_values": [s.value for s in MetadataFieldStatus]
                }
            }
        )
    
    service = MetadataFieldDefinitionService(session)
    
    try:
        field = await service.update_field_definition(tenant_id, id, field_update)
    except ValueError as e:
        return JSONResponse(
            status_code=400,
            content={
                "error_code": "VALIDATION_ERROR",
                "message": str(e),
            }
        )
    
    if not field:
        return JSONResponse(
            status_code=404,
            content={
                "error_code": "NOT_FOUND",
                "message": f"Field definition {id} not found",
            }
        )
    
    await session.commit()
    
    return JSONResponse(content=_field_to_dict(field))


@router.delete(
    "/{id}",
    operation_id="deleteMetadataSchema",
    summary="Delete metadata schema",
    description="[AC-MRS-16] 删除元数据字段定义，无需考虑历史数据兼容性",
    status_code=204,
)
async def delete_schema(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    id: str,
) -> JSONResponse:
    """
    [AC-MRS-16] 删除元数据字段定义
    """
    logger.info(
        f"[AC-MRS-16] Deleting metadata field definition: "
        f"tenant={tenant_id}, id={id}"
    )
    
    service = MetadataFieldDefinitionService(session)
    success = await service.delete_field_definition(tenant_id, id)
    
    if not success:
        return JSONResponse(
            status_code=404,
            content={
                "error_code": "NOT_FOUND",
                "message": f"Field definition not found: {id}",
            }
        )
    
    return JSONResponse(status_code=204, content=None)


@router.get(
    "/active",
    operation_id="getActiveMetadataSchemas",
    summary="Get active metadata schemas",
    description="[AC-IDSMETA-14] 获取活跃状态的字段定义，用于新建对象时选择",
)
async def get_active_schemas(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    scope: Annotated[str | None, Query(
        description="按适用范围过滤: kb_document/intent_rule/script_flow/prompt_template"
    )] = None,
) -> JSONResponse:
    """
    [AC-IDSMETA-14] 获取活跃状态的字段定义
    """
    logger.info(
        f"[AC-IDSMETA-14] Getting active metadata field definitions: "
        f"tenant={tenant_id}, scope={scope}"
    )
    
    service = MetadataFieldDefinitionService(session)
    fields = await service.get_active_field_definitions(tenant_id, scope)
    
    return JSONResponse(
        content=[_field_to_dict(f) for f in fields]
    )


@router.get(
    "/readable",
    operation_id="getReadableMetadataSchemas",
    summary="Get readable metadata schemas",
    description="[AC-IDSMETA-14] 获取可读取的字段定义（active + deprecated），用于历史数据展示",
)
async def get_readable_schemas(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    scope: Annotated[str | None, Query(
        description="按适用范围过滤: kb_document/intent_rule/script_flow/prompt_template"
    )] = None,
) -> JSONResponse:
    """
    [AC-IDSMETA-14] 获取可读取的字段定义（active + deprecated）
    """
    logger.info(
        f"[AC-IDSMETA-14] Getting readable metadata field definitions: "
        f"tenant={tenant_id}, scope={scope}"
    )
    
    service = MetadataFieldDefinitionService(session)
    fields = await service.get_field_definitions_for_read(tenant_id, scope)
    
    return JSONResponse(
        content=[_field_to_dict(f) for f in fields]
    )


@router.post(
    "/validate",
    operation_id="validateMetadataForCreate",
    summary="Validate metadata for create",
    description="[AC-IDSMETA-14, AC-IDSMETA-15] 验证元数据是否可用于新建对象",
)
async def validate_metadata_for_create(
    tenant_id: Annotated[str, Depends(get_current_tenant_id)],
    session: Annotated[AsyncSession, Depends(get_session)],
    body: dict[str, Any],
) -> JSONResponse:
    """
    [AC-IDSMETA-14, AC-IDSMETA-15] 验证元数据是否可用于新建对象
    
    Request body:
    {
        "metadata": {"grade": "初一", "subject": "语文"},
        "scope": "kb_document"
    }
    """
    metadata = body.get("metadata", {})
    scope = body.get("scope", "kb_document")
    
    logger.info(
        f"[AC-IDSMETA-14] Validating metadata for create: "
        f"tenant={tenant_id}, scope={scope}"
    )
    
    service = MetadataFieldDefinitionService(session)
    is_valid, errors = await service.validate_metadata_for_create(
        tenant_id, metadata, scope
    )
    
    return JSONResponse(
        content={
            "isValid": is_valid,
            "errors": errors,
        }
    )
