"""Title library CRUD routes."""

from __future__ import annotations

from typing import Optional

from app.auth import AuthenticatedUser, get_current_user
from app.dependencies import get_db_session, get_user_repository
from app.schemas.title_library import (
    CreateTitleLibraryRequest,
    ListTitleLibraryResponse,
    TitleLibraryItemResponse,
    UpdateTitleLibraryRequest,
)
from fastapi import APIRouter, Depends, HTTPException, Query, Response, status
from sqlalchemy.orm import Session

from packages.adapters.sqlalchemy_impl.title_library_repository import SQLAlchemyTitleLibraryRepository
from packages.application.title_library.commands import CreateTitleLibraryCommand, UpdateTitleLibraryCommand
from packages.application.title_library.use_cases import (
    CreateTitleLibraryUseCase,
    DeleteTitleLibraryUseCase,
    GetTitleLibraryUseCase,
    ListTitleLibraryUseCase,
    NotFoundError,
    QuotaExceededError,
    UpdateTitleLibraryUseCase,
)
from packages.ports.user_repository import UserRepository

router = APIRouter()


def _get_title_repository(session: Session = Depends(get_db_session)) -> SQLAlchemyTitleLibraryRepository:
    return SQLAlchemyTitleLibraryRepository(session)


def _to_response(item) -> TitleLibraryItemResponse:
    return TitleLibraryItemResponse(
        id=item.id,
        user_id=item.user_id,
        name=item.name,
        text=item.text,
        category=item.category,
        description=item.description,
        tags=item.tags,
        usage_count=item.usage_count,
        is_active=item.is_active,
        created_at=item.created_at,
        updated_at=item.updated_at,
    )


def _get_user_plan(user_id: str, user_repository: UserRepository) -> str:
    user = user_repository.find_by_id(user_id)
    if user is None:
        return "free"
    return getattr(user, "subscription_plan", "free") or "free"


@router.get("", response_model=ListTitleLibraryResponse)
def list_titles(
    category: Optional[str] = Query(None),
    skip: int = Query(0, ge=0),
    limit: int = Query(50, ge=1, le=200),
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    title_repository: SQLAlchemyTitleLibraryRepository = Depends(_get_title_repository),
) -> ListTitleLibraryResponse:
    user_id = authenticated_user.user.id
    use_case = ListTitleLibraryUseCase(title_repository)
    items = use_case.execute(user_id, category=category, skip=skip, limit=limit)
    total = title_repository.count_by_user(user_id)
    return ListTitleLibraryResponse(
        items=[_to_response(i) for i in items],
        total=total,
    )


@router.get("/{title_id}", response_model=TitleLibraryItemResponse)
def get_title(
    title_id: str,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    title_repository: SQLAlchemyTitleLibraryRepository = Depends(_get_title_repository),
) -> TitleLibraryItemResponse:
    user_id = authenticated_user.user.id
    use_case = GetTitleLibraryUseCase(title_repository)
    item = use_case.execute(title_id, user_id)
    if item is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Title not found")
    return _to_response(item)


@router.post("", response_model=TitleLibraryItemResponse, status_code=status.HTTP_201_CREATED)
def create_title(
    request: CreateTitleLibraryRequest,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    title_repository: SQLAlchemyTitleLibraryRepository = Depends(_get_title_repository),
    user_repository: UserRepository = Depends(get_user_repository),
) -> TitleLibraryItemResponse:
    user_id = authenticated_user.user.id
    plan_name = _get_user_plan(user_id, user_repository)
    command = CreateTitleLibraryCommand(
        user_id=user_id,
        name=request.name,
        text=request.text,
        category=request.category,
        description=request.description,
        tags=request.tags,
    )
    use_case = CreateTitleLibraryUseCase(title_repository)
    try:
        item = use_case.execute(command, plan_name=plan_name)
    except QuotaExceededError as exc:
        raise HTTPException(
            status_code=status.HTTP_429_TOO_MANY_REQUESTS,
            detail=f"标题库配额已满（{exc.used}/{exc.limit}），请升级套餐",
        )
    return _to_response(item)


@router.put("/{title_id}", response_model=TitleLibraryItemResponse)
def update_title(
    title_id: str,
    request: UpdateTitleLibraryRequest,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    title_repository: SQLAlchemyTitleLibraryRepository = Depends(_get_title_repository),
) -> TitleLibraryItemResponse:
    user_id = authenticated_user.user.id
    command = UpdateTitleLibraryCommand(
        title_id=title_id,
        user_id=user_id,
        name=request.name,
        text=request.text,
        category=request.category,
        description=request.description,
        tags=request.tags,
    )
    use_case = UpdateTitleLibraryUseCase(title_repository)
    try:
        item = use_case.execute(command)
    except NotFoundError:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Title not found")
    return _to_response(item)


@router.delete("/{title_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_title(
    title_id: str,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    title_repository: SQLAlchemyTitleLibraryRepository = Depends(_get_title_repository),
) -> Response:
    user_id = authenticated_user.user.id
    use_case = DeleteTitleLibraryUseCase(title_repository)
    deleted = use_case.execute(title_id, user_id)
    if not deleted:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Title not found")
    return Response(status_code=204)
