import { useState, useCallback, useEffect, useRef } from "react";
import type { Persona, Affect, ChatMessage, LatencyLog } from "./types";
import { resetSession, checkHealth } from "./lib/api";
import { useWebcam } from "./hooks/useWebcam";
import { useSensing } from "./hooks/useSensing";
import { PersonaSelector } from "./components/PersonaSelector";
import { ChatPanel } from "./components/ChatPanel";
import { WebcamSensing } from "./components/WebcamSensing";
import { SensingStatus } from "./components/SensingStatus";
import { LatencyMetrics } from "./components/LatencyMetrics";
import "./App.css";

function App() {
  const [persona, setPersona] = useState<Persona | null>(null);
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [latency, setLatency] = useState<LatencyLog | null>(null);
  const [webcamEnabled, setWebcamEnabled] = useState(false);
  const [affectOverride, setAffectOverride] = useState<Affect | null>(null);
  const [backendReady, setBackendReady] = useState(false);
  const healthPoll = useRef<ReturnType<typeof setInterval>>(undefined);

  useEffect(() => {
    async function poll() {
      const ready = await checkHealth();
      if (ready) {
        setBackendReady(true);
        clearInterval(healthPoll.current);
      }
    }
    poll();
    healthPoll.current = setInterval(poll, 2000);
    return () => clearInterval(healthPoll.current);
  }, []);

  const {
    sensing,
    ready,
    initError,
    init,
    processFrame,
    clearAirWrittenText,
    clearHeadSignal,
    resetCalibration,
  } = useSensing();

  const onFrame = useCallback(
    (video: HTMLVideoElement, timestamp: number) => {
      processFrame(video, timestamp);
    },
    [processFrame]
  );

  const { videoRef, active, error } = useWebcam({
    enabled: webcamEnabled && ready,
    onFrame,
  });

  async function handleWebcamToggle() {
    if (!webcamEnabled) {
      const ok = await init();
      if (ok) setWebcamEnabled(true);
    } else {
      setWebcamEnabled(false);
      resetCalibration();
    }
  }

  async function handlePersonaSelect(p: Persona) {
    setPersona(p);
    setMessages([]);
    setLatency(null);
    try {
      await resetSession(p.id);
    } catch {
      // Session reset failed — non-critical, continue with fresh UI state
    }
  }

  return (
    <div className="app-layout">
      <aside className="sidebar">
        <h1 className="app-title">
          <img src="/favicon.svg" alt="" className="app-logo" />
          AAC Chatbot
        </h1>

        <PersonaSelector
          selected={persona?.id ?? null}
          onSelect={handlePersonaSelect}
        />

        <div className="sidebar-section">
          <label className="toggle-label">
            <input
              type="checkbox"
              checked={webcamEnabled}
              onChange={handleWebcamToggle}
            />
            Enable webcam
          </label>
          <WebcamSensing videoRef={videoRef} active={active} error={error || initError} />
          <SensingStatus sensing={sensing} webcamActive={active} />
        </div>

        <div className="sidebar-section">
          <label htmlFor="affect-override">Affect override</label>
          <select
            id="affect-override"
            value={affectOverride ?? "auto"}
            onChange={(e) =>
              setAffectOverride(
                e.target.value === "auto" ? null : (e.target.value as Affect)
              )
            }
          >
            <option value="auto">Auto (webcam)</option>
            <option value="HAPPY">HAPPY</option>
            <option value="FRUSTRATED">FRUSTRATED</option>
            <option value="NEUTRAL">NEUTRAL</option>
            <option value="SURPRISED">SURPRISED</option>
          </select>
        </div>

        <LatencyMetrics latency={latency} />
      </aside>

      <main className="main-content">
        <ChatPanel
          userId={persona?.id ?? null}
          personaName={persona?.name ?? ""}
          sensing={sensing}
          affectOverride={affectOverride}
          onAirTextConsumed={clearAirWrittenText}
          onHeadSignalConsumed={clearHeadSignal}
          messages={messages}
          setMessages={setMessages}
          onLatency={setLatency}
          backendReady={backendReady}
        />
      </main>

    </div>
  );
}

export default App;
