"""
ARQ Background Worker for INDELIS.

Replaces Celery+RabbitMQ with ARQ (async Redis queue).
ARQ is fully async and uses Redis — no separate message broker needed.

Run worker:
    arq src.worker.arq_app.WorkerSettings
"""
import logging
from typing import Any

from src.core.config import settings

logger = logging.getLogger(__name__)


# ── Task Definitions ──────────────────────────────────────────────────────────

async def send_welcome_email(ctx: dict, tenant_id: str, admin_email: str, subdomain: str):
    """Send welcome email after tenant signup."""
    logger.info(f"[email] Sending welcome email to {admin_email} for tenant {subdomain}")
    # TODO: Integrate AWS SES
    # ses_client = boto3.client("ses", region_name=settings.AWS_REGION)
    # ses_client.send_email(...)
    return {"status": "sent", "email": admin_email}


async def send_invoice_reminder(ctx: dict, invoice_id: str, tenant_id: str, days_overdue: int):
    """Send overdue invoice reminder email."""
    logger.info(f"[email] Sending {days_overdue}d reminder for invoice {invoice_id}")
    # TODO: Integrate SES + email template
    return {"status": "sent", "invoice_id": invoice_id}


async def generate_qr_code(ctx: dict, tenant_id: str, entity_type: str, entity_id: str, target_url: str):
    """Generate QR code PNG and upload to S3."""
    logger.info(f"[qr] Generating QR for {entity_type}:{entity_id}")
    try:
        import qrcode
        from io import BytesIO
        qr = qrcode.QRCode(version=1, box_size=10, border=4)
        qr.add_data(target_url)
        qr.make(fit=True)
        img = qr.make_image(fill_color="black", back_color="white")
        buf = BytesIO()
        img.save(buf, format="PNG")
        buf.seek(0)
        # TODO: Upload buf to S3 → settings.S3_BUCKET / tenant/{tenant_id}/qrcodes/{entity_id}.png
        logger.info(f"[qr] QR code generated for {entity_id}")
        return {"status": "generated", "entity_id": entity_id}
    except Exception as e:
        logger.error(f"[qr] Failed to generate QR: {e}")
        raise


async def check_overdue_invoices(ctx: dict):
    """Scheduled job: find overdue invoices and queue reminder emails."""
    logger.info("[scheduler] Checking overdue invoices")
    from datetime import date
    from src.database.session import AsyncSessionLocal
    from sqlalchemy import select, and_
    from sqlalchemy.ext.asyncio import AsyncSession

    async with AsyncSessionLocal() as db:
        from src.apps.billing.models.invoice import Invoice
        today = date.today()
        result = await db.execute(
            select(Invoice).where(
                and_(
                    Invoice.status.in_(["outstanding", "partial"]),
                    Invoice.due_date < today,
                    Invoice.reminder_count < 3,
                )
            )
        )
        invoices = result.scalars().all()

        for invoice in invoices:
            days_overdue = (today - invoice.due_date).days
            if days_overdue in (7, 14, 30):
                await ctx["redis"].enqueue_job(
                    "send_invoice_reminder",
                    str(invoice.id),
                    str(invoice.tenant_id),
                    days_overdue,
                )

    logger.info(f"[scheduler] Processed {len(invoices)} overdue invoices")


async def startup(ctx: dict):
    logger.info("ARQ worker started")


async def shutdown(ctx: dict):
    logger.info("ARQ worker stopped")


# ── Worker Settings ───────────────────────────────────────────────────────────

class WorkerSettings:
    functions = [
        send_welcome_email,
        send_invoice_reminder,
        generate_qr_code,
        check_overdue_invoices,
    ]
    on_startup = startup
    on_shutdown = shutdown
    redis_settings_from_url = settings.REDIS_URL
    max_jobs = 10
    job_timeout = 300  # 5 min
    keep_result = 3600  # 1 hour

    # Scheduled jobs (cron)
    cron_jobs = [
        # check_overdue_invoices runs daily at 08:00 UTC
        # arq.cron(check_overdue_invoices, hour=8, minute=0)
    ]
