"""
Project API Routes - Full CRUD Implementation
"""

from datetime import datetime
from typing import List

from fastapi import APIRouter, HTTPException, status
from pydantic import BaseModel

from opentester.core.storage import StorageError, get_project_storage
from opentester.models.project import (
    ProjectCreate,
    ProjectResponse,
    Target,
    TargetType,
    TestProject,
)

router = APIRouter()
storage = get_project_storage()


class ProjectUpdate(BaseModel):
    """Request model for updating a project."""
    name: str | None = None
    prd_content: str | None = None


@router.get("", response_model=List[ProjectResponse])
async def list_projects() -> List[ProjectResponse]:
    """List all projects."""
    projects = storage.list_projects()
    return [
        ProjectResponse(
            id=p["id"],
            name=p["name"],
            target_type=p["target_type"],
            created_at=p["created_at"],
            updated_at=p["updated_at"],
            case_count=p["case_count"],
            group_count=p["group_count"],
        )
        for p in projects
    ]


@router.post("", response_model=ProjectResponse, status_code=status.HTTP_201_CREATED)
async def create_project(data: ProjectCreate) -> ProjectResponse:
    """Create a new project."""
    import uuid

    now = datetime.now().isoformat()
    project = TestProject(
        id=str(uuid.uuid4()),
        name=data.name,
        target=Target(type=data.target_type),
        prd_content=data.prd_content,
        created_at=datetime.fromisoformat(now),
        updated_at=datetime.fromisoformat(now),
    )

    try:
        storage.save_project(project)
    except StorageError as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to create project: {e}",
        )

    return ProjectResponse(
        id=project.id,
        name=project.name,
        target_type=project.target.type,
        created_at=now,
        updated_at=now,
        case_count=0,
        group_count=0,
    )


@router.get("/{project_id}", response_model=ProjectResponse)
async def get_project(project_id: str) -> ProjectResponse:
    """Get a project by ID."""
    project = storage.get_project(project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project {project_id} not found",
        )

    return ProjectResponse(
        id=project.id,
        name=project.name,
        target_type=project.target.type,
        created_at=project.created_at.isoformat(),
        updated_at=project.updated_at.isoformat(),
        case_count=len(project.cases),
        group_count=len(project.groups),
    )


@router.put("/{project_id}", response_model=ProjectResponse)
async def update_project(project_id: str, data: ProjectUpdate) -> ProjectResponse:
    """Update a project."""
    project = storage.get_project(project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project {project_id} not found",
        )

    if data.name is not None:
        project.name = data.name
    if data.prd_content is not None:
        project.prd_content = data.prd_content

    try:
        storage.save_project(project)
    except StorageError as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to update project: {e}",
        )

    return ProjectResponse(
        id=project.id,
        name=project.name,
        target_type=project.target.type,
        created_at=project.created_at.isoformat(),
        updated_at=project.updated_at.isoformat(),
        case_count=len(project.cases),
        group_count=len(project.groups),
    )


@router.delete("/{project_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_project(project_id: str) -> None:
    """Delete a project."""
    if not storage.project_exists(project_id):
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project {project_id} not found",
        )

    success = storage.delete_project(project_id)
    if not success:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to delete project",
        )
