"""
Enrichment archive API endpoints.

Provides history, export, and download capabilities for enriched data.
"""

import csv
import io
import logging
import os
from datetime import datetime
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import and_, select
from sqlalchemy.ext.asyncio import AsyncSession
from starlette.responses import StreamingResponse

from ...auth_core import require_org_context
from ...db import get_session
from ...model_defs.enrichment_vault import EnrichmentVault
from ...models import EnrichmentUsage

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/enrichment", tags=["enrichment-archive"])


@router.get("/history")
async def get_enrichment_history(
    from_ts: Optional[datetime] = Query(None, description="Start timestamp (UTC)"),
    to_ts: Optional[datetime] = Query(None, description="End timestamp (UTC)"),
    object_type: Optional[str] = Query(
        None, description="SFDC object type (Lead, Contact, Account)"
    ),
    user_email: Optional[str] = Query(None, description="Filter by user email"),
    page: int = Query(1, ge=1, description="Page number"),
    page_size: int = Query(50, ge=1, le=500, description="Records per page"),
    org=Depends(require_org_context),
    db: AsyncSession = Depends(get_session),
):
    """
    Get enrichment history for the authenticated account.

    Returns paginated list of enrichment usage records with archival status.
    """
    where_clauses = [EnrichmentUsage.account_id == org.account_id]

    if from_ts:
        where_clauses.append(EnrichmentUsage.created_at >= from_ts)
    if to_ts:
        where_clauses.append(EnrichmentUsage.created_at < to_ts)
    if object_type:
        where_clauses.append(EnrichmentUsage.sfdc_object == object_type)
    if user_email:
        where_clauses.append(EnrichmentUsage.user_email == user_email)

    q = (
        select(EnrichmentUsage)
        .where(and_(*where_clauses))
        .order_by(EnrichmentUsage.created_at.desc())
        .offset((page - 1) * page_size)
        .limit(page_size)
    )

    result = await db.execute(q)
    rows = result.scalars().all()

    # Serialize to JSON
    return [
        {
            "id": r.id,
            "created_at": r.created_at.isoformat() if r.created_at else None,
            "sfdc_object": r.sfdc_object,
            "user_email": r.user_email,
            "credits_debited": r.credits_debited,
            "provider": r.provider,
            "has_archived_data": r.has_archived_data,
            "job_id": r.job_id,
            "records_scanned": r.records_scanned,
            "matches_found": r.matches_found,
            "records_written": r.records_written,
            "fields_updated": r.fields_updated,
            "cost_usd": float(r.cost_usd) if r.cost_usd else 0.0,
            "price_usd": float(r.price_usd) if r.price_usd else 0.0,
        }
        for r in rows
    ]


@router.post("/{usage_id}/export.csv")
async def export_enrichment_csv(
    usage_id: int,
    org=Depends(require_org_context),
    db: AsyncSession = Depends(get_session),
):
    """
    Export enrichment vault data for a specific usage_id as CSV.

    Returns a streaming CSV with field-level before/after values.
    """
    # Verify usage belongs to this account
    usage = await db.get(EnrichmentUsage, usage_id)
    if not usage or usage.account_id != org.account_id:
        raise HTTPException(status_code=404, detail="Enrichment usage not found")

    if not usage.has_archived_data:
        raise HTTPException(
            status_code=404,
            detail="No archived data available for this enrichment. Archival may have been disabled.",
        )

    # Belt & suspenders: enforce account_id on vault rows too
    q = (
        select(EnrichmentVault)
        .where(
            EnrichmentVault.usage_id == usage_id,
            EnrichmentVault.account_id == org.account_id,
        )
        .order_by(EnrichmentVault.created_at.asc())
    )

    result = await db.execute(q)
    rows = result.scalars().all()

    if not rows:
        raise HTTPException(
            status_code=404, detail="No vault data found for this enrichment"
        )

    # Get SFDC instance URL from env (for clickable links)
    sfdc_base_url = os.getenv("SALESFORCE_INSTANCE_URL", "https://login.salesforce.com")

    def iter_csv():
        """Stream CSV rows."""
        buf = io.StringIO()
        w = csv.writer(buf)

        # Write header
        w.writerow(
            [
                "created_at",
                "sfdc_object",
                "sfdc_record_id",
                "sfdc_record_url",
                "field_name",
                "value_before",
                "value_after",
                "provider_confidence",
            ]
        )
        yield buf.getvalue()
        buf.seek(0)
        buf.truncate(0)

        # Write data rows
        for r in rows:
            # Build clickable SFDC URL
            record_url = ""
            if r.sfdc_object in ("Lead", "Contact", "Account", "Opportunity", "Case"):
                record_url = f"{sfdc_base_url}/{r.sfdc_record_id}"

            w.writerow(
                [
                    r.created_at.isoformat() if r.created_at else "",
                    r.sfdc_object,
                    r.sfdc_record_id,
                    record_url,
                    r.field_name,
                    r.value_before or "",
                    r.value_after,
                    r.provider_confidence or "",
                ]
            )
            yield buf.getvalue()
            buf.seek(0)
            buf.truncate(0)

    filename = f"enrichment_usage_{usage_id}.csv"
    return StreamingResponse(
        iter_csv(),
        media_type="text/csv",
        headers={"Content-Disposition": f'attachment; filename="{filename}"'},
    )
