#!/usr/bin/env python3
"""
SmartEye SENTINEL - Watchdog d'Alertes
========================================
Script cron qui tourne toutes les minutes.
Vérifie les alertes non acquittées et les renvoie avec escalade.

Crontab :
  * * * * * /usr/bin/python3 /var/www/lucas/alert_watchdog.py >> /var/log/smarteye_watchdog.log 2>&1

Auteur : Unigest Solutions / SmartEye V30
"""

import json
import sys
import os
import uuid
from datetime import datetime, timedelta

# Ajouter le chemin du projet
sys.path.insert(0, '/var/www/lucas')

from alert_manager import (
    get_alertes_pending,
    enregistrer_envoi,
    mettre_a_jour_statut,
    nettoyer_alertes_obsoletes,
    AlertStatus
)

# Firebase
import firebase_admin
from firebase_admin import credentials, messaging

# --- CONFIGURATION ---
TOKEN_TELEPHONE = "fheHxyPRQlS7T0hDnKIpeR:APA91bFPd7v3zO0GqU7pW3X-IfODgnfIUOFUoM4M1_CsCNNE5BSLVSIrCpXqL_xNNNBWdUFE4A4SCNs9_LWUQn8s7mVaw2gnQxhveC1SOc9E0gRiQW1Ct84"
DOMAIN = "https://lucas.unigest.fr"

# --- INITIALISATION FIREBASE ---
if not firebase_admin._apps:
    try:
        cred = credentials.Certificate("/var/www/lucas/admin_key.json")
        firebase_admin.initialize_app(cred)
    except Exception as e:
        print(f"[WATCHDOG] Erreur Firebase init: {e}")
        sys.exit(1)


def envoyer_rappel(alerte_info):
    """
    Envoie une notification de rappel avec le niveau d'escalade approprié.
    Le message change selon l'urgence croissante.
    """
    alert_id = alerte_info["alert_id"]
    alerte = alerte_info["alerte"]
    level = alerte_info["escalation_level"]
    priority = alerte_info["priority"]
    count = alerte_info["notification_count"]
    age = alerte_info["age_seconds"]
    
    image_path = alerte.get("image_path", "")
    url_image = f"{DOMAIN}/{image_path}" if image_path else ""
    
    # Messages d'escalade progressifs
    messages_escalade = {
        0: {"title": "⚠️ RAPPEL ALERTE CHUTE", 
            "body": f"Alerte non vue depuis {age // 60} min — Appuyez pour voir"},
        1: {"title": "🔴 ALERTE CHUTE NON TRAITÉE", 
            "body": f"URGENT : Personne potentiellement au sol depuis {age // 60} min !"},
        2: {"title": "🚨 ALERTE CRITIQUE NON TRAITÉE", 
            "body": f"Aucune réponse depuis {age // 60} min — Intervention nécessaire !"},
        3: {"title": "🆘 ALERTE MAXIMALE", 
            "body": f"SANS RÉPONSE DEPUIS {age // 60} MIN — Vérifiez immédiatement !"},
        4: {"title": "🆘 DERNIÈRE TENTATIVE", 
            "body": f"Alerte ignorée depuis {age // 60} min — Escalade en cours"},
    }
    
    msg_data = messages_escalade.get(level, messages_escalade[4])
    
    now = datetime.now()
    
    try:
        message = messaging.Message(
            notification=messaging.Notification(
                title=msg_data["title"],
                body=msg_data["body"],
            ),
            android=messaging.AndroidConfig(
                priority='high',
                notification=messaging.AndroidNotification(
                    channel_id='fall_alert_channel',
                    priority='max' if level >= 2 else 'high',
                    default_sound=True,
                    default_vibrate_timings=True,
                    visibility='public',
                ),
                # TTL court pour forcer la livraison rapide
                ttl=timedelta(seconds=60),
            ),
            data={
                "urgence": "true",
                "type": "chute_rappel",
                "alert_id": alert_id,
                "escalation_level": str(level),
                "escalation_label": alerte_info["escalation_label"],
                "notification_count": str(count + 1),
                "original_time": alerte.get("created_at", ""),
                "age_minutes": str(age // 60),
                "senior_name": "Mamie Lucas",
                "senior_photo_url": f"{DOMAIN}/photos/mamie.jpg",
                "image_url": url_image,
                "camera_id": alerte.get("camera_id", ""),
                "audio_relay_ws": alerte.get("audio_relay_ws", "ws://57.128.74.87:8800"),
                "camera_ip_map": alerte.get("camera_ip_map", "{}"),
                "is_reminder": "true",
                "click_action": "FLUTTER_NOTIFICATION_CLICK",
            },
            token=TOKEN_TELEPHONE,
        )
        
        response = messaging.send(message)
        
        # Enregistrer l'envoi
        enregistrer_envoi(alert_id, level)
        
        print(f"[WATCHDOG] ✅ Rappel envoyé — Alerte {alert_id[:8]}... "
              f"| Niveau {level} | Envoi #{count + 1} | Âge {age // 60}min "
              f"| Firebase: {response}")
        
        return True
        
    except messaging.UnregisteredError:
        # Token invalide — le téléphone a été réinitialisé ou l'app désinstallée
        print(f"[WATCHDOG] ❌ Token Firebase invalide ! L'app est peut-être désinstallée.")
        # TODO: Escalader vers SMS ou contact secondaire
        return False
        
    except Exception as e:
        print(f"[WATCHDOG] ❌ Erreur envoi rappel {alert_id[:8]}...: {e}")
        return False


def run_watchdog():
    """Boucle principale du watchdog"""
    now = datetime.now()

    # Nettoyage des alertes obsolètes (SEEN > 4h, ACKNOWLEDGED > 2h)
    cleaned = nettoyer_alertes_obsoletes()
    if cleaned > 0:
        print(f"[WATCHDOG] 🧹 {cleaned} alerte(s) obsolète(s) nettoyée(s)")

    # Récupérer les alertes qui nécessitent un renvoi
    alertes_a_renvoyer = get_alertes_pending()
    
    if not alertes_a_renvoyer:
        # Silencieux si rien à faire (le cron tourne chaque minute)
        return
    
    print(f"\n[WATCHDOG] === {now.strftime('%Y-%m-%d %H:%M:%S')} === "
          f"{len(alertes_a_renvoyer)} alerte(s) à renvoyer")
    
    for alerte_info in alertes_a_renvoyer:
        envoyer_rappel(alerte_info)
    
    print(f"[WATCHDOG] --- Fin du cycle ---\n")


if __name__ == "__main__":
    run_watchdog()