"""
Fee Settlement Router — 7 admin endpoints.
All routes require superuser auth and are mounted under /admin.
"""
import logging
from datetime import date
from typing import Literal, Optional

from fastapi import APIRouter, Depends, Query, Request, status
from fastapi import HTTPException
from sqlalchemy.orm import Session

from src.apps.admin.models.admin_audit_log import AdminAuditLog
from src.apps.auth.utils.auth import get_current_superuser, require_not_impersonation
from src.apps.fee_settlement.crud import (
    get_active_settlement_account,
    get_settlement_account_by_id,
    get_settlement_account_history,
    get_settlement_run_by_id,
    get_settlement_run_transactions,
    get_settlement_runs,
)
from src.apps.fee_settlement.schemas.settlement_account import (
    SettlementAccountCreate,
    SettlementAccountListResponse,
    SettlementAccountResponse,
)
from src.apps.fee_settlement.schemas.settlement_run import (
    FeeSettlementRunListResponse,
    FeeSettlementRunResponse,
    SettlementRunTransactionItem,
    SettlementRunTransactionList,
)
from src.apps.fee_settlement.services import (
    create_settlement_account,
    delete_settlement_account,
)
from src.core.database import get_db

logger = logging.getLogger(__name__)

router = APIRouter()


# ─── Settlement Account endpoints ────────────────────────────────────────────

@router.get("/settlement-account", tags=["ADMIN_SETTLEMENT"])
def get_active_account(
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_db),
):
    """Return the currently active settlement account, or null if none."""
    account = get_active_settlement_account(db)
    if not account:
        return None
    return SettlementAccountResponse.model_validate(account)


@router.get("/settlement-account/history", tags=["ADMIN_SETTLEMENT"])
def get_account_history(
    page: int = Query(1, ge=1),
    per_page: int = Query(20, ge=1, le=100),
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_db),
):
    """Return paginated history of all settlement accounts (active and superseded)."""
    items, total = get_settlement_account_history(db, page=page, per_page=per_page)
    return SettlementAccountListResponse(
        items=[SettlementAccountResponse.model_validate(a) for a in items],
        total=total,
    )


@router.post(
    "/settlement-account",
    status_code=status.HTTP_201_CREATED,
    tags=["ADMIN_SETTLEMENT"],
    dependencies=[Depends(require_not_impersonation)],
)
def save_settlement_account(
    request: Request,
    payload: SettlementAccountCreate,
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_db),
):
    """
    Create a new settlement account and make it the active one.
    Any previously active account is deactivated atomically.
    """
    account, deactivated = create_settlement_account(
        db=db,
        data=payload,
        created_by_user_id=current_user.id,
    )
    ip = request.client.host if request.client else None
    # Audit: log each deactivated account (deactivated is a list of plain dicts)
    for old_acct in deactivated:
        AdminAuditLog.log(
            db,
            admin_user_id=current_user.id,
            action="settlement_account.deactivated",
            target_type="hw_platform_bank_account",
            target_id=old_acct["id"],
            metadata={"nickname": old_acct["nickname"], "reason": "replaced_by_new"},
            ip_address=ip,
        )
    # Audit: log new account creation
    AdminAuditLog.log(
        db,
        admin_user_id=current_user.id,
        action="settlement_account.created",
        target_type="hw_platform_bank_account",
        target_id=account.id,
        metadata={
            "nickname": account.nickname,
            "account_number_last4": account.account_number_last4,
        },
        ip_address=ip,
    )
    db.commit()
    return SettlementAccountResponse.model_validate(account)


@router.delete(
    "/settlement-account/{account_id}",
    status_code=status.HTTP_204_NO_CONTENT,
    tags=["ADMIN_SETTLEMENT"],
    dependencies=[Depends(require_not_impersonation)],
)
def remove_settlement_account(
    account_id: int,
    request: Request,
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_db),
):
    """Soft-delete a settlement account by ID."""
    account = get_settlement_account_by_id(db, account_id)
    if not account:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Settlement account not found")
    nickname = account.nickname
    last4 = account.account_number_last4
    delete_settlement_account(db=db, account_id=account_id)
    AdminAuditLog.log(
        db,
        admin_user_id=current_user.id,
        action="settlement_account.deleted",
        target_type="hw_platform_bank_account",
        target_id=account_id,
        metadata={"nickname": nickname, "account_number_last4": last4},
        ip_address=request.client.host if request.client else None,
    )
    return None


# ─── Settlement Run endpoints ─────────────────────────────────────────────────

@router.get("/fee-settlements", tags=["ADMIN_SETTLEMENT"])
def list_settlement_runs(
    page: int = Query(1, ge=1),
    per_page: int = Query(20, ge=1, le=100),
    status_filter: Optional[Literal["pending", "processing", "settled", "failed", "skipped"]] = Query(None, alias="status"),
    date_from: Optional[date] = Query(None),
    date_to: Optional[date] = Query(None),
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_db),
):
    """List fee settlement runs with optional date/status filters."""
    items, total = get_settlement_runs(
        db,
        page=page,
        per_page=per_page,
        status=status_filter,
        date_from=date_from,
        date_to=date_to,
    )
    return FeeSettlementRunListResponse(
        items=[FeeSettlementRunResponse.model_validate(r) for r in items],
        total=total,
        page=page,
        per_page=per_page,
    )


@router.get("/fee-settlements/{run_id}", tags=["ADMIN_SETTLEMENT"])
def get_settlement_run_detail(
    run_id: int,
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_db),
):
    """Return detailed info for a single settlement run."""
    run = get_settlement_run_by_id(db, run_id)
    if not run:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Settlement run not found")
    return FeeSettlementRunResponse.model_validate(run)


@router.get("/fee-settlements/{run_id}/transactions", tags=["ADMIN_SETTLEMENT"])
def list_run_transactions(
    run_id: int,
    page: int = Query(1, ge=1),
    per_page: int = Query(50, ge=1, le=200),
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_db),
):
    """List transactions included in a specific settlement run."""
    run = get_settlement_run_by_id(db, run_id)
    if not run:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Settlement run not found")

    txns, total = get_settlement_run_transactions(db, run_id=run_id, page=page, per_page=per_page)

    items = []
    for txn in txns:
        merchant_name = txn.merchant.name if txn.merchant else None
        items.append(
            SettlementRunTransactionItem(
                id=txn.id,
                txn_literal=txn.txn_literal,
                merchant_id=txn.merchant_id,
                merchant_name=merchant_name,
                txn_amount=float(txn.txn_amount) / 100 if txn.txn_amount is not None else None,
                platform_fee_amount=float(txn.platform_fee_amount) if txn.platform_fee_amount is not None else None,
                occurred_at=txn.ocurred_at,
            )
        )

    return SettlementRunTransactionList(
        items=items,
        total=total,
        page=page,
        per_page=per_page,
    )
