"""
Demon de verification des rappels.
Tourne en arriere-plan et dispatche les notifications
vers le bon fournisseur (Telegram, Gmail ou Discord).
"""
import sys
import time
import logging
from datetime import datetime, timedelta
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent))

from alerte_sms.config import (
    load_events, save_events, load_config,
    load_telegram_config, load_gmail_config, load_discord_config,
    CONFIG_DIR,
)
from alerte_sms.providers import send_telegram, send_gmail, send_discord

LOG_FILE = CONFIG_DIR / "scheduler.log"
CONFIG_DIR.mkdir(parents=True, exist_ok=True)

logging.basicConfig(
    filename=str(LOG_FILE),
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
)
logger = logging.getLogger(__name__)

CHECK_INTERVAL = 60

FREQUENCY_DELTAS = {
    "1 semaine avant": timedelta(weeks=1),
    "3 jours avant":   timedelta(days=3),
    "1 jour avant":    timedelta(days=1),
    "12h avant":       timedelta(hours=12),
    "1 heure avant":   timedelta(hours=1),
    "Le jour meme":    timedelta(hours=0),
}


def should_send(event: dict, now: datetime) -> bool:
    try:
        event_dt = datetime.fromisoformat(event["event_date"])
        delta = FREQUENCY_DELTAS.get(event["frequency"])
        if delta is None:
            return False
        reminder_time = event_dt - delta
        return abs(now - reminder_time) <= timedelta(minutes=5)
    except (KeyError, ValueError) as e:
        logger.warning(f"Evenement invalide ignore: {e}")
        return False


def build_message(event: dict) -> str:
    event_dt = datetime.fromisoformat(event["event_date"])
    return (
        f"Rappel : {event['name']}\n"
        f"Date : {event_dt.strftime('%d/%m/%Y a %H:%M')}\n"
        f"Ce rappel : {event['frequency']}\n"
        f"-- alerte-event"
    )


def dispatch(config: dict, event: dict, message: str):
    provider = config.get("provider")

    if provider == "telegram":
        cfg = load_telegram_config()
        results = send_telegram(cfg["token"], cfg["chat_ids"], message)
        logger.info(f"Telegram: {sum(results.values())}/{len(results)} envoyes")

    elif provider == "gmail":
        cfg = load_gmail_config()
        results = send_gmail(
            cfg["address"], cfg["app_password"],
            event["recipients"],
            subject=f"Rappel : {event['name']}",
            message=message,
        )
        logger.info(f"Gmail: {sum(results.values())}/{len(results)} envoyes")

    elif provider == "discord":
        cfg = load_discord_config()
        results = send_discord(cfg["webhook_urls"], message)
        logger.info(f"Discord: {sum(results.values())}/{len(results)} envoyes")

    else:
        logger.warning(f"Fournisseur inconnu: {provider}")


def check_and_send(config: dict, events: list, now: datetime) -> list:
    updated = []
    for event in events:
        if not event.get("sent") and should_send(event, now):
            logger.info(f"Envoi rappel : {event['name']}")
            dispatch(config, event, build_message(event))
            event["sent"] = True
            event["sent_at"] = now.isoformat()
        updated.append(event)
    return updated


def run():
    logger.info("=== Scheduler alerte-sms demarre ===")
    print("Scheduler demarre. Log :", LOG_FILE)

    while True:
        try:
            config = load_config()
            if not config.get("provider"):
                logger.warning("Aucun fournisseur configure.")
            else:
                events = load_events()
                now = datetime.now()
                updated = check_and_send(config, events, now)
                if updated != events:
                    save_events(updated)
        except Exception as e:
            logger.error(f"Erreur boucle principale: {e}")
        time.sleep(CHECK_INTERVAL)


if __name__ == "__main__":
    run()
