"""
專案 API。

階段 2a 提供:
  - GET    /api/projects        ─ 列出所有非 archived 專案
  - POST   /api/projects        ─ 建立新專案(建立者自動成為 owner)
  - GET    /api/projects/{id}   ─ 取得單一專案(含任務數統計)
  - PATCH  /api/projects/{id}   ─ 更新專案(只有專案 owner 或公司 owner 能改)
  - DELETE /api/projects/{id}   ─ 軟刪除專案(只有 owner 能刪)

設計重點:
  1. 軟刪除:deleted_at 有值代表刪除,前端永遠看不到
  2. 權限:目前只區分「公司 owner」「專案 owner」「其他人」,
     階段 3 之後若要更細的權限再擴充
"""

from datetime import datetime, timezone
from uuid import UUID

from fastapi import APIRouter, HTTPException, status
from sqlalchemy import select

from app.core.deps import CurrentUser, DBSession
from app.models.task import Project
from app.schemas.task import ProjectCreateRequest, ProjectPublic, ProjectUpdateRequest


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


@router.get("", response_model=list[ProjectPublic], summary="列出所有專案")
async def list_projects(
    current_user: CurrentUser,
    db: DBSession,
    include_archived: bool = False,
) -> list[Project]:
    """列出所有非軟刪除的專案。

    預設不含已歸檔(archived)專案,加 ?include_archived=true 看全部。
    """
    stmt = select(Project).where(Project.deleted_at.is_(None))
    if not include_archived:
        stmt = stmt.where(Project.status == "active")
    stmt = stmt.order_by(Project.created_at.desc())

    result = await db.execute(stmt)
    return list(result.scalars().all())


@router.post(
    "",
    response_model=ProjectPublic,
    status_code=status.HTTP_201_CREATED,
    summary="建立新專案",
)
async def create_project(
    payload: ProjectCreateRequest,
    current_user: CurrentUser,
    db: DBSession,
) -> Project:
    project = Project(
        name=payload.name,
        description=payload.description,
        color=payload.color,
        owner_id=current_user.id,
        status="active",
    )
    db.add(project)
    await db.commit()
    await db.refresh(project)
    return project


async def _get_project_or_404(project_id: UUID, db: DBSession) -> Project:
    """共用查單一專案的 helper(過濾軟刪除)。"""
    stmt = select(Project).where(Project.id == project_id, Project.deleted_at.is_(None))
    project = (await db.execute(stmt)).scalar_one_or_none()
    if project is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="找不到此專案")
    return project


@router.get("/{project_id}", response_model=ProjectPublic, summary="取得單一專案")
async def get_project(
    project_id: UUID,
    current_user: CurrentUser,
    db: DBSession,
) -> Project:
    return await _get_project_or_404(project_id, db)


def _can_edit_project(user, project: Project) -> bool:
    """誰能改/刪這個專案?專案 owner 或公司 owner。"""
    return user.role == "owner" or project.owner_id == user.id


@router.patch("/{project_id}", response_model=ProjectPublic, summary="更新專案")
async def update_project(
    project_id: UUID,
    payload: ProjectUpdateRequest,
    current_user: CurrentUser,
    db: DBSession,
) -> Project:
    project = await _get_project_or_404(project_id, db)
    if not _can_edit_project(current_user, project):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="只有專案 owner 或公司 owner 能修改",
        )

    if payload.name is not None:
        project.name = payload.name
    if payload.description is not None:
        project.description = payload.description
    if payload.color is not None:
        project.color = payload.color
    if payload.status is not None:
        project.status = payload.status

    await db.commit()
    await db.refresh(project)
    return project


@router.delete(
    "/{project_id}",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="軟刪除專案",
)
async def delete_project(
    project_id: UUID,
    current_user: CurrentUser,
    db: DBSession,
) -> None:
    project = await _get_project_or_404(project_id, db)
    if not _can_edit_project(current_user, project):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="只有專案 owner 或公司 owner 能刪除",
        )
    project.deleted_at = datetime.now(timezone.utc)
    await db.commit()
