        from_email=account.email,
        to_email=str(payload.to_email),
        subject=subject,
        html_body=res_html,
        text_body=res_text,
        attachments=attachments,
        unsubscribe_url=unsub_url,
    )

    # REAL send in a worker thread with a sync DB session (token refresh writes)
    def _real_send():
        with SyncSession() as s:
            acc = s.get(GmailAccount, account.id)
            token = s.query(OAuthToken).filter_by(account_id=account.id).first()
            if not token:
                return {"ok": False, "error": "No OAuth token stored for this account",
                        "error_class": "auth"}
            client = build_gmail_client_from_account(acc, token)
            if client.method == "smtp":
                return client.send_mime_smtp(mime)
            return client.send_mime_api(mime)

    try:
        result = await asyncio.get_event_loop().run_in_executor(None, _real_send)
    except Exception as e:
        await log_audit(db, user.id, "test_send.error", "gmail_account", account.id,
                        {"error": str(e)[:200]})
        return {"ok": False, "stage": "temp_failed", "detail": str(e)[:400],
                "error_class": "unknown", "elapsed_ms": int((time.monotonic() - t0) * 1000)}

    elapsed = int((time.monotonic() - t0) * 1000)
    if result.get("ok"):
        await log_audit(db, user.id, "test_send.success", "gmail_account", account.id,
                        {"to": str(payload.to_email), "message_id": result.get("message_id")})
        return {"ok": True, "stage": "accepted", "detail": "Gmail accepted the message",
                "message_id": result.get("message_id"),
                "thread_id": result.get("thread_id"),
                "method": client_method(account),
                "provider_response": _clip(str(result.get("raw_response", ""))),
                "elapsed_ms": elapsed}
    # provider refused — surface the REAL error, never fake success
    err = str(result.get("error", "") or result.get("detail", ""))
    await log_audit(db, user.id, "test_send.failed", "gmail_account", account.id,
                    {"to": str(payload.to_email), "error": err[:200]})
    return {"ok": False, "stage": "perm_failed", "detail": err[:400],
            "error_class": result.get("error_class", "unknown"),
            "method": client_method(account),
            "provider_response": _clip(str(result.get("raw_response", ""))),
            "elapsed_ms": elapsed}


def _clip(s: str) -> str:
    return s[:300]


def client_method(account: GmailAccount) -> str:
    return account.sending_method or "api"


@router.get("/accounts")
async def test_accounts(db: AsyncSession = Depends(get_db),
                        user: User = Depends(get_current_user)):
    """Authorized accounts available for test sends."""
    rows = (await db.execute(
        select(GmailAccount).where(GmailAccount.user_id == user.id,
                                   GmailAccount.status == "authorized",
====
"""Send Test Email: REAL send through a connected Gmail account with provider-confirmed
results (message ID from Gmail), full variable substitution and optional attachments.
This is the compliance-friendly way to verify end-to-end delivery before a campaign."""
import asyncio
import base64
from datetime import datetime, timezone
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, EmailStr, Field
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_current_user, get_db, require_csrf
from app.core.config import settings as cfg
from app.core.security import log_audit
from app.models import EmailTemplate, GmailAccount, OAuthToken, User
from app.services import message_builder
from app.services.campaign_engine import get_setting
from app.services.gmail_service import build_gmail_client_from_account
from app.services.variable_engine import GeneratedValues, VariableEngine
from app.db.session import SyncSession

router = APIRouter(prefix="/test-send", tags=["test-send"])


class TestSendIn(BaseModel):
    account_id: int
    to_email: EmailStr
    subject: str = Field(min_length=1, max_length=500)
    template_id: Optional[int] = None
    body_html: str = ""
    body_text: str = ""
    include_pdf: bool = False
    use_random_variables: bool = True


@router.post("/send")
async def send_test(payload: TestSendIn, db: AsyncSession = Depends(get_db),
                    user: User = Depends(get_current_user),
