#!/usr/bin/env python3
"""
Astra Cloud - Client Raspberry Pi
Capture depuis la caméra Pi et envoie les frames au serveur pour analyse.

Usage:
    python3 raspberry_client.py --server https://astra-cloud --key VOTRE_CLE_API

Dépendances:
    pip3 install opencv-python requests
"""

import argparse
import time
import sys
import os
import requests
import threading

try:
    import cv2
except ImportError:
    print("[ERREUR] OpenCV non installé. Lancez : pip3 install opencv-python")
    sys.exit(1)

# ─── Arguments ────────────────────────────────────────────────────────────────

parser = argparse.ArgumentParser(description="Astra Cloud - Client Raspberry Pi")
parser.add_argument("--server", default="http://localhost:5000", help="URL du serveur Astra Cloud")
parser.add_argument("--key", default="", help="Clé API (configurée dans les paramètres)")
parser.add_argument("--camera", type=int, default=0, help="Index de la caméra (défaut: 0)")
parser.add_argument("--interval", type=float, default=1.5, help="Intervalle entre chaque analyse (secondes)")
parser.add_argument("--resolution", default="640x480", help="Résolution caméra (WxH)")
parser.add_argument("--quality", type=int, default=75, help="Qualité JPEG 1-100")
args = parser.parse_args()

SERVER = args.server.rstrip("/")
API_KEY = args.key
CAMERA_INDEX = args.camera
INTERVAL = args.interval
QUALITY = args.quality

try:
    W, H = map(int, args.resolution.split("x"))
except Exception:
    W, H = 640, 480

print(f"""
╔═══════════════════════════════════════╗
║   Astra Cloud - Client Raspberry Pi  ║
╠═══════════════════════════════════════╣
║  Serveur  : {SERVER:<27}║
║  Caméra   : /dev/video{CAMERA_INDEX:<19}║
║  Résol.   : {W}x{H:<24}║
║  Intervalle: {INTERVAL}s{' '*(24-len(str(INTERVAL)))}║
╚═══════════════════════════════════════╝
""")

# ─── Caméra ───────────────────────────────────────────────────────────────────

cap = cv2.VideoCapture(CAMERA_INDEX)
if not cap.isOpened():
    print(f"[ERREUR] Impossible d'ouvrir la caméra {CAMERA_INDEX}")
    sys.exit(1)

cap.set(cv2.CAP_PROP_FRAME_WIDTH, W)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, H)
cap.set(cv2.CAP_PROP_FPS, 15)

print(f"[OK] Caméra ouverte ({int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))}x{int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))})")

# ─── Test connexion serveur ───────────────────────────────────────────────────

try:
    r = requests.get(f"{SERVER}/api/status", timeout=5)
    status = r.json()
    print(f"[OK] Serveur joignable - Face recognition: {'✓' if status.get('face_recognition') else '✗'}")
    print(f"     Personnes surveillées: {status.get('persons_count', 0)}")
except Exception as e:
    print(f"[ERREUR] Serveur inaccessible: {e}")
    print(f"         Vérifiez que le serveur tourne sur {SERVER}")
    sys.exit(1)

# ─── Statistiques ─────────────────────────────────────────────────────────────

stats = {
    "frames_sent": 0,
    "detections": 0,
    "errors": 0,
    "last_detection": None
}

def print_stats():
    while True:
        time.sleep(30)
        print(f"\n[Stats] Frames: {stats['frames_sent']} | Détections: {stats['detections']} | "
              f"Erreurs: {stats['errors']} | "
              f"Dernière: {stats['last_detection'] or 'jamais'}\n")

threading.Thread(target=print_stats, daemon=True).start()

# ─── Boucle principale ────────────────────────────────────────────────────────

print("\n[INFO] Surveillance démarrée. Ctrl+C pour arrêter.\n")

try:
    while True:
        ret, frame = cap.read()
        if not ret:
            print("[WARN] Échec lecture frame, retry...")
            time.sleep(0.5)
            continue
        
        # Encoder en JPEG
        encode_params = [cv2.IMWRITE_JPEG_QUALITY, QUALITY]
        success, buffer = cv2.imencode('.jpg', frame, encode_params)
        if not success:
            continue
        
        frame_bytes = buffer.tobytes()
        
        try:
            headers = {"Content-Type": "image/jpeg"}
            if API_KEY:
                headers["X-API-Key"] = API_KEY
            
            r = requests.post(
                f"{SERVER}/api/raspberry/frame",
                data=frame_bytes,
                headers=headers,
                timeout=5
            )
            
            if r.status_code == 200:
                data = r.json()
                stats["frames_sent"] += 1
                
                if data.get("count", 0) > 0:
                    stats["detections"] += data["count"]
                    from datetime import datetime
                    stats["last_detection"] = datetime.now().strftime("%H:%M:%S")
                    
                    for det in data.get("detections", []):
                        name = det.get("person_name", "Inconnu")
                        conf = int(det.get("confidence", 0) * 100)
                        print(f"[⚠ ALERTE] {name} détecté ({conf}% confiance)")
            
            elif r.status_code == 401:
                print("[ERREUR] Clé API invalide. Vérifiez la configuration.")
                sys.exit(1)
            else:
                stats["errors"] += 1
        
        except requests.exceptions.ConnectionError:
            stats["errors"] += 1
            print(f"[WARN] Connexion perdue, retry dans {INTERVAL}s...")
        
        except requests.exceptions.Timeout:
            stats["errors"] += 1
        
        time.sleep(INTERVAL)

except KeyboardInterrupt:
    print(f"\n[INFO] Arrêt. {stats['frames_sent']} frames envoyés, {stats['detections']} détections.")
finally:
    cap.release()
