from fastapi import APIRouter, Depends, Header
from pydantic import BaseModel
from sqlmodel import Session

from app.db.session import get_session
from app.services.benefits import (
    cancel_redemption,
    fulfill_redemption,
    list_benefits,
    list_redemptions,
    redeem_benefit,
)
from app.services.admin_auth import get_admin_session

router = APIRouter(tags=["benefits"])


def require_admin(
    x_admin_session: str | None = Header(default=None, alias="X-Admin-Session"),
    session: Session = Depends(get_session),
) -> None:
    get_admin_session(session, x_admin_session)


class RedeemRequest(BaseModel):
    child_id: int
    idempotency_key: str | None = None


class IdempotentActionRequest(BaseModel):
    idempotency_key: str | None = None


@router.get("/benefits")
def get_benefits(child_id: int | None = None, session: Session = Depends(get_session)) -> dict:
    return list_benefits(session, child_id=child_id)


@router.post("/benefits/{benefit_id}/redeem")
def post_redeem_benefit(
    benefit_id: int,
    payload: RedeemRequest,
    session: Session = Depends(get_session),
) -> dict:
    return redeem_benefit(session, benefit_id, payload.child_id, payload.idempotency_key)


@router.get("/admin/redemptions")
def get_admin_redemptions(
    child_id: int | None = None,
    _: None = Depends(require_admin),
    session: Session = Depends(get_session),
) -> dict:
    return list_redemptions(session, child_id=child_id)


@router.post("/admin/redemptions/{redemption_id}/fulfill")
def post_fulfill_redemption(
    redemption_id: int,
    payload: IdempotentActionRequest | None = None,
    _: None = Depends(require_admin),
    session: Session = Depends(get_session),
) -> dict:
    return fulfill_redemption(session, redemption_id, payload.idempotency_key if payload else None)


@router.post("/admin/redemptions/{redemption_id}/cancel")
def post_cancel_redemption(
    redemption_id: int,
    payload: IdempotentActionRequest | None = None,
    _: None = Depends(require_admin),
    session: Session = Depends(get_session),
) -> dict:
    return cancel_redemption(session, redemption_id, payload.idempotency_key if payload else None)
