"""Campaign logs and audit log endpoints: send attempts, events, errors with filters,
CSV export, per-recipient history. Combined logs view for the Logs page."""
import csv
import io
from datetime import datetime, timezone

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

from app.api.deps import get_current_user, get_db
from app.models import AuditLog, Campaign, CampaignRecipient, EmailEvent, SendAttempt, User

router = APIRouter(prefix="/logs", tags=["logs"])


def _ser_attempt(a: SendAttempt) -> dict:
    return {
        "id": a.id,
        "campaign_id": a.campaign_id,
        "campaign_recipient_id": a.campaign_recipient_id,
        "account_id": a.gmail_account_id,
        "attempt_number": a.attempt_number,
        "outcome": a.outcome,
        "error_class": a.error_class,
        "error_message": (a.error_message or "")[:300],
        "message_id": a.message_id,
        "provider_response": (a.provider_response or "")[:300],
        "created_at": a.created_at.isoformat() if a.created_at else None,
    }


@router.get("/list")
async def list_logs(campaign_id: int = Query(0),
                    outcome: str = Query("", description="submitted|accepted|temp_failed|perm_failed|skipped"),
                    search: str = Query("", description="email or message id fragment"),
                    page: int = Query(1, ge=1),
                    page_size: int = Query(50, ge=1, le=200),
                    db: AsyncSession = Depends(get_db),
                    user: User = Depends(get_current_user)):
    """Unified send log: SendAttempt rows joined with CampaignRecipient for context."""
    q = (select(SendAttempt, CampaignRecipient)
         .join(CampaignRecipient, SendAttempt.campaign_recipient_id == CampaignRecipient.id)
         .join(Campaign, Campaign.id == SendAttempt.campaign_id)
         .where(Campaign.user_id == user.id))
    if campaign_id:
        q = q.where(SendAttempt.campaign_id == campaign_id)
    if outcome:
        q = q.where(SendAttempt.outcome == outcome)
    if search:
        like = f"%{search}%"
        q = q.where(or_(CampaignRecipient.email.ilike(like),
                        SendAttempt.message_id.ilike(like)))
    total = (await db.execute(
        select(func.count()).select_from(q.subquery()))).scalar() or 0
    rows = (await db.execute(
        q.order_by(SendAttempt.id.desc()).offset((page - 1) * page_size).limit(page_size)
    )).all()
    out = []
    for a, cr in rows:
        d = _ser_attempt(a)
        d["email"] = cr.email
        d["recipient_status"] = cr.status
        out.append(d)
    return {"logs": out, "total": total, "page": page, "page_size": page_size}


@router.get("/events")
async def list_events(campaign_id: int = Query(0),
                      event_type: str = Query(""),
                      page: int = Query(1, ge=1),
                      page_size: int = Query(50, ge=1, le=200),
                      db: AsyncSession = Depends(get_db),
                      user: User = Depends(get_current_user)):
    q = (select(EmailEvent, CampaignRecipient)
         .join(CampaignRecipient, EmailEvent.campaign_recipient_id == CampaignRecipient.id)
         .join(Campaign, Campaign.id == EmailEvent.campaign_id)
         .where(Campaign.user_id == user.id))
    if campaign_id:
