"""Project CRUD API routes."""

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession

from mixlift.deps import get_current_user, get_db
from mixlift.projects.models import Dataset, ModelRun, Project, User
from mixlift.projects.schemas import ProjectCreate, ProjectResponse

router = APIRouter(prefix="/projects", tags=["projects"])


@router.get("/", response_model=list[ProjectResponse])
async def list_projects(
    user: User = Depends(get_current_user),
    session: AsyncSession = Depends(get_db),
):
    result = await session.execute(
        select(Project).where(Project.user_id == user.id).order_by(Project.created_at.desc())
    )
    projects = result.scalars().all()

    responses = []
    for project in projects:
        # Count datasets
        ds_count = await session.execute(
            select(func.count()).where(Dataset.project_id == project.id)
        )
        # Latest run status
        latest_run = await session.execute(
            select(ModelRun.status)
            .where(ModelRun.project_id == project.id)
            .order_by(ModelRun.created_at.desc())
            .limit(1)
        )
        run_status = latest_run.scalar_one_or_none()

        responses.append(
            ProjectResponse(
                id=str(project.id),
                name=project.name,
                target_metric=project.target_metric,
                currency=project.currency,
                created_at=project.created_at,
                dataset_count=ds_count.scalar() or 0,
                latest_run_status=run_status,
            )
        )

    return responses


@router.post("/", response_model=ProjectResponse, status_code=status.HTTP_201_CREATED)
async def create_project(
    request: ProjectCreate,
    user: User = Depends(get_current_user),
    session: AsyncSession = Depends(get_db),
):
    # Check project limit for free tier
    if user.tier == "free":
        from mixlift.config import settings

        count = await session.execute(
            select(func.count()).where(Project.user_id == user.id)
        )
        if (count.scalar() or 0) >= settings.free_max_projects:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail=f"Free tier limited to {settings.free_max_projects} projects",
            )

    project = Project(
        user_id=user.id,
        name=request.name,
        target_metric=request.target_metric,
        currency=request.currency,
    )
    session.add(project)
    await session.flush()

    return ProjectResponse(
        id=str(project.id),
        name=project.name,
        target_metric=project.target_metric,
        currency=project.currency,
        created_at=project.created_at,
    )


@router.get("/{project_id}", response_model=ProjectResponse)
async def get_project(
    project_id: str,
    user: User = Depends(get_current_user),
    session: AsyncSession = Depends(get_db),
):
    result = await session.execute(
        select(Project).where(Project.id == project_id, Project.user_id == user.id)
    )
    project = result.scalar_one_or_none()
    if not project:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Project not found")

    ds_count = await session.execute(
        select(func.count()).where(Dataset.project_id == project.id)
    )
    latest_run = await session.execute(
        select(ModelRun.status)
        .where(ModelRun.project_id == project.id)
        .order_by(ModelRun.created_at.desc())
        .limit(1)
    )

    return ProjectResponse(
        id=str(project.id),
        name=project.name,
        target_metric=project.target_metric,
        currency=project.currency,
        created_at=project.created_at,
        dataset_count=ds_count.scalar() or 0,
        latest_run_status=latest_run.scalar_one_or_none(),
    )


@router.delete("/{project_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_project(
    project_id: str,
    user: User = Depends(get_current_user),
    session: AsyncSession = Depends(get_db),
):
    result = await session.execute(
        select(Project).where(Project.id == project_id, Project.user_id == user.id)
    )
    project = result.scalar_one_or_none()
    if not project:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Project not found")

    await session.delete(project)
