from typing import Literal

from fastapi import APIRouter, Depends, Query
from sqlalchemy.ext.asyncio import AsyncSession

from app.database.session import get_db
from app.domain.entities.lens import LensEntity
from app.domain.entities.responses.paginated_lens import PaginatedLensesResponseEntity
from app.infrastructure.dependencies import get_current_user
from app.infrastructure.lenses_service import LensesService

router = APIRouter()


@router.get(
    "/",
    response_model=PaginatedLensesResponseEntity,
    summary="Get all lenses with pagination and filtering",
    description="Returns a paginated list of lenses with optional search, sorting, and advanced filtering",
)
async def get_all_lenses(
    page: int = Query(1, ge=1, description="Page number"),
    page_size: int = Query(10, ge=1, le=100, description="Number of lenses per page"),
    search: str = Query(None, description="Search term for filtering lenses"),
    sort_order: Literal["asc", "desc"] = Query("desc", description="Sort order by id (asc or desc)"),
    tor: float = Query(None, description="Filter by tor"),
    diameter: float = Query(None, description="Filter by diameter"),
    preset_refraction: float = Query(None, description="Filter by preset refraction"),
    periphery_toricity: float = Query(None, description="Filter by periphery toricity"),
    side: Literal["левая", "правая", "all"] = Query("all", description="Filter by side"),
    issued: bool = Query(None, description="Filter by issued status"),
    trial: float = Query(None, description="Filter by trial"),
    db: AsyncSession = Depends(get_db),
    user=Depends(get_current_user),
):
    lenses_service = LensesService(db)
    lenses, total_count = await lenses_service.get_all_lenses(
        page=page,
        page_size=page_size,
        search=search,
        sort_order=sort_order,
        tor=tor,
        diameter=diameter,
        preset_refraction=preset_refraction,
        periphery_toricity=periphery_toricity,
        side=side,
        issued=issued,
        trial=trial,
    )
    return {"lenses": lenses, "total_count": total_count}


@router.get(
    "/not_issued/",
    response_model=list[LensEntity],
    summary="Get all not issued lenses",
    description="Returns a list of all not issued lenses",
)
async def get_all_not_issued_lenses(
        db: AsyncSession = Depends(get_db),
        user=Depends(get_current_user),
):
    lenses_service = LensesService(db)
    return await lenses_service.get_all_not_issued_lenses()


@router.post(
    "/",
    response_model=LensEntity,
    summary="Create lens",
    description="Creates a new lens",
)
async def create_lens(
        lens: LensEntity,
        db: AsyncSession = Depends(get_db),
        user=Depends(get_current_user),
):
    lenses_service = LensesService(db)
    return await lenses_service.create_lens(lens)


@router.put(
    "/{lens_id}/",
    response_model=LensEntity,
    summary="Update lens",
    description="Updates an existing lens",
)
async def update_lens(
        lens_id: int,
        lens: LensEntity,
        db: AsyncSession = Depends(get_db),
        user=Depends(get_current_user),
):
    lenses_service = LensesService(db)
    return await lenses_service.update_lens(lens_id, lens)


@router.delete(
    "/{lens_id}/",
    response_model=LensEntity,
    summary="Delete lens",
    description="Deletes an existing lens",
)
async def delete_lens(
        lens_id: int,
        db: AsyncSession = Depends(get_db),
        user=Depends(get_current_user),
):
    lenses_service = LensesService(db)
    return await lenses_service.delete_lens(lens_id)
