import { useEffect, useRef, useCallback } from 'react';
import { useSentinelStore } from '@/store/sentinelStore';
import { useAuthStore } from '@/store/authStore';

/**
 * useSentinelWebSocket
 * Connects to the Sentinel WebSocket endpoint on core-api.
 * Translates raw CCTV events into store actions.
 * The broker-facing UI NEVER sees: WebSocket status, connection state,
 *   raw event types, MediaPipe processing info, or frame IDs.
 *
 * Events handled:
 *   visitor_detected   → setPendingAlert (triggers SentinelAlertBanner)
 *   session_start      → setShowroomActive(true)
 *   qd_update          → update session QD score
 *   session_end        → setShowroomActive(false)
 *   ai_observation     → update session AI observation text
 */

interface RawSentinelEvent {
  type: 'visitor_detected' | 'session_start' | 'qd_update' | 'session_end' | 'ai_observation';
  session_id?: string;
  qd_score?: number;
  qd_trend?: number;
  zone?: string;
  matched_person_id?: string;
  matched_name?: string;
  face_confidence?: number;
  ai_observation?: string;
  peak_qd?: number;
}

interface LiveSession {
  sessionId: string;
  qdScore: number;
  qdTrend: number;
  currentZone?: string;
  aiObservation?: string;
  peakQd?: number;
}

export function useSentinelWebSocket() {
  const wsRef = useRef<WebSocket | null>(null);
  const sessionRef = useRef<LiveSession | null>(null);
  const { token } = useAuthStore.getState();
  const {
    setPendingAlert,
    setShowroomActive,
    setSessionDuration,
    setHasInsights,
  } = useSentinelStore();

  const connect = useCallback(() => {
    // wss:// on velocity.local, proxied by Traefik → core-api
    const wsUrl = `wss://${window.location.host}/ws/sentinel?token=${token}`;
    const ws = new WebSocket(wsUrl);
    wsRef.current = ws;

    ws.onmessage = (evt) => {
      let event: RawSentinelEvent;
      try { event = JSON.parse(evt.data); }
      catch { return; }

      switch (event.type) {
        case 'visitor_detected':
          setPendingAlert({
            id:             String(Date.now()),
            matchedName:    event.matched_name,
            matchedPersonId:event.matched_person_id,
            confidence:     event.face_confidence,
            zone:           event.zone ?? 'Entrance',
            timestamp:      new Date(),
          });
          break;

        case 'session_start':
          sessionRef.current = {
            sessionId: event.session_id!,
            qdScore:   0,
            qdTrend:   0,
          };
          setShowroomActive(true, event.session_id);
          break;

        case 'qd_update':
          if (sessionRef.current) {
            sessionRef.current = {
              ...sessionRef.current,
              qdScore:  event.qd_score ?? 0,
              qdTrend:  event.qd_trend ?? 0,
              currentZone: event.zone,
              peakQd: Math.max(sessionRef.current.peakQd ?? 0, event.qd_score ?? 0),
            };
          }
          break;

        case 'ai_observation':
          if (sessionRef.current) {
            sessionRef.current = {
              ...sessionRef.current,
              aiObservation: event.ai_observation,
            };
            setHasInsights(true);
          }
          break;

        case 'session_end':
          setShowroomActive(false);
          break;
      }
    };

    ws.onerror = () => { /* silent — broker never sees connection errors */ };
    ws.onclose = (e) => {
      if (e.code !== 1000) {
        // Reconnect after 3s on unexpected disconnect
        setTimeout(connect, 3000);
      }
    };
  }, [token, setPendingAlert, setShowroomActive, setHasInsights]);

  useEffect(() => {
    connect();
    return () => { wsRef.current?.close(1000, 'component unmount'); };
  }, [connect]);

  return { session: sessionRef.current };
}
