import json
import os
import tempfile
from pathlib import Path
from datetime import datetime, timezone

def validar(epg):
    if not isinstance(epg, dict):
        return False

    response = epg.get("response")
    if not isinstance(response, dict):
        return False

    sections = ("games", "prevGames", "nextGames")

    if not all(
        isinstance(response.get(k), list)
        for k in sections
    ):
        return False

    return any(response[k] for k in sections)

def guardar(epg, ruta):
    if not validar(epg):
        return False

    p = Path(ruta)
    registro = {
        "received_at": datetime.now(timezone.utc).isoformat(),
        "epg": epg
    }

    fd, temporal = tempfile.mkstemp(
        prefix=p.name + ".",
        dir=str(p.parent)
    )

    try:
        with os.fdopen(fd, "w", encoding="utf-8") as f:
            json.dump(registro, f, ensure_ascii=False)
            f.flush()
            os.fsync(f.fileno())

        os.replace(temporal, str(p))
    finally:
        if os.path.exists(temporal):
            os.unlink(temporal)

    return True

def cargar(ruta):
    p = Path(ruta)

    if not p.exists():
        return None

    try:
        registro = json.loads(p.read_text(encoding="utf-8"))
        if not validar(registro.get("epg")):
            return None
        return registro
    except (OSError, ValueError, TypeError):
        return None


def cargar_vigente(ruta, max_edad_segundos=300):
    registro = cargar(ruta)

    if registro is None:
        return None

    try:
        recibido = datetime.fromisoformat(
            registro["received_at"]
        )

        if recibido.tzinfo is None:
            return None

        edad = (
            datetime.now(timezone.utc) - recibido
        ).total_seconds()

        if edad < 0 or edad > max_edad_segundos:
            return None

        return registro

    except (ValueError, TypeError, KeyError):
        return None
