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

from database.postgres import get_pg_session
from auth.dependencies import get_current_user, require_staff_management
from auth.models import TokenPayload
from staff import service
from staff.models import (
    StaffCreate, StaffUpdate, StaffPasswordUpdate,
    StaffResponse, StaffListResponse,
    PreferencesUpdate,
)

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


@router.get("/me", response_model=StaffResponse)
async def get_current_staff(
    current_user: TokenPayload = Depends(get_current_user),
    db: AsyncSession = Depends(get_pg_session),
):
    return await service.get_staff_me(db, current_user.sub)


@router.get("/me/preferences", response_model=dict)
async def get_preferences(
    current_user: TokenPayload = Depends(get_current_user),
    db: AsyncSession = Depends(get_pg_session),
):
    return await service.get_preferences(db, current_user.sub)


@router.patch("/me/preferences/{page_key}", response_model=dict)
async def update_preferences(
    page_key: str,
    body: PreferencesUpdate,
    current_user: TokenPayload = Depends(get_current_user),
    db: AsyncSession = Depends(get_pg_session),
):
    return await service.update_preferences(db, current_user.sub, page_key, body.prefs)


@router.get("", response_model=StaffListResponse)
async def list_staff(
    search: str = Query(None),
    role: str = Query(None),
    current_user: TokenPayload = Depends(require_staff_management),
    db: AsyncSession = Depends(get_pg_session),
):
    return await service.list_staff(db, search=search, role_filter=role)


@router.get("/{staff_id}", response_model=StaffResponse)
async def get_staff(
    staff_id: str,
    current_user: TokenPayload = Depends(require_staff_management),
    db: AsyncSession = Depends(get_pg_session),
):
    return await service.get_staff(db, staff_id)


@router.post("", response_model=StaffResponse)
async def create_staff(
    body: StaffCreate,
    current_user: TokenPayload = Depends(require_staff_management),
    db: AsyncSession = Depends(get_pg_session),
):
    return await service.create_staff(
        db,
        data=body.model_dump(),
        current_user_role=current_user.role,
    )


@router.put("/{staff_id}", response_model=StaffResponse)
async def update_staff(
    staff_id: str,
    body: StaffUpdate,
    current_user: TokenPayload = Depends(require_staff_management),
    db: AsyncSession = Depends(get_pg_session),
):
    return await service.update_staff(
        db,
        staff_id=staff_id,
        data=body.model_dump(exclude_unset=True),
        current_user_role=current_user.role,
        current_user_id=current_user.sub,
    )


@router.put("/{staff_id}/password")
async def update_staff_password(
    staff_id: str,
    body: StaffPasswordUpdate,
    current_user: TokenPayload = Depends(require_staff_management),
    db: AsyncSession = Depends(get_pg_session),
):
    return await service.update_staff_password(
        db,
        staff_id=staff_id,
        new_password=body.new_password,
        current_user_role=current_user.role,
    )


@router.delete("/{staff_id}")
async def delete_staff(
    staff_id: str,
    current_user: TokenPayload = Depends(require_staff_management),
    db: AsyncSession = Depends(get_pg_session),
):
    return await service.delete_staff(
        db,
        staff_id=staff_id,
        current_user_role=current_user.role,
        current_user_id=current_user.sub,
    )
