"""邮件异步任务（Celery）"""
import asyncio
from app.celery_app import celery_app


@celery_app.task(
    bind=True,
    name="email.send_email",
    max_retries=3,
    default_retry_delay=60,
    acks_late=True,
)
def send_email_task(
    self,
    *,
    to: str,
    subject: str,
    html_body: str,
    text_body: str | None = None,
    smtp_config: dict,
    attachments: list | None = None,
):
    """直接发送邮件（不依赖模板）的异步任务。"""
    try:
        asyncio.run(_async_send_email(
            to=to,
            subject=subject,
            html_body=html_body,
            text_body=text_body,
            smtp_config=smtp_config,
            attachments=attachments,
        ))
    except Exception as exc:
        raise self.retry(exc=exc)


async def _async_send_email(to, subject, html_body, text_body, smtp_config, attachments):
    from app.services.email import send_email
    await send_email(
        to=to, subject=subject, html_body=html_body,
        text_body=text_body, smtp_config=smtp_config,
        attachments=attachments,
    )


@celery_app.task(
    bind=True,
    name="email.send_notification",
    max_retries=3,
    default_retry_delay=60,   # 失败后 60s 重试
    acks_late=True,
)
def send_notification_task(
    self,
    *,
    tenant_id: int,
    template_key: str,
    to_email: str,
    variables: dict,
    smtp_config: dict,
    customer_language: str | None = None,
):
    """在独立 worker 进程里发送邮件（含 PDF 生成），与主进程完全内存隔离。"""
    try:
        asyncio.run(_async_send(
            tenant_id=tenant_id,
            template_key=template_key,
            to_email=to_email,
            variables=variables,
            smtp_config=smtp_config,
            customer_language=customer_language,
        ))
    except Exception as exc:
        raise self.retry(exc=exc)


async def _async_send(
    tenant_id: int,
    template_key: str,
    to_email: str,
    variables: dict,
    smtp_config: dict,
    customer_language: str | None,
):
    from app.database import AsyncSessionLocal
    from app.services.email import send_notification

    async with AsyncSessionLocal() as db:
        try:
            await send_notification(
                db=db,
                tenant_id=tenant_id,
                template_key=template_key,
                to_email=to_email,
                variables=variables,
                smtp_config=smtp_config,
                customer_language=customer_language,
            )
            await db.commit()
        except Exception:
            await db.rollback()
            raise
