
from fastapi import APIRouter, Depends, HTTPException
from common_logging import get_logger
from sqlalchemy.orm import Session

from app.api.deps import get_current_user, get_db
from app.crud.data_model import data_model_crud
from app.models.data_model import DataModel
from app.models.user import User
from app.schemas.data_model import DataModelCreate, DataModelResponse, DataModelUpdate

logger = get_logger(__name__)
router = APIRouter()


@router.get("/models", response_model=list[DataModelResponse])
async def list_models(
    status: str | None = None,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    logger.info(f"Listing data models: status={status}, user={current_user.id}")
    if current_user.tenant_id:
        query = db.query(DataModel).filter(
            (DataModel.tenant_id == current_user.tenant_id) | (DataModel.type == "system")
        )
    else:
        query = db.query(DataModel).filter(
            (DataModel.tenant_id is None) | (DataModel.type == "system")
        )
    if status:
        query = query.filter(DataModel.status == status)
    models = query.all()
    logger.info(f"Found {len(models)} data models")
    return models


@router.get("/models/{model_id}", response_model=DataModelResponse)
async def get_model(
    model_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)
):
    model = data_model_crud.get(db, id=model_id)
    if not model:
        raise HTTPException(status_code=404, detail="Model not found")
    return model


@router.post("/models", response_model=DataModelResponse)
async def create_model(
    model_in: DataModelCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    logger.info(f"Creating data model: key={model_in.key}, user={current_user.id}")
    existing = data_model_crud.get_by_key(db, key=model_in.key)
    if existing:
        logger.warning(f"Model key already exists: key={model_in.key}")
        raise HTTPException(status_code=400, detail="Model key already exists")
    tenant_id = current_user.tenant_id if current_user.tenant_id else None
    model = data_model_crud.create_with_fields(
        db, obj_in=model_in, created_by=current_user.id, tenant_id=tenant_id
    )
    logger.info(f"Data model created: id={model.id}, key={model.key}")
    return model


@router.put("/models/{model_id}", response_model=DataModelResponse)
async def update_model(
    model_id: int,
    model_in: DataModelUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    model = data_model_crud.get(db, id=model_id)
    if not model:
        raise HTTPException(status_code=404, detail="Model not found")
    if model.type == "system":
        raise HTTPException(status_code=403, detail="System models cannot be modified")
    return data_model_crud.update_with_fields(db, db_obj=model, obj_in=model_in)


@router.delete("/models/{model_id}")
async def delete_model(
    model_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)
):
    logger.info(f"Deleting data model: id={model_id}, user={current_user.id}")
    model = data_model_crud.get(db, id=model_id)
    if not model:
        logger.warning(f"Model not found: id={model_id}")
        raise HTTPException(status_code=404, detail="Model not found")
    if model.type == "system":
        logger.warning(f"Attempt to delete system model: id={model_id}")
        raise HTTPException(status_code=403, detail="System models cannot be deleted")
    data_model_crud.remove(db, id=model_id)
    logger.info(f"Data model deleted: id={model_id}")
    return {"message": "Model deleted successfully"}
