"""
Rai EPG Scraper — fetches schedule data from RaiPlay API.

Endpoint: https://www.raiplay.it/palinsesto/app/{channel_id}/{DD-MM-YYYY}.json
Returns events with: name, hour, duration_in_minutes, image, description
"""
import logging
from datetime import date, datetime, timedelta
from typing import List
from zoneinfo import ZoneInfo

from models import EPGEntry
import config
from scrapers.base_scraper import BaseScraper

logger = logging.getLogger(__name__)

ROME_TZ = ZoneInfo("Europe/Rome")


class RaiScraper(BaseScraper):

    def get_provider_name(self) -> str:
        return "rai"

    def get_channels(self) -> dict:
        return config.RAI_CHANNELS

    def fetch_channel_schedule(self, channel_id: str, channel_name: str,
                                target_date: date) -> List[EPGEntry]:
        entries = []
        for offset in [-1, 0]:
            d = target_date + timedelta(days=offset)
            date_str = d.strftime("%d-%m-%Y")
            url = config.RAI_BASE_URL.format(
                channel_id=channel_id, date=date_str
            )

            data = self._make_request(url)
            events = data.get("events", [])

            for event in events:
                try:
                    entry = self._parse_event(event, channel_name, d)
                    if entry:
                        entries.append(entry)
                except Exception as e:
                    logger.debug(
                        f"[rai] Errore parsing evento '{event.get('name', '?')}': {e}"
                    )
                    continue

        return entries

    def _parse_event(self, event: dict, channel_name: str,
                     target_date: date) -> EPGEntry | None:
        name = event.get("name")
        hour = event.get("hour")
        duration_str = event.get("duration_in_minutes", "")

        if not name or not hour:
            return None

        # Parse start time (format: "HH:MM")
        try:
            hour_parts = hour.split(":")
            start_dt = datetime(
                target_date.year, target_date.month, target_date.day,
                int(hour_parts[0]), int(hour_parts[1]),
                tzinfo=ROME_TZ
            )
        except (ValueError, IndexError):
            return None

        # Parse duration and calculate end time
        end_iso = ""
        duration = event.get("duration", "")
        if duration:
            # Duration format: "HH:MM:SS"
            try:
                parts = duration.split(":")
                total_minutes = int(parts[0]) * 60 + int(parts[1])
                if len(parts) > 2:
                    total_minutes += int(parts[2]) / 60
                end_dt = start_dt + timedelta(minutes=total_minutes)
                end_iso = end_dt.isoformat()
            except (ValueError, IndexError):
                pass

        # Build image URL
        image = event.get("image", "")
        if image and not image.startswith("http"):
            image = config.RAI_IMAGE_PREFIX + image

        # Description
        description = event.get("description", "").strip()

        # Category from dfp data
        category = ""
        dfp = event.get("dfp", {})
        if dfp:
            category = dfp.get("escaped_genre_name", "")
            if not category:
                category = dfp.get("escaped_typology_name", "")

        return EPGEntry(
            title=name,
            image=image,
            channel=channel_name,
            start=start_dt.isoformat(),
            end=end_iso,
            description=description,
            category=category,
        )
