"""Point ledger APIs — Phase 7.2."""
from __future__ import annotations

from uuid import UUID

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

from app.api.deps import get_db, require_tenant
from app.api.permissions import require_permissions
from app.models.types import LedgerEntryType
from app.permissions.definitions import (
    LOYALTY_POINTS_ADJUST,
    LOYALTY_POINTS_EARN,
    LOYALTY_POINTS_EXPIRE,
    LOYALTY_POINTS_REDEEM,
    LOYALTY_POINTS_VIEW,
)
from app.schemas.ledger import (
    PointAdjustRequest,
    PointBalanceRead,
    PointEarnRequest,
    PointExpireRequest,
    PointLedgerEntryRead,
    PointLedgerPage,
    PointRedeemRequest,
)
from app.services.point_engine import PointEngineService
from shared.security import CurrentUser

router = APIRouter()


@router.get("/{account_id}/balance", response_model=PointBalanceRead)
async def get_balance(
    account_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(require_permissions(LOYALTY_POINTS_VIEW)),
):
    return await PointEngineService(db).get_balance(tenant_id, account_id)


@router.get("/{account_id}/ledger", response_model=PointLedgerPage)
async def list_ledger(
    account_id: UUID,
    offset: int = Query(default=0, ge=0),
    limit: int = Query(default=50, ge=1, le=200),
    entry_type: LedgerEntryType | None = None,
    q: str | None = Query(default=None, max_length=100),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(require_permissions(LOYALTY_POINTS_VIEW)),
):
    rows, total = await PointEngineService(db).list_entries(
        tenant_id,
        account_id,
        entry_type=entry_type,
        offset=offset,
        limit=limit,
        q=q,
    )
    return PointLedgerPage(
        items=rows, total=total, offset=offset, limit=limit
    )


@router.post("/{account_id}/earn", response_model=PointLedgerEntryRead)
async def earn_points(
    account_id: UUID,
    body: PointEarnRequest,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(LOYALTY_POINTS_EARN)),
):
    return await PointEngineService(db).earn(tenant_id, account_id, body, actor=user)


@router.post("/{account_id}/redeem", response_model=PointLedgerEntryRead)
async def redeem_points(
    account_id: UUID,
    body: PointRedeemRequest,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(LOYALTY_POINTS_REDEEM)),
):
    return await PointEngineService(db).redeem(
        tenant_id, account_id, body, actor=user
    )


@router.post("/{account_id}/adjust", response_model=PointLedgerEntryRead)
async def adjust_points(
    account_id: UUID,
    body: PointAdjustRequest,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(LOYALTY_POINTS_ADJUST)),
):
    return await PointEngineService(db).adjust(
        tenant_id, account_id, body, actor=user
    )


@router.post("/{account_id}/expire-points", response_model=PointLedgerEntryRead)
async def expire_points(
    account_id: UUID,
    body: PointExpireRequest,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(LOYALTY_POINTS_EXPIRE)),
):
    return await PointEngineService(db).expire(
        tenant_id, account_id, body, actor=user
    )
