from datetime import datetime
from fastapi import APIRouter, Depends, Request, HTTPException, status
from sqlalchemy.orm import Session
from app.models.database import get_db
from app.models.client import Client
from app.security.dependencies import get_jwt_client
from app.security.rate_limit import limiter
from app.services.mt940_parser import MT940Parser
from app.services.reconciliation import parse_ledger_csv, reconcile as run_reconciliation
from app.schemas.api import ReconcileRequest, ReconcileResponse

router = APIRouter(tags=["reconciliation"])
_parser = MT940Parser()


@router.post("/reconcile", response_model=ReconcileResponse)
@limiter.limit("30/minute")
def reconcile(
    request: Request,
    body: ReconcileRequest,
    db: Session = Depends(get_db),
    client: Client = Depends(get_jwt_client),
):
    if client.credits_remaining is not None:
        if client.credits_expire_at and datetime.utcnow() > client.credits_expire_at:
            raise HTTPException(
                status_code=status.HTTP_402_PAYMENT_REQUIRED,
                detail="Tu paquete de conversiones venció. Solicita uno nuevo.",
            )
        if client.credits_remaining <= 0:
            raise HTTPException(
                status_code=status.HTTP_402_PAYMENT_REQUIRED,
                detail="No te quedan conversiones disponibles en tu paquete. Solicita uno nuevo.",
            )

    if body.format not in ("MT940", "MT950"):
        raise HTTPException(
            status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
            detail=f"Formato no soportado: {body.format}. Use MT940 o MT950",
        )

    try:
        parsed = _parser.parse(body.mt940_message)
    except ValueError as e:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(e))

    bank_txs = []
    for tx in parsed["transactions"]:
        signed = tx["amount"] if tx["dc_indicator"] == "CRDT" else -tx["amount"]
        bank_txs.append({**tx, "signed_amount": signed})

    try:
        ledger_entries = parse_ledger_csv(body.ledger_csv)
    except ValueError as e:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(e))

    result = run_reconciliation(bank_txs, ledger_entries, tolerance_days=body.tolerance_days)

    if client.credits_remaining is not None:
        client.credits_remaining -= 1
        db.commit()

    return result
