import { useEffect, useEffectEvent, useState } from "react";
import type { LegacyLifeSession } from "./legacySessionTypes";
import {
  canOpenLegacyView,
  getLegacyVisibleViews,
  resolveLegacyEnterAction,
  type LegacyShortcutAction,
  type LegacyView,
  type LegacyViewDefinition,
} from "../components/legacy-app/legacyAppConfig";

type LegacyAppNavigationSession = Pick<
  LegacyLifeSession,
  | "beginLife"
  | "openSummary"
  | "remakeLife"
  | "reshuffleSpecialThanks"
  | "setAutoPlaySpeed"
  | "stage"
  | "stepLife"
  | "trajectory"
>;

interface UseLegacyAppViewProps {
  hasMetaUnlocked: boolean;
  session: LegacyAppNavigationSession;
}

interface LegacyAppViewState {
  view: LegacyView;
  visibleViews: LegacyViewDefinition[];
  openView: (nextView: LegacyView) => void;
  handleRemake: () => void;
}

function isEditableTarget(target: EventTarget | null): target is HTMLElement {
  return (
    target instanceof HTMLElement &&
    (target.tagName === "INPUT" ||
      target.tagName === "TEXTAREA" ||
      target.isContentEditable)
  );
}

export function useLegacyAppView({
  hasMetaUnlocked,
  session,
}: UseLegacyAppViewProps): LegacyAppViewState {
  const [view, setView] = useState<LegacyView>("home");
  const visibleViews = getLegacyVisibleViews(hasMetaUnlocked);

  function openView(nextView: LegacyView): void {
    if (!canOpenLegacyView(nextView, hasMetaUnlocked)) {
      return;
    }

    if (nextView !== "run") {
      session.setAutoPlaySpeed(null);
    }

    setView(nextView);

    if (nextView === "thanks") {
      session.reshuffleSpecialThanks();
    }
  }

  function handleRemake(): void {
    session.remakeLife();
    setView("home");
  }

  const runShortcutAction = useEffectEvent((action: LegacyShortcutAction) => {
    switch (action.type) {
      case "open-view":
        openView(action.view);
        return;
      case "begin-life":
        session.beginLife();
        return;
      case "open-summary":
        session.openSummary();
        return;
      case "remake-life":
        handleRemake();
        return;
      case "step-life":
        session.stepLife();
        return;
    }
  });

  const handleKeyboardShortcut = useEffectEvent((event: KeyboardEvent) => {
    if (
      event.defaultPrevented ||
      event.altKey ||
      event.ctrlKey ||
      event.metaKey
    ) {
      return;
    }

    if (isEditableTarget(event.target)) {
      return;
    }

    let action: LegacyShortcutAction | null = null;

    if (event.key === "Escape") {
      action = view === "home" ? null : { type: "open-view", view: "home" };
    } else if (event.key === "Enter") {
      action = resolveLegacyEnterAction(
        view,
        session.stage,
        session.trajectory.at(-1)?.isEnd ?? false,
      );
    }

    if (!action) {
      return;
    }

    event.preventDefault();
    runShortcutAction(action);
  });

  useEffect(() => {
    const onKeyDown = (event: KeyboardEvent) => handleKeyboardShortcut(event);
    window.addEventListener("keydown", onKeyDown);

    return () => {
      window.removeEventListener("keydown", onKeyDown);
    };
  }, [handleKeyboardShortcut]);

  return {
    view,
    visibleViews,
    openView,
    handleRemake,
  };
}
