from typing import List

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel
from sqlalchemy.orm import Session

from src.infrastructure.database.connection import get_db
from src.infrastructure.repositories.sql_kw_capping_repository import SqlKWCappingRepository
from src.application.use_cases.kw_capping.list_kw_cappings import ListKWCappingsUseCase
from src.application.use_cases.kw_capping.update_kw_cappings import UpdateKWCappingsUseCase
from src.domain.entities.kw_capping import KWCappingRecord
from src.core.rbac.rbac_dependency import require_permission, get_current_user_payload
from src.core.rbac.permissions_registry import Perm
from src.core.exceptions import ValidationError

router = APIRouter()


# ── Schemas ────────────────────────────────────────────────────────────────────

class KWCappingResponse(BaseModel):
    id: int
    kw: int
    max_approved_value: int


class KWCappingUpdateItem(BaseModel):
    kw: int
    max_approved_value: int


class BulkUpdateKWCappingRequest(BaseModel):
    records: List[KWCappingUpdateItem]


# ── Endpoints ──────────────────────────────────────────────────────────────────

@router.get(
    "/",
    response_model=List[KWCappingResponse],
    tags=["kw-capping"],
    dependencies=[Depends(require_permission(Perm.MERCHANTS_VIEW))],
)
def list_kw_cappings(db: Session = Depends(get_db)):
    """List all KW capping tiers with their current max approved loan values."""
    repo = SqlKWCappingRepository(db)
    records = ListKWCappingsUseCase(repo).execute()
    return [KWCappingResponse(id=r.id, kw=r.kw, max_approved_value=r.max_approved_value)
            for r in records]


@router.put(
    "/",
    response_model=List[KWCappingResponse],
    tags=["kw-capping"],
    dependencies=[Depends(require_permission(Perm.MERCHANTS_EDIT))],
)
def update_kw_cappings(
    body: BulkUpdateKWCappingRequest,
    db: Session = Depends(get_db),
    payload: dict = Depends(get_current_user_payload),
):
    """Batch-update max_approved_value for one or more KW tiers.

    Only existing tiers can be updated. Unknown KW values are silently skipped.
    Mirrors Laravel's MerchantController::updateKWValues().
    """
    user_id: int = payload.get("user_id", 0)
    repo = SqlKWCappingRepository(db)
    updates = [
        KWCappingRecord(id=0, kw=item.kw, max_approved_value=item.max_approved_value)
        for item in body.records
    ]
    try:
        updated = UpdateKWCappingsUseCase(repo).execute(updates=updates, user_id=user_id)
    except ValidationError as exc:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(exc))

    return [KWCappingResponse(id=r.id, kw=r.kw, max_approved_value=r.max_approved_value)
            for r in updated]
