from fastapi import APIRouter, Depends, HTTPException, Query, status

from app.api.dependencies.auth import get_access_token
from app.api.dependencies.permissions import require_permission
from app.application.admin.variants import VariantService
from app.schemas.auth import AuthenticatedUser
from app.schemas.admin import VariantCreate, VariantListResponse, VariantRead, VariantUpdate

router = APIRouter()
service = VariantService()


@router.get("", response_model=VariantListResponse)
async def list_variants(
    experiment_id: str | None = Query(default=None),
    access_token: str = Depends(get_access_token),
    _: AuthenticatedUser = Depends(require_permission("can_manage_variants")),
) -> VariantListResponse:
    items = await service.list_variants(
        experiment_id=experiment_id,
        access_token=access_token,
    )
    return VariantListResponse(items=items)


@router.get("/{variant_id}", response_model=VariantRead)
async def get_variant(
    variant_id: str,
    access_token: str = Depends(get_access_token),
    _: AuthenticatedUser = Depends(require_permission("can_manage_variants")),
) -> VariantRead:
    item = await service.get_variant(variant_id, access_token=access_token)
    if not item:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Variant '{variant_id}' not found.",
        )
    return item


@router.post("", response_model=VariantRead, status_code=status.HTTP_201_CREATED)
async def create_variant(
    payload: VariantCreate,
    access_token: str = Depends(get_access_token),
    _: AuthenticatedUser = Depends(require_permission("can_manage_variants")),
) -> VariantRead:
    return await service.create_variant(payload, access_token=access_token)


@router.patch("/{variant_id}", response_model=VariantRead)
async def update_variant(
    variant_id: str,
    payload: VariantUpdate,
    access_token: str = Depends(get_access_token),
    _: AuthenticatedUser = Depends(require_permission("can_manage_variants")),
) -> VariantRead:
    item = await service.update_variant(variant_id, payload, access_token=access_token)
    if not item:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Variant '{variant_id}' not found.",
        )
    return item
