"""
ABOS AI Worker – Mail Reference Classifier Router
==================================================
Backend-facing only, called by MailAiClassificationScheduler for mail
MailClassificationService's rule-based pass couldn't place with a Contact (no exact sender-email
match, but not internal/vendor/social/announcement/password-reset either — a genuinely ambiguous
"could be a customer/collaborator" message). This service never touches a database: Spring Boot
assembles the tenant's open Leads/Deals shortlist and hands it over, this endpoint only reasons
over that list via OpenRouter and returns candidate matches (possibly none) for a human to
approve — same "Java gathers, Python reasons" shape as SiteChatRequest.contextText.
"""

from __future__ import annotations

import logging

from fastapi import APIRouter, HTTPException, status

from app.llm_client import call_openrouter
from app.schemas import ClassifyEmailReferenceRequest, ClassifyEmailReferenceResponse, EmailReferenceMatch

logger = logging.getLogger(__name__)

email_classifier_router = APIRouter()

_PROMPT = (
    "You are matching an incoming email to a CRM Lead or Deal it might belong to, based only on "
    "the sender, subject, and body snippet given below plus a shortlist of candidate Leads/Deals. "
    "Respond with ONLY a JSON object of this exact shape:\n"
    "{\n"
    "  \"matches\": [\n"
    "    {\"candidateId\": 123, \"candidateType\": \"LEAD\", \"confidence\": \"HIGH\", "
    "\"reasoning\": \"one short sentence\"}\n"
    "  ]\n"
    "}\n"
    "Only include a candidate if there is a real, specific textual signal connecting the email to "
    "it (a matching name, company, or clear context) — do not guess. If nothing in the candidate "
    "list plausibly matches, return {\"matches\": []}. confidence must be HIGH, MEDIUM, or LOW."
)


@email_classifier_router.post(
    "/email/classify-reference",
    response_model=ClassifyEmailReferenceResponse,
    status_code=status.HTTP_200_OK,
    summary="Suggest which Lead/Deal (if any) an otherwise-unmatched email belongs to",
    tags=["Backend-Facing"],
)
async def classify_reference(request: ClassifyEmailReferenceRequest) -> ClassifyEmailReferenceResponse:
    if not request.candidates:
        return ClassifyEmailReferenceResponse(matches=[])

    candidate_lines = "\n".join(
        f"- id={c.id}, type={c.type}, label=\"{c.label}\"" for c in request.candidates
    )
    document_text = (
        f"From: {request.from_address or '(unknown)'}\n"
        f"Subject: {request.subject or '(no subject)'}\n"
        f"Body:\n{request.body_snippet or '(empty)'}\n\n"
        f"Candidate Leads/Deals:\n{candidate_lines}"
    )

    try:
        data, model_used = await call_openrouter(
            openrouter_key=request.openrouter_key,
            prompt=_PROMPT,
            document_text=document_text,
            model=request.model,
        )
    except Exception as exc:
        logger.error("Mail reference classification failed: %s", exc)
        raise HTTPException(
            status_code=status.HTTP_502_BAD_GATEWAY,
            detail=f"Mail reference classification failed: {exc}",
        ) from exc

    raw_matches = data.get("matches") or []
    matches: list[EmailReferenceMatch] = []
    valid_ids = {c.id for c in request.candidates}
    for m in raw_matches:
        try:
            candidate_id = int(m.get("candidateId"))
        except (TypeError, ValueError):
            continue
        if candidate_id not in valid_ids:
            continue  # never trust an id the LLM invented outside the shortlist we gave it
        matches.append(EmailReferenceMatch(
            candidate_id=candidate_id,
            candidate_type=str(m.get("candidateType", "")),
            confidence=str(m.get("confidence", "LOW")),
            reasoning=str(m.get("reasoning", "")),
        ))

    return ClassifyEmailReferenceResponse(matches=matches, model_used=model_used)
