"""
ABOS AI Worker – Finance statement pre-checks
================================================
Bank-profile-match and duplicate-statement checks for the AI bank/credit-card statement
extraction flow (app/routes.py::extract_data). This worker never touches a database directly
(see app/abos_api_client.py's docstring) — both checks call back into abos-api's own
/api/finance/ai-processing/entity-match and /statement-duplicate endpoints, forwarding the same
JWT Spring Boot forwarded to us (ExtractRequest.spring_boot_auth_token), exactly the auth model
app/mcp_tools.py already uses for its tool calls.

Both functions fail soft: a missing token or a failed call logs a warning and returns None rather
than raising, so a broken/unavailable check never blocks the extraction result itself — this is a
review-time UX enhancement, not a hard gate. The human reviewing the extracted data always makes
the final call either way.
"""

from __future__ import annotations

import logging
from typing import Optional

from app.abos_api_client import AbosApiError, call_abos_api
from app.schemas import DuplicateStatementResult, EntityMatchResult, EntityType

logger = logging.getLogger(__name__)


async def check_entity_match(
    *, auth_token: Optional[str], entity_type: EntityType, account_number: Optional[str]
) -> Optional[EntityMatchResult]:
    """Does a bank/credit-card profile already exist for this account number?"""
    if not auth_token or not account_number:
        return None
    try:
        body = await call_abos_api(
            method="GET",
            path="/api/finance/ai-processing/entity-match",
            auth_token=auth_token,
            params={"entityType": entity_type.value, "accountNumber": account_number},
        )
    except AbosApiError as exc:
        logger.warning("entity-match check failed, continuing without it: %s", exc.message)
        return None
    if not body:
        return None
    return EntityMatchResult.model_validate(body)


async def check_duplicate_statement(
    *, auth_token: Optional[str], entity_id: Optional[int], statement_period: Optional[str]
) -> Optional[DuplicateStatementResult]:
    """Has a statement already been imported for this entity + statement period?"""
    if not auth_token or not entity_id or not statement_period:
        return None
    try:
        body = await call_abos_api(
            method="GET",
            path="/api/finance/ai-processing/statement-duplicate",
            auth_token=auth_token,
            params={"entityId": entity_id, "statementPeriod": statement_period},
        )
    except AbosApiError as exc:
        logger.warning("statement-duplicate check failed, continuing without it: %s", exc.message)
        return None
    if not body:
        return None
    return DuplicateStatementResult.model_validate(body)


async def fetch_entity_guidance(
    *, auth_token: Optional[str], entity_id: Optional[int]
) -> Optional[str]:
    """Staff-curated guidance text for this entity (from a 'marked' reference statement), used to
    steer this extraction's prompt. Only applies when entity_id is already known up front (i.e.
    uploading a new statement against an existing account) — a brand-new account's first-ever
    extraction has nothing to fetch yet, which is expected."""
    if not auth_token or not entity_id:
        return None
    try:
        body = await call_abos_api(
            method="GET",
            path="/api/finance/ai-processing/entity-guidance",
            auth_token=auth_token,
            params={"entityId": entity_id},
        )
    except AbosApiError as exc:
        logger.warning("entity-guidance fetch failed, continuing without it: %s", exc.message)
        return None
    if not body:
        return None
    return body.get("guidanceText")


async def set_entity_guidance(
    *, auth_token: Optional[str], entity_id: int, guidance_text: str
) -> None:
    """Persists guidance text extracted from a staff-uploaded 'marked' reference statement onto
    the entity, so later extractions for the same account can use it. Fails soft — a failed save
    is logged, not raised, since this is a reference-quality-of-life feature, not core to saving
    the reference PDF itself (the attachment upload, which owns the actual failure/success signal
    the caller sees, happens separately)."""
    if not auth_token:
        return
    try:
        await call_abos_api(
            method="PUT",
            path="/api/finance/ai-processing/entity-guidance",
            auth_token=auth_token,
            json_body={"entityId": entity_id, "guidanceText": guidance_text},
        )
    except AbosApiError as exc:
        logger.warning("entity-guidance save failed for entity_id=%s: %s", entity_id, exc.message)
