"""Router for Rekonsiliasi Harian (daily sounding-based reconciliation) endpoints."""

from datetime import date

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

from app.core.database import get_db
from app.dependencies import get_current_user, get_spbu_access
from app.models.user import User
from app.services import rekonsiliasi_service

router = APIRouter(
    prefix="/spbus/{spbu_id}/rekonsiliasi",
    tags=["rekonsiliasi"],
)


def _service_error(e: ValueError | PermissionError) -> HTTPException:
    if isinstance(e, PermissionError):
        return HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(e))
    return HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))


@router.get("", response_model=dict)
async def list_rekonsiliasi(
    spbu_id: int,
    tanggal_mulai: date | None = Query(default=None),
    tanggal_akhir: date | None = Query(default=None),
    status_filter: str | None = Query(default=None, alias="status"),
    skip: int = Query(default=0, ge=0),
    limit: int = Query(default=50, ge=1, le=200),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_spbu_access),
) -> dict:
    """List daily reconciliations for an SPBU."""
    try:
        rows, total = await rekonsiliasi_service.list_rekonsiliasi(
            db, spbu_id,
            tanggal_mulai=tanggal_mulai,
            tanggal_akhir=tanggal_akhir,
            status=status_filter,
            skip=skip, limit=limit,
        )
    except (ValueError, PermissionError) as e:
        raise _service_error(e)
    return {
        "data": [r.model_dump() for r in rows],
        "meta": {"total": total, "page": skip // limit + 1, "per_page": limit},
    }


@router.get("/{tanggal}", response_model=dict)
async def get_rekonsiliasi(
    spbu_id: int,
    tanggal: date,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_spbu_access),
) -> dict:
    """Get reconciliation detail for a specific date."""
    result = await rekonsiliasi_service.get_rekonsiliasi(db, spbu_id, tanggal)
    if result is None:
        return {"data": None, "message": "Rekonsiliasi belum dijalankan untuk tanggal ini"}
    return {"data": result.model_dump()}


@router.post("/{tanggal}/run", response_model=dict, status_code=status.HTTP_201_CREATED)
async def run_rekonsiliasi(
    spbu_id: int,
    tanggal: date,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_spbu_access),
) -> dict:
    """Run (or re-run) daily reconciliation. All shifts must be submitted first."""
    try:
        result = await rekonsiliasi_service.run_rekonsiliasi(
            db, spbu_id, tanggal, current_user.id
        )
    except (ValueError, PermissionError) as e:
        raise _service_error(e)
    return {"data": result.model_dump(), "message": "Rekonsiliasi harian berhasil dijalankan"}


@router.patch("/{tanggal}/approve", response_model=dict)
async def approve_rekonsiliasi(
    spbu_id: int,
    tanggal: date,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_spbu_access),
) -> dict:
    """Approve a pending reconciliation."""
    try:
        result = await rekonsiliasi_service.approve_rekonsiliasi(
            db, spbu_id, tanggal, current_user.id
        )
    except (ValueError, PermissionError) as e:
        raise _service_error(e)
    return {"data": result.model_dump(), "message": "Rekonsiliasi berhasil diapprove"}
