import { useState, useEffect, useCallback, useRef } from "react";
import type { StreamStatus, Channel } from "./types";
import * as api from "./api/client";
import Player from "./components/Player";
import StatusBar from "./components/StatusBar";
import AdminPanel from "./components/AdminPanel";
import ChannelList from "./components/ChannelList";
import "./App.css";

// Detect touch-primary devices (phones/tablets have no hover pointer).
const isTouchPrimary = () =>
  window.matchMedia("(pointer: coarse)").matches || navigator.maxTouchPoints > 0;

const HIDE_DELAY = 3000; // ms of inactivity before toggle hides again

export default function App() {
  const [status, setStatus] = useState<StreamStatus | null>(null);
  const [channels, setChannels] = useState<Channel[]>([]);
  const [sidebarOpen, setSidebarOpen] = useState(false);
  const [toggleVisible, setToggleVisible] = useState(false);
  const hideTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

  const fetchStatus = useCallback(async () => {
    try {
      const s = await api.getStatus();
      setStatus(s);
    } catch {
      // backend unreachable
    }
  }, []);

  const fetchChannels = useCallback(async () => {
    try {
      const ch = await api.getChannels();
      setChannels(ch);
    } catch {
      // backend unreachable
    }
  }, []);

  useEffect(() => {
    fetchStatus();
    fetchChannels();
    // Poll faster while live so passive viewers detect channel switches promptly.
    // Transitioning gets the fastest rate so the UI clears quickly after a switch.
    const rate = status?.transitioning ? 1000 : status?.live ? 2000 : 5000;
    const interval = setInterval(fetchStatus, rate);
    return () => clearInterval(interval);
  }, [fetchStatus, fetchChannels, status?.live, status?.transitioning]);

  useEffect(() => {
    if (status?.playlist_version) {
      fetchChannels();
    }
  }, [fetchChannels, status?.playlist_version]);

  // Show the toggle button on interaction, then auto-hide after HIDE_DELAY.
  // When the sidebar is open we keep it visible so the user can close it.
  const showToggle = useCallback(() => {
    setToggleVisible(true);
    if (hideTimer.current) clearTimeout(hideTimer.current);
    if (!sidebarOpen) {
      hideTimer.current = setTimeout(() => setToggleVisible(false), HIDE_DELAY);
    }
  }, [sidebarOpen]);

  // Keep toggle visible while sidebar is open; restart timer when it closes.
  useEffect(() => {
    if (sidebarOpen) {
      if (hideTimer.current) clearTimeout(hideTimer.current);
      setToggleVisible(true);
    } else {
      hideTimer.current = setTimeout(() => setToggleVisible(false), HIDE_DELAY);
    }
    return () => {
      if (hideTimer.current) clearTimeout(hideTimer.current);
    };
  }, [sidebarOpen]);

  // Wire up interaction listeners on the document.
  useEffect(() => {
    const touch = isTouchPrimary();
    if (touch) {
      document.addEventListener("touchstart", showToggle, { passive: true });
      return () => document.removeEventListener("touchstart", showToggle);
    } else {
      document.addEventListener("mousemove", showToggle);
      return () => document.removeEventListener("mousemove", showToggle);
    }
  }, [showToggle]);

  const handlePlaylistReloaded = () => {
    fetchChannels();
  };

  const handleChannelRefresh = () => {
    fetchStatus();
  };

  return (
    <div className="app">
      {/* Fullscreen video background */}
      <div className="stage">
        <Player
          live={status?.live ?? false}
          streamKey={status?.channel_name ?? "offline"}
        />
      </div>

      {/* Collapsible right sidebar */}
      <button
        className={`sidebar-toggle ${sidebarOpen ? "open" : ""} ${toggleVisible ? "visible" : ""}`}
        onClick={() => setSidebarOpen((v) => !v)}
        aria-label={sidebarOpen ? "Collapse panel" : "Open panel"}
        title={sidebarOpen ? "Collapse panel" : "Open panel"}
      >
        {sidebarOpen ? "›" : "‹"}
      </button>

      <aside className={`sidebar ${sidebarOpen ? "open" : "collapsed"}`}>
        <div className="sidebar-inner">
          <AdminPanel onPlaylistReloaded={handlePlaylistReloaded} />
          <ChannelList
          channels={channels}
          activeChannel={status?.channel_name ?? ""}
          playlistVersion={status?.playlist_version ?? 0}
          onRefresh={handleChannelRefresh}
        />
        </div>
      </aside>

      {/* Status banner fixed to the bottom */}
      <StatusBar status={status} />
    </div>
  );
}
