import { useCallback, useRef } from "react";
import { MdOndemandVideo } from "react-icons/md";
import { createLogger } from "../logger";
import { liveConnectionStore } from "../state/liveConnectionStore";
import { usePlaybackActions, useRecording } from "./RecordingProvider";
import styles from "./LoadDemoButton.module.css";

const log = createLogger("LoadDemoButton");

export function LoadDemoButton({
  isActive = false,
  choosingMap = false,
  onCancelChoosingMap,
}: {
  isActive?: boolean;
  choosingMap?: boolean;
  onCancelChoosingMap?: () => void;
}) {
  const recording = useRecording();
  const isDemoLoaded = recording?.source === "demo";
  const { setRecording } = usePlaybackActions();
  const inputRef = useRef<HTMLInputElement>(null);
  const parseTokenRef = useRef(0);

  const handleClick = useCallback(() => {
    if (choosingMap && isDemoLoaded) {
      onCancelChoosingMap?.();
      return;
    }
    if (isDemoLoaded) {
      // Unload the recording/parser but leave entities frozen in the store.
      parseTokenRef.current += 1;
      setRecording(null);
      return;
    }
    inputRef.current?.click();
  }, [isDemoLoaded, choosingMap, onCancelChoosingMap, setRecording]);

  const handleFileChange = useCallback(
    async (e: React.ChangeEvent<HTMLInputElement>) => {
      const file = e.target.files?.[0];
      if (!file) return;
      // Reset the input so the same file can be re-selected.
      e.target.value = "";
      try {
        const buffer = await file.arrayBuffer();
        const parseToken = parseTokenRef.current + 1;
        parseTokenRef.current = parseToken;
        const { createDemoStreamingRecording } =
          await import("../stream/demoStreaming");
        const recording = await createDemoStreamingRecording(buffer);
        if (parseTokenRef.current !== parseToken) {
          return;
        }
        // Disconnect from any live server before loading the demo.
        const liveState = liveConnectionStore.getState();
        liveState.disconnectServer();
        // Metadata-first: mission/game-mode sync happens immediately.
        setRecording(recording);
      } catch (err) {
        log.error("Failed to load demo: %o", err);
      }
    },
    [setRecording],
  );

  return (
    <>
      <input
        ref={inputRef}
        type="file"
        accept=".rec"
        style={{ display: "none" }}
        onChange={handleFileChange}
      />
      <button
        type="button"
        className={styles.Root}
        aria-label={isDemoLoaded ? "Unload demo" : "Load demo (.rec)"}
        title={isDemoLoaded ? "Unload demo" : "Load demo (.rec)"}
        onClick={handleClick}
        data-active={isActive}
      >
        <MdOndemandVideo className={styles.DemoIcon} />
        <span className={styles.ButtonLabel}>Demo</span>
        <span className={styles.ButtonHint}>
          {choosingMap && isDemoLoaded
            ? "Return to demo"
            : isDemoLoaded
              ? "Click to unload"
              : "Load a .rec file"}
        </span>
      </button>
    </>
  );
}
