"""
POI Refresh Scheduler

Background scheduler for periodic POI context refresh.
Runs every hour to check for and execute pending POI refresh jobs.
"""

import asyncio
from typing import Optional
from datetime import datetime, timezone
import structlog

from app.services.poi_refresh_service import POIRefreshService

logger = structlog.get_logger()


class POIRefreshScheduler:
    """
    POI Refresh Scheduler

    Background task that periodically checks for and executes
    pending POI refresh jobs.
    """

    def __init__(
        self,
        poi_refresh_service: Optional[POIRefreshService] = None,
        check_interval_seconds: int = 3600,  # 1 hour
        max_concurrent_jobs: int = 5
    ):
        """
        Initialize POI refresh scheduler.

        Args:
            poi_refresh_service: POI refresh service instance
            check_interval_seconds: Seconds between checks (default: 3600 = 1 hour)
            max_concurrent_jobs: Max concurrent job executions (default: 5)
        """
        self.poi_refresh_service = poi_refresh_service or POIRefreshService()
        self.check_interval_seconds = check_interval_seconds
        self.max_concurrent_jobs = max_concurrent_jobs

        self._task: Optional[asyncio.Task] = None
        self._running = False

        logger.info(
            "POI Refresh Scheduler initialized",
            check_interval_seconds=check_interval_seconds,
            max_concurrent_jobs=max_concurrent_jobs
        )

    async def start(self):
        """Start the scheduler background task"""
        if self._running:
            logger.warning("POI Refresh Scheduler already running")
            return

        self._running = True
        self._task = asyncio.create_task(self._run_scheduler())

        logger.info("POI Refresh Scheduler started")

    async def stop(self):
        """Stop the scheduler background task"""
        if not self._running:
            return

        self._running = False

        if self._task:
            self._task.cancel()
            try:
                await self._task
            except asyncio.CancelledError:
                pass

        logger.info("POI Refresh Scheduler stopped")

    async def _run_scheduler(self):
        """Main scheduler loop"""
        logger.info("POI Refresh Scheduler loop started")

        while self._running:
            try:
                await self._process_cycle()
            except Exception as e:
                logger.error(
                    "POI refresh scheduler cycle failed",
                    error=str(e),
                    exc_info=True
                )

            # Wait for next cycle
            try:
                await asyncio.sleep(self.check_interval_seconds)
            except asyncio.CancelledError:
                break

        logger.info("POI Refresh Scheduler loop ended")

    async def _process_cycle(self):
        """Process one scheduler cycle"""
        cycle_start = datetime.now(timezone.utc)

        logger.debug(
            "POI refresh scheduler cycle started",
            timestamp=cycle_start.isoformat()
        )

        # Process pending jobs
        result = await self.poi_refresh_service.process_pending_jobs(
            max_concurrent=self.max_concurrent_jobs
        )

        cycle_end = datetime.now(timezone.utc)
        cycle_duration = (cycle_end - cycle_start).total_seconds()

        if result["total_jobs"] > 0:
            logger.info(
                "POI refresh scheduler cycle completed",
                total_jobs=result["total_jobs"],
                successful=result["successful"],
                failed=result["failed"],
                cycle_duration_seconds=cycle_duration
            )
        else:
            logger.debug(
                "POI refresh scheduler cycle completed (no jobs)",
                cycle_duration_seconds=cycle_duration
            )

    async def trigger_immediate_check(self):
        """Trigger an immediate check for pending jobs (bypasses schedule)"""
        logger.info("POI refresh scheduler immediate check triggered")

        try:
            result = await self.poi_refresh_service.process_pending_jobs(
                max_concurrent=self.max_concurrent_jobs
            )

            logger.info(
                "POI refresh scheduler immediate check completed",
                total_jobs=result["total_jobs"],
                successful=result["successful"],
                failed=result["failed"]
            )

            return result
        except Exception as e:
            logger.error(
                "POI refresh scheduler immediate check failed",
                error=str(e),
                exc_info=True
            )
            raise

    @property
    def is_running(self) -> bool:
        """Check if scheduler is running"""
        return self._running


# Global scheduler instance
_scheduler_instance: Optional[POIRefreshScheduler] = None


def get_scheduler() -> POIRefreshScheduler:
    """Get global scheduler instance (singleton)"""
    global _scheduler_instance

    if _scheduler_instance is None:
        _scheduler_instance = POIRefreshScheduler()

    return _scheduler_instance


async def start_scheduler():
    """Start global POI refresh scheduler"""
    scheduler = get_scheduler()
    await scheduler.start()


async def stop_scheduler():
    """Stop global POI refresh scheduler"""
    scheduler = get_scheduler()
    await scheduler.stop()
