"""Batch-flush script execution live state from Redis to MySQL (every 60s, up to 50 rows/cycle)."""

import asyncio
import logging

from server.domain.models import AuditLog
from server.infrastructure.database.audit_log_repo import AuditLogRepositoryImpl
from server.infrastructure.database.script_repo import ScriptExecutionRepositoryImpl
from server.infrastructure.database.session import AsyncSessionLocal
from server.infrastructure.redis.script_execution_store import (
    FLUSH_INTERVAL_SECONDS,
    detect_stuck_executions,
    flush_pending_batch,
)

logger = logging.getLogger("nexus.script_execution_flush")


async def script_execution_flush_loop():
    """Every minute: flush queued script execution snapshots to MySQL."""
    logger.info("Script execution flush loop started (interval=%ss)", FLUSH_INTERVAL_SECONDS)
    while True:
        await asyncio.sleep(FLUSH_INTERVAL_SECONDS)
        try:
            async with AsyncSessionLocal() as session:
                repo = ScriptExecutionRepositoryImpl(session)
                audit_repo = AuditLogRepositoryImpl(session)

                async def _audit(action, target_type, target_id, operator, _repo=audit_repo):  # noqa: B023
                    await _repo.create(AuditLog(
                        admin_username=operator or "system",
                        action=action,
                        target_type=target_type,
                        target_id=target_id,
                        detail=f"执行ID={target_id}",
                    ))

                stuck = await detect_stuck_executions(repo, _audit)
                count = await flush_pending_batch(repo)
            if stuck:
                logger.info("Script execution: auto-marked %s stuck", stuck)
            if count:
                logger.info("Script execution flush: %s record(s) written to MySQL", count)
        except Exception as e:
            logger.error("Script execution flush loop error: %s", e)
