from fastapi import APIRouter, Depends, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from typing import Optional, List
from pydantic import BaseModel
import logging

from ...db import get_session
from ...auth_core import get_current_account
from ...model_defs.l2a_models import L2APolicy, L2ASuggestion
from ...services.salesforce_gateway import SalesforceGateway, get_salesforce_gateway

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/v2/l2a", tags=["l2a"])


# Request model for L2A run
class L2ARunRequest(BaseModel):
    threshold_override: Optional[float] = None
    b2c_mode: Optional[str] = None
    b2c_whitelist: Optional[List[str]] = None


@router.post("/run")
async def run_l2a_clean():
    """Clean L2A run endpoint for testing."""
    return {"ok": True, "clean": True}


@router.get("/suggestions")
async def list_suggestions(
    page: int = 1,
    page_size: int = 50,
    status: Optional[str] = "pending",
    min_score: Optional[float] = Query(None, ge=0.0, le=1.0),
    tier: Optional[str] = None,
    expand: bool = True,
    db: AsyncSession = Depends(get_session),
    account_id: str = Depends(get_current_account),
    sf: Optional[SalesforceGateway] = Depends(get_salesforce_gateway),
):
    """List L2A suggestions with hydrated names from Salesforce."""
    pols = await db.execute(
        select(L2APolicy.id).where(
            L2APolicy.account_id == str(account_id),
            L2APolicy.status == "ACTIVE",
        )
    )
    pol_ids = [r[0] for r in pols.all()]
    if not pol_ids:
        return {"items": [], "total": 0, "page": page, "page_size": page_size}

    base = select(L2ASuggestion).where(L2ASuggestion.policy_id.in_(pol_ids))
    if status and status != "all":
        base = base.where(L2ASuggestion.status == status)
    if min_score is not None:
        base = base.where(L2ASuggestion.score >= min_score)
    if tier:
        base = base.where(L2ASuggestion.tier == tier)

    total = (
        await db.execute(select(func.count()).select_from(base.subquery()))
    ).scalar_one()
    q = (
        base.order_by(L2ASuggestion.score.desc())
        .offset((page - 1) * page_size)
        .limit(page_size)
    )
    res = await db.execute(q)
    rows = res.scalars().all()

    # Batch fetch Salesforce data for hydration
    lead_map = {}
    account_map = {}

    if expand and sf and rows:
        logger.info(f"Hydrating {len(rows)} L2A suggestions from Salesforce")
        # Collect unique IDs
        lead_ids = list(set(r.lead_id for r in rows if r.lead_id))
        account_ids = list(set(r.account_id for r in rows if r.account_id))

        # Batch fetch leads
        if lead_ids:
            try:
                lead_ids_clause = ",".join(f"'{lid}'" for lid in lead_ids[:200])
                lead_query = f"SELECT Id, Company, Email FROM Lead WHERE Id IN ({lead_ids_clause}) LIMIT 200"
                leads_result = await sf.soql(lead_query)
                if leads_result and leads_result.get("records"):
                    for lead in leads_result["records"]:
                        lead_map[lead["Id"]] = lead
            except Exception as e:
                logger.error(f"Could not batch fetch leads: {e}")

        # Batch fetch accounts
        if account_ids:
            try:
                account_ids_clause = ",".join(f"'{aid}'" for aid in account_ids[:200])
                account_query = f"SELECT Id, Name, Website FROM Account WHERE Id IN ({account_ids_clause}) LIMIT 200"
                accounts_result = await sf.soql(account_query)
                if accounts_result and accounts_result.get("records"):
                    for account in accounts_result["records"]:
                        account_map[account["Id"]] = account
            except Exception as e:
                logger.error(f"Could not batch fetch accounts: {e}")

    # Build items with hydrated names
    items = []
    for s in rows:
        lead = lead_map.get(s.lead_id, {})
        account = account_map.get(s.account_id, {})

        item = {
            "id": s.id,
            "lead_id": s.lead_id,
            "account_id": s.account_id,
            "lead_company": lead.get("Company") or f"Lead {s.lead_id[:10]}",
            "lead_email": lead.get("Email", ""),
            "account_name": account.get("Name") or f"Account {s.account_id[:10]}",
            "account_website": account.get("Website", ""),
            "score": s.score,
            "tier": s.tier,
            "reasons": s.reasons,
            "explanation": s.explanation,
            "field_score_details": s.field_score_details,
            "status": s.status,
            "created_at": s.created_at,
        }
        items.append(item)

    return {"items": items, "total": total, "page": page, "page_size": page_size}
