from typing import Any

from app.auth import AuthenticatedUser, get_current_user
from app.dependencies import get_project_repository
from app.schemas.project import (
    CreateProjectRequest,
    ListProjectsResponse,
    ProjectResponse,
)
from fastapi import APIRouter, Depends, HTTPException, status

from packages.application import (
    CreateProjectCommand,
    CreateProjectUseCase,
    DeleteProjectUseCase,
    GetProjectUseCase,
    ListProjectsUseCase,
)

router = APIRouter()


def _to_project_response(item) -> ProjectResponse:
    return ProjectResponse(
        id=item.id,
        owner_user_id=item.owner_user_id,
        name=item.name,
        description=item.description,
        shared_users=item.shared_users,
    )


@router.get("/{project_id}", response_model=ProjectResponse)
def get_project(
    project_id: str,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    project_repository: Any = Depends(get_project_repository),
) -> ProjectResponse:
    use_case = GetProjectUseCase(project_repository)
    project = use_case.execute(project_id)
    if project is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Project not found")
    if not project.can_access(authenticated_user.user.id):
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Access denied to project")
    return _to_project_response(project)


@router.get("", response_model=ListProjectsResponse)
def list_projects(
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    project_repository: Any = Depends(get_project_repository),
) -> ListProjectsResponse:
    use_case = ListProjectsUseCase(project_repository)
    projects = use_case.execute(authenticated_user.user.id)
    return ListProjectsResponse(items=[_to_project_response(item) for item in projects])


@router.post("", response_model=ProjectResponse)
def create_project(
    request: CreateProjectRequest,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    project_repository: Any = Depends(get_project_repository),
) -> ProjectResponse:
    use_case = CreateProjectUseCase(project_repository)
    project = use_case.execute(
        CreateProjectCommand(
            name=request.name,
            description=request.description,
        ),
        owner_user_id=authenticated_user.user.id,
    )
    return _to_project_response(project)


@router.delete("/{project_id}")
def delete_project(
    project_id: str,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    project_repository: Any = Depends(get_project_repository),
):
    use_case = DeleteProjectUseCase(project_repository)
    try:
        deleted = use_case.execute(project_id, authenticated_user.user.id)
    except PermissionError:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Only the project owner can delete this project",
        )
    if not deleted:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Project not found")
    return {"message": "Project deleted successfully"}
