import { useEffect, useState } from "react";

import { LayerStack } from "./components/LayerStack";
import { StackPresetToolbar } from "./components/StackPresetToolbar";
import { StatusPanels } from "./components/StatusPanels";
import { useRuntimeState } from "./hooks/useRuntimeState";

function App() {
  const [appState, setAppState] = useRuntimeState();
  const [pendingShaderId, setPendingShaderId] = useState("");
  const [presetName, setPresetName] = useState("");
  const [selectedPresetName, setSelectedPresetName] = useState("");
  const [expandedLayerIds, setExpandedLayerIds] = useState([]);
  const [dragLayerId, setDragLayerId] = useState(null);
  const [dropTargetLayerId, setDropTargetLayerId] = useState(null);

  const layers = appState?.layers ?? [];
  const shaders = appState?.shaders ?? [];
  const performance = appState?.performance ?? {};
  const runtime = appState?.runtime ?? {};
  const video = appState?.video ?? {};
  const app = appState?.app ?? {};
  const stackPresets = appState?.stackPresets ?? [];

  useEffect(() => {
    if (!pendingShaderId && shaders.length > 0) {
      setPendingShaderId(shaders[0].id);
    } else if (pendingShaderId && !shaders.some((shader) => shader.id === pendingShaderId)) {
      setPendingShaderId(shaders[0]?.id ?? "");
    }
  }, [pendingShaderId, shaders]);

  useEffect(() => {
    if (!selectedPresetName && stackPresets.length > 0) {
      setSelectedPresetName(stackPresets[0]);
    } else if (selectedPresetName && !stackPresets.includes(selectedPresetName)) {
      setSelectedPresetName(stackPresets[0] ?? "");
    }
  }, [selectedPresetName, stackPresets]);

  useEffect(() => {
    const layerIds = new Set(layers.map((layer) => layer.id));
    setExpandedLayerIds((current) => current.filter((layerId) => layerIds.has(layerId)));
  }, [layers]);

  if (!appState) {
    return (
      <main className="layout">
        <section className="panel">
          <h3>Loading</h3>
          <p className="muted">Waiting for control state from the native host.</p>
          <div className="progress-track" aria-hidden="true">
            <div className="progress-bar is-indeterminate" />
          </div>
        </section>
      </main>
    );
  }

  return (
    <main className="layout">
      <header className="app-header">
        <div>
          <h2>Video Shader Toys</h2>
          <p className="muted">Live shader stack, DeckLink status, and runtime controls.</p>
        </div>
        <div className={`status-pill${runtime.compileSucceeded ? " status-pill--ready" : " status-pill--error"}`}>
          {runtime.compileSucceeded ? "Ready" : "Compile Error"}
        </div>
      </header>

      <section className="panel app-summary" aria-label="Runtime summary">
        <dl className="summary-grid">
          <div className="summary-item">
            <dt>Shaders</dt>
            <dd>{shaders.length}</dd>
          </div>
          <div className="summary-item">
            <dt>Layers</dt>
            <dd>{layers.length}</dd>
          </div>
          <div className="summary-item">
            <dt>Signal</dt>
            <dd>{video.hasSignal ? "Present" : "Missing"}</dd>
          </div>
          <div className="summary-item">
            <dt>Render</dt>
            <dd>{Number(performance.renderMs ?? 0).toFixed(2)} ms</dd>
          </div>
        </dl>
      </section>

      <section className="dashboard-grid">
        <StatusPanels app={app} performance={performance} runtime={runtime} video={video} />
        <StackPresetToolbar
          presetName={presetName}
          selectedPresetName={selectedPresetName}
          stackPresets={stackPresets}
          onPresetNameChange={setPresetName}
          onSelectedPresetNameChange={setSelectedPresetName}
        />
      </section>

      <LayerStack
        dragLayerId={dragLayerId}
        dropTargetLayerId={dropTargetLayerId}
        expandedLayerIds={expandedLayerIds}
        layers={layers}
        pendingShaderId={pendingShaderId}
        setAppState={setAppState}
        setDragLayerId={setDragLayerId}
        setDropTargetLayerId={setDropTargetLayerId}
        setExpandedLayerIds={setExpandedLayerIds}
        setPendingShaderId={setPendingShaderId}
        shaders={shaders}
      />
    </main>
  );
}

export default App;
