from fastapi import APIRouter, Depends, HTTPException, status

from app.api.deps import require_session
from app.services.tenant_store import (
    SessionIdentity,
    TipsRosterWritePayload,
    TipsRunPayoutStatusPayload,
    TipsRunPreviewPayload,
    get_tenant_store,
)


router = APIRouter()


def _raise_tips_error(exc: ValueError) -> None:
    detail = str(exc)
    normalized = detail.lower()
    status_code = status.HTTP_403_FORBIDDEN if "non puo" in normalized else status.HTTP_400_BAD_REQUEST
    raise HTTPException(status_code=status_code, detail=detail) from exc


@router.get("/{area}")
def get_tips_module(
    area: str,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().get_tips_module(session, area)
    except ValueError as exc:
        _raise_tips_error(exc)


@router.put("/{area}/roster")
def replace_tips_roster(
    area: str,
    payload: TipsRosterWritePayload,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().replace_tips_roster(session, area, payload)
    except ValueError as exc:
        _raise_tips_error(exc)


@router.post("/{area}/preview")
def preview_tips_distribution(
    area: str,
    payload: TipsRunPreviewPayload,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().preview_tips_distribution(session, area, payload)
    except ValueError as exc:
        _raise_tips_error(exc)


@router.post("/{area}/runs")
def save_tips_distribution(
    area: str,
    payload: TipsRunPreviewPayload,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().save_tips_distribution(session, area, payload)
    except ValueError as exc:
        _raise_tips_error(exc)


@router.get("/{area}/runs/{run_id}")
def get_tips_run_detail(
    area: str,
    run_id: str,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().get_tips_run_detail(session, area, run_id)
    except KeyError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=exc.args[0] if exc.args else str(exc)) from exc
    except ValueError as exc:
        _raise_tips_error(exc)


@router.patch("/{area}/runs/{run_id}/payout-status")
def update_tips_run_payout_status(
    area: str,
    run_id: str,
    payload: TipsRunPayoutStatusPayload,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().set_tips_run_payout_status(session, area, run_id, delivered=payload.delivered)
    except KeyError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=exc.args[0] if exc.args else str(exc)) from exc
    except ValueError as exc:
        _raise_tips_error(exc)
