from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session

from mineru_flow.internal.common.db import get_db
from mineru_flow.internal.common.logging import get_api_logger
from mineru_flow.internal.crud.task import config as config_crud
from mineru_flow.internal.api.v1.schema.request.config import (
    ConfigCreateRequest,
    ConfigUpdateRequest,
)
from mineru_flow.internal.api.v1.schema.response.config import (
    ConfigResponse,
    ConfigListResponse,
    ConfigCreateResponse,
    ConfigUpdateResponse,
    ConfigDeleteResponse,
)

router = APIRouter(tags=["configs"])
config_logger = get_api_logger().bind(endpoint="configs")


@router.post("/configs", response_model=ConfigCreateResponse)
async def create_config(config_in: ConfigCreateRequest, db: Session = Depends(get_db)):
    """创建配置"""
    # 检查是否已存在相同类型和名称的配置
    existing_config = config_crud.get_by_type_and_name(
        db=db, type=config_in.type, name=config_in.name
    )
    if existing_config:
        config_logger.warning(
            "Configuration already exists",
            type=config_in.type,
            name=config_in.name,
        )
        raise HTTPException(status_code=400, detail="Configuration already exists")

    # 转换为内部schema
    config_create = ConfigCreateRequest(**config_in.model_dump())
    config = config_crud.create(db=db, obj_in=config_create)
    config_logger.info(
        "配置创建成功",
        config_id=config.id,
        type=config_in.type,
        name=config_in.name,
    )

    return ConfigCreateResponse(
        success=True, message="配置创建成功", data=ConfigResponse.model_validate(config)
    )


@router.get("/configs/all", response_model=ConfigListResponse)
async def list_all_configs(
    type: Optional[str] = Query(None, description="按类型过滤"),
    db: Session = Depends(get_db),
):
    """获取全部配置"""
    configs, total = config_crud.get_all(db=db, filters={"type": type})
    config_logger.debug("获取全部配置", filter_type=type, total=total)
    return ConfigListResponse(
        data=[ConfigResponse.model_validate(config) for config in configs],
        total=total,
    )


@router.get("/configs/{config_id}", response_model=ConfigResponse)
async def get_config(config_id: int, db: Session = Depends(get_db)):
    """获取配置详情"""
    config = config_crud.get(db=db, id=config_id)
    if not config:
        config_logger.warning("Configuration not found", config_id=config_id)
        raise HTTPException(status_code=404, detail="Configuration not found")
    config_logger.debug("Retrieve configuration details", config_id=config_id)
    return ConfigResponse.model_validate(config)


@router.get("/configs", response_model=ConfigListResponse)
async def list_configs(
    type: Optional[str] = Query(None, description="按类型过滤"),
    skip: int = Query(0, ge=0, description="跳过的记录数"),
    limit: int = Query(100, ge=1, le=1000, description="返回的记录数"),
    db: Session = Depends(get_db),
):
    """获取配置列表"""
    if type:
        configs, total = config_crud.get_by_type(db=db, type=type)
        config_responses = [ConfigResponse.model_validate(config) for config in configs]
    else:
        configs, total = config_crud.get_multi(db=db, skip=skip, limit=limit)
        config_responses = [ConfigResponse.model_validate(config) for config in configs]
    config_logger.debug(
        "查询配置列表",
        filter_type=type,
        skip=skip,
        limit=limit,
        returned=len(config_responses),
        total=total,
    )

    return ConfigListResponse(data=config_responses, total=total)


@router.put("/configs/{config_id}", response_model=ConfigUpdateResponse)
async def update_config(
    config_id: int, config_in: ConfigUpdateRequest, db: Session = Depends(get_db)
):
    """更新配置"""
    config = config_crud.get(db=db, id=config_id)
    if not config:
        config_logger.warning("Configuration not found", config_id=config_id)
        raise HTTPException(status_code=404, detail="Configuration not found")

    # 转换为内部schema
    update_payload = config_in.model_dump(exclude_unset=True)
    config_update = ConfigUpdateRequest(**update_payload)
    config = config_crud.update(db=db, id=config_id, obj_in=config_update)
    config_logger.info(
        "配置更新成功",
        config_id=config_id,
        fields=list(update_payload.keys()),
    )

    return ConfigUpdateResponse(
        success=True, message="配置更新成功", data=ConfigResponse.model_validate(config)
    )


@router.delete("/configs/{config_id}", response_model=ConfigDeleteResponse)
async def delete_config(config_id: int, db: Session = Depends(get_db)):
    """删除配置"""
    config = config_crud.get(db=db, id=config_id)
    if not config:
        config_logger.warning("Configuration not found", config_id=config_id)
        raise HTTPException(status_code=404, detail="Configuration not found")

    config_crud.delete(db=db, id=config_id)
    config_logger.info("Configuration deleted", config_id=config_id)
    return ConfigDeleteResponse(success=True, message="配置删除成功")
