"""Task: Clean up expired preview environments."""
from datetime import UTC, datetime
from pathlib import Path
from shutil import rmtree
from uuid import UUID

import structlog
from sqlalchemy import select

logger = structlog.get_logger()


async def cleanup_expired_previews(ctx: dict) -> dict:
    from src.core.database import async_session_factory
    from src.domain.previews.models import PreviewEnvironment

    db_factory = ctx.get("db_factory", async_session_factory)
    now = datetime.now(UTC)
    cleaned = 0

    async with db_factory() as db:
        result = await db.execute(
            select(PreviewEnvironment)
            .where(PreviewEnvironment.status == "running")
            .where(PreviewEnvironment.expires_at.isnot(None))
            .where(PreviewEnvironment.expires_at < now)
        )
        expired = result.scalars().all()

        for preview in expired:
            preview.status = "stopped"
            preview.stopped_at = now
            cleaned += 1

        await db.commit()

    logger.info("cleanup_expired_previews", cleaned=cleaned)
    return {"cleaned": cleaned}


async def cleanup_expired_guest_drafts(ctx: dict) -> dict:
    """Delete expired short-lived draft content from the temporary upload area."""
    from src.config import get_settings
    from src.core.database import async_session_factory
    from src.domain.guest_drafts.models import GuestDraft

    db_factory = ctx.get("db_factory", async_session_factory)
    now = datetime.now(UTC)
    draft_ids: list[UUID] = []

    async with db_factory() as db:
        result = await db.execute(
            select(GuestDraft.id).where(GuestDraft.expires_at <= now)
        )
        draft_ids = list(result.scalars().all())
        if draft_ids:
            expired = await db.execute(
                select(GuestDraft).where(GuestDraft.id.in_(draft_ids))
            )
            for draft in expired.scalars().all():
                await db.delete(draft)
            await db.commit()

    root = Path(get_settings().prompt_media_upload_root) / "guest-drafts"
    for draft_id in draft_ids:
        directory = root / str(draft_id)
        if directory.exists():
            rmtree(directory, ignore_errors=True)

    logger.info("cleanup_expired_guest_drafts", cleaned=len(draft_ids))
    return {"cleaned": len(draft_ids)}
