import { useKeyboard, useTerminalDimensions } from "@opentui/react";
import { useCallback, useMemo, useState } from "react";
import type { LogSession } from "@/lib/logger";
import { formatProjectNameForDisplay } from "@/lib/tui/sessions/session-display";
import { CenteredModal } from "@/lib/tui/shared/CenteredModal";
import { TUI_COLORS } from "@/lib/tui/shared/colors";
import { KeyboardShortcutsModal } from "@/lib/tui/shared/KeyboardShortcutsModal";
import { ShortcutHint } from "@/lib/tui/shared/ShortcutHint";
import { SessionDetailPane } from "./SessionListDetailPane";
import {
  buildSessionOverlayOptions,
  resolveSessionOverlayKeyAction,
} from "./session-overlay-utils";
import { useSessionOverlayState } from "./use-session-overlay-state";

const NARROW_WIDTH_THRESHOLD = 110;

interface SessionOverlayProps {
  onClose: () => void;
}

function sessionLabel(session: LogSession): string {
  return session.name.replace(/\.jsonl$/, "");
}

function SessionHelpModal({ onClose }: { onClose: () => void }) {
  useKeyboard((key) => {
    if (key.name === "escape" || key.name === "q" || key.name === "?" || key.name === "h") {
      onClose();
    }
  });

  return <KeyboardShortcutsModal shortcuts={SESSION_OVERLAY_SHORTCUTS} />;
}

const SESSION_OVERLAY_SHORTCUTS = [
  { keys: "[Tab ←/→]", label: "Switch pane focus" },
  { keys: "[↑/↓ j/k]", label: "Navigate / Scroll" },
  { keys: "[d]", label: "Delete selected log" },
  { keys: "[h/?]", label: "Toggle help" },
] as const;

interface SessionDeleteModalProps {
  sessionName: string;
  error: string | null;
  isDeleting: boolean;
}

function SessionDeleteModal({ sessionName, error, isDeleting }: SessionDeleteModalProps) {
  return (
    <CenteredModal title="Delete Session Log" width={58}>
      <box flexDirection="column" gap={1}>
        <text fg={TUI_COLORS.text.primary}>{sessionName}</text>
        <text fg={TUI_COLORS.status.error}>This cannot be undone.</text>
        <text>
          <span fg={TUI_COLORS.accent.key}>[y]</span>
          <span fg={TUI_COLORS.status.error}> Delete</span>
          <span fg={TUI_COLORS.text.muted}> </span>
          <span fg={TUI_COLORS.accent.key}>[n/Esc]</span>
          <span fg={TUI_COLORS.text.muted}> Cancel</span>
        </text>
        {isDeleting && <text fg={TUI_COLORS.text.muted}>Deleting...</text>}
        {error && <text fg={TUI_COLORS.status.error}>{error}</text>}
      </box>
    </CenteredModal>
  );
}

type OverlayPane = "list" | "detail";

export function SessionOverlay({ onClose }: SessionOverlayProps) {
  const { width: terminalWidth, height: terminalHeight } = useTerminalDimensions();
  const {
    sessions,
    selectedPath,
    selectedStats,
    isLoading,
    sessionsError,
    statsLoading,
    statsError,
    isDeleting,
    deleteError,
    setSelectedPath,
    clearDeleteError,
    deleteSelectedSession,
  } = useSessionOverlayState();
  const [showHelp, setShowHelp] = useState(false);
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const [focusedPane, setFocusedPane] = useState<OverlayPane>("list");

  const cycleFocus = useCallback(() => {
    setFocusedPane((prev) => (prev === "list" ? "detail" : "list"));
  }, []);

  const { selectOptions, sessionSlots } = useMemo(
    () => buildSessionOverlayOptions(sessions),
    [sessions]
  );

  const selectedSession = selectedPath
    ? (sessions.find((s) => s.path === selectedPath) ?? null)
    : null;
  const sessionTitle = selectedSession
    ? `${formatProjectNameForDisplay(selectedSession.projectName)} Logs`
    : "Logs";

  const confirmDeleteSelectedSession = useCallback(async () => {
    const result = await deleteSelectedSession();
    if (result.deleted) {
      setShowDeleteConfirm(false);
    }
  }, [deleteSelectedSession]);

  const closeDeleteConfirm = useCallback(() => {
    if (isDeleting) {
      return;
    }

    setShowDeleteConfirm(false);
    clearDeleteError();
  }, [clearDeleteError, isDeleting]);

  const isOverlayBlocked = showHelp || showDeleteConfirm;
  const isNarrow = terminalWidth < NARROW_WIDTH_THRESHOLD;
  // Overhead: outer padding (2) + panel border (2) + panel padding (2) + status bar (2) = 8.
  // In narrow mode the tab strip (1) and its gap (1) add two more rows.
  const selectHeight = Math.max(3, terminalHeight - (isNarrow ? 10 : 8));

  useKeyboard((key) => {
    const action = resolveSessionOverlayKeyAction({
      keyName: key.name,
      showHelp,
      showDeleteConfirm,
      hasSelectedSession: Boolean(selectedSession),
      isNarrow,
      focusedPane,
    });

    if (action === "close-delete-confirm") {
      closeDeleteConfirm();
      return;
    }

    if (action === "confirm-delete") {
      void confirmDeleteSelectedSession();
      return;
    }

    if (action === "toggle-help") {
      setShowHelp((prev) => !prev);
      return;
    }

    if (action === "close-help") {
      setShowHelp(false);
      return;
    }

    if (action === "open-delete-confirm") {
      clearDeleteError();
      setShowDeleteConfirm(true);
      return;
    }

    if (action === "cycle-focus") {
      cycleFocus();
      return;
    }

    if (action === "focus-detail") {
      setFocusedPane("detail");
      return;
    }

    if (action === "close-overlay") {
      onClose();
      return;
    }
  });

  const listBorderColor =
    focusedPane === "list" ? TUI_COLORS.ui.borderFocused : TUI_COLORS.ui.border;
  const detailBorderColor =
    focusedPane === "detail" ? TUI_COLORS.ui.borderFocused : TUI_COLORS.ui.border;

  const listPanel = (
    <box
      border
      borderStyle="rounded"
      borderColor={listBorderColor}
      title={sessionTitle}
      titleAlignment="left"
      width={isNarrow ? undefined : 70}
      flexGrow={isNarrow ? 1 : 0}
      flexShrink={isNarrow ? 1 : 0}
      minHeight={0}
      flexDirection="column"
      padding={1}
    >
      {isLoading ? (
        <text fg={TUI_COLORS.text.muted}>Loading...</text>
      ) : sessionsError ? (
        <text fg={TUI_COLORS.status.error}>{sessionsError}</text>
      ) : selectOptions.length === 0 ? (
        <text fg={TUI_COLORS.text.muted}>No sessions found</text>
      ) : (
        <select
          options={selectOptions}
          height={selectHeight}
          focused={focusedPane === "list" && !isOverlayBlocked}
          showScrollIndicator
          showDescription={false}
          itemSpacing={1}
          selectedIndex={sessionSlots.findIndex((s) => s?.path === selectedPath)}
          onChange={(idx) => {
            const slot = sessionSlots[idx];
            if (slot) setSelectedPath(slot.path);
          }}
        />
      )}
    </box>
  );

  const detailPanel = (
    <box
      border
      borderStyle="rounded"
      borderColor={detailBorderColor}
      title={selectedSession ? sessionLabel(selectedSession) : "Session Detail"}
      titleAlignment="left"
      flexGrow={1}
      minHeight={0}
      flexDirection="column"
      padding={1}
    >
      {statsLoading ? (
        <text fg={TUI_COLORS.text.muted}>Loading...</text>
      ) : statsError ? (
        <text fg={TUI_COLORS.status.error}>{statsError}</text>
      ) : !selectedStats ? (
        <text fg={TUI_COLORS.text.muted}>Select a session to view details</text>
      ) : (
        <SessionDetailPane
          stats={selectedStats}
          focused={focusedPane === "detail" && !isOverlayBlocked}
          height={selectHeight}
        />
      )}
    </box>
  );

  return (
    <box
      position="absolute"
      left={0}
      top={0}
      width="100%"
      height="100%"
      flexDirection="column"
      backgroundColor="#0d0d1a"
    >
      {isNarrow ? (
        <box flexDirection="column" width="100%" flexGrow={1} minHeight={0} gap={1} padding={1}>
          <box flexDirection="row" gap={3} paddingLeft={1} paddingRight={1}>
            <text>
              <span fg={focusedPane === "list" ? TUI_COLORS.ui.borderFocused : TUI_COLORS.text.dim}>
                {focusedPane === "list" ? "▸ Logs" : "  Logs"}
              </span>
            </text>
            <text>
              <span
                fg={focusedPane === "detail" ? TUI_COLORS.ui.borderFocused : TUI_COLORS.text.dim}
              >
                {focusedPane === "detail" ? "▸ Detail" : "  Detail"}
              </span>
            </text>
          </box>
          {focusedPane === "list" ? listPanel : detailPanel}
        </box>
      ) : (
        <box flexDirection="row" width="100%" flexGrow={1} minHeight={0} gap={1} padding={1}>
          {listPanel}
          {detailPanel}
        </box>
      )}

      <box
        flexDirection="row"
        justifyContent="space-between"
        paddingLeft={1}
        paddingRight={1}
        paddingBottom={1}
      >
        <box flexDirection="row" gap={2}>
          {isNarrow && <ShortcutHint keys="[Tab]" label="Switch" />}
          <ShortcutHint keys="[d]" label="Delete" />
          <ShortcutHint keys="[h]" label="Help" />
        </box>
        <text fg={TUI_COLORS.text.dim}>Focus: {focusedPane === "list" ? "List" : "Detail"}</text>
      </box>

      {showHelp && <SessionHelpModal onClose={() => setShowHelp(false)} />}
      {showDeleteConfirm && (
        <SessionDeleteModal
          sessionName={selectedSession ? sessionLabel(selectedSession) : "Unknown session"}
          error={deleteError}
          isDeleting={isDeleting}
        />
      )}
    </box>
  );
}
