"""
Dispute Scheduler for automatic dispute resolution after 24 hours.
"""
import asyncio
from datetime import datetime, timedelta
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload

from app.models import Dispute, DisputeStatus, Assignment, AssignmentStatus
from app.services.disputes import dispute_service


# Configuration
CHECK_INTERVAL_SECONDS = 300  # Check every 5 minutes
DISPUTE_WINDOW_HOURS = 24  # Disputes auto-resolve after 24 hours


class DisputeScheduler:
    """Background scheduler for automatic dispute resolution."""

    def __init__(self):
        self._running = False
        self._task: asyncio.Task | None = None

    async def start(self, session_factory) -> None:
        """Start the scheduler background task."""
        if self._running:
            return

        self._running = True
        self._task = asyncio.create_task(self._run_loop(session_factory))
        print("[DisputeScheduler] Started")

    async def stop(self) -> None:
        """Stop the scheduler."""
        self._running = False
        if self._task:
            self._task.cancel()
            try:
                await self._task
            except asyncio.CancelledError:
                pass
        print("[DisputeScheduler] Stopped")

    async def _run_loop(self, session_factory) -> None:
        """Main scheduler loop."""
        while self._running:
            try:
                async with session_factory() as db:
                    await self._process_expired_disputes(db)
            except Exception as e:
                print(f"[DisputeScheduler] Error in loop: {e}")

            await asyncio.sleep(CHECK_INTERVAL_SECONDS)

    async def _process_expired_disputes(self, db: AsyncSession) -> None:
        """Process and resolve expired disputes."""
        cutoff_time = datetime.utcnow() - timedelta(hours=DISPUTE_WINDOW_HOURS)

        # Find all open disputes that have expired
        result = await db.execute(
            select(Dispute)
            .options(
                selectinload(Dispute.votes),
                selectinload(Dispute.assignment).selectinload(Assignment.participant),
            )
            .where(
                Dispute.status == DisputeStatus.OPEN.value,
                Dispute.created_at < cutoff_time,
            )
        )
        expired_disputes = result.scalars().all()

        for dispute in expired_disputes:
            try:
                result_status, votes_valid, votes_invalid = await dispute_service.resolve_dispute(
                    db, dispute.id
                )
                print(
                    f"[DisputeScheduler] Auto-resolved dispute {dispute.id}: "
                    f"{result_status} (valid: {votes_valid}, invalid: {votes_invalid})"
                )
            except Exception as e:
                print(f"[DisputeScheduler] Failed to resolve dispute {dispute.id}: {e}")


# Global scheduler instance
dispute_scheduler = DisputeScheduler()
