import { useCallback, useEffect, useRef, useState } from "react";
import { CircleDollarSign, Sparkles, BookOpen } from "lucide-react";
import { useAppStore } from "../../../stores/useAppStore";
import { getAppSetting } from "../../../services/tauri";
import { tooltipAttributes } from "../../../hotkeys/display";
import { isMacHotkeyPlatform } from "../../../hotkeys/platform";
import { ModelSelector, is1mContextModel, get1mFallback } from "../ModelSelector";
import { findModelInRegistry } from "../modelRegistry";
import { useModelRegistry } from "../useModelRegistry";
import { isFastSupported, isEffortSupported } from "../modelCapabilities";
import {
  normalizeReasoningLevel,
  reasoningVariantForModel,
} from "../reasoningControls";
import { applySelectedModel } from "../applySelectedModel";
import { applyPlanModeMountDefault } from "../applyPlanModeMountDefault";
import { ToolbarPill } from "./ToolbarPill";
import { ReasoningPill } from "./ReasoningPill";
import { OverflowMenu } from "./OverflowMenu";
import { ClaudeFlagsTooltip } from "./ClaudeFlagsTooltip";
import styles from "./ComposerToolbar.module.css";

interface ComposerToolbarProps {
  sessionId: string;
  workspaceId: string;
  repoId: string | null;
  /** Blocks controls that mutate turn configuration. Env preparation must not set this. */
  configDisabled: boolean;
  /** Blocks actions that require a ready workspace environment. */
  sendDisabled: boolean;
  /** True while a turn is in flight. Pills that mutate session state stay locked;
   *  the overflow menu's Remote Control row uses this to queue mid-turn enables. */
  isRunning: boolean;
  isRemote: boolean;
}

export function ComposerToolbar({
  sessionId,
  workspaceId,
  repoId,
  configDisabled,
  sendDisabled,
  isRunning,
  isRemote,
}: ComposerToolbarProps) {
  // Session-mutating pills (model, plan, reasoning) keep their pre-split
  // behavior: locked whenever a turn is running.
  // Env preparation only blocks actions that need the resolved environment;
  // users can still configure the first turn while that warmup runs.
  // The overflow menu deliberately opts out so users can queue Remote
  // Control mid-turn — see `OverflowMenu` for the per-item gating.
  const mutationDisabled = configDisabled || isRunning;
  const selectedModel = useAppStore((s) => s.selectedModel[sessionId] ?? "opus");
  const selectedProvider = useAppStore((s) => s.selectedModelProvider[sessionId] ?? "anthropic");
  const disable1mContext = useAppStore((s) => s.disable1mContext);
  const planMode = useAppStore((s) => s.planMode[sessionId] ?? false);
  const modelSelectorOpen = useAppStore((s) => s.modelSelectorOpen);
  const keybindings = useAppStore((s) => s.keybindings);
  const setSelectedModel = useAppStore((s) => s.setSelectedModel);
  const setFastMode = useAppStore((s) => s.setFastMode);
  const setThinkingEnabled = useAppStore((s) => s.setThinkingEnabled);
  const setPlanMode = useAppStore((s) => s.setPlanMode);
  const setEffortLevel = useAppStore((s) => s.setEffortLevel);
  const setChromeEnabled = useAppStore((s) => s.setChromeEnabled);
  const setShowThinkingBlocks = useAppStore((s) => s.setShowThinkingBlocks);
  const setModelSelectorOpen = useAppStore((s) => s.setModelSelectorOpen);
  const claudeFlagsState = useAppStore(
    (s) => s.claudeFlagsByWorkspace[workspaceId],
  );
  const loadWorkspaceClaudeFlags = useAppStore(
    (s) => s.loadWorkspaceClaudeFlags,
  );

  useEffect(() => {
    if (!claudeFlagsState) {
      void loadWorkspaceClaudeFlags(workspaceId, repoId);
    }
  }, [workspaceId, repoId, claudeFlagsState, loadWorkspaceClaudeFlags]);

  const resolvedFlags = claudeFlagsState?.resolved ?? [];

  const [loaded, setLoaded] = useState(false);
  // Single source for visibility (feature flags + OAuth gate) — see
  // `useModelRegistry`.
  const registry = useModelRegistry();
  const registryRef = useRef(registry);
  useEffect(() => {
    registryRef.current = registry;
  }, [registry]);

  useEffect(() => {
    let cancelled = false;
    async function load() {
      const [model, provider, fast, thinking, effort, showThinking, chrome, defModel, defProvider, defFast, defThinking, defPlan, defEffort, defShowThinking, defChrome] = await Promise.all([
        getAppSetting(`model:${sessionId}`),
        getAppSetting(`model_provider:${sessionId}`),
        getAppSetting(`fast_mode:${sessionId}`),
        getAppSetting(`thinking_enabled:${sessionId}`),
        getAppSetting(`effort_level:${sessionId}`),
        getAppSetting(`show_thinking:${sessionId}`),
        getAppSetting(`chrome_enabled:${sessionId}`),
        getAppSetting("default_model"),
        getAppSetting("default_agent_backend"),
        getAppSetting("default_fast_mode"),
        getAppSetting("default_thinking"),
        getAppSetting("default_plan_mode"),
        getAppSetting("default_effort"),
        getAppSetting("default_show_thinking"),
        getAppSetting("default_chrome"),
      ]);
      if (cancelled) return;
      const loadedModel = model ?? defModel ?? "opus";
      const loadedProvider = provider ?? defProvider ?? "anthropic";
      const loadedEntry = findModelInRegistry(registryRef.current, loadedModel, loadedProvider);
      const supportsFast = loadedEntry?.supportsFastMode ?? isFastSupported(loadedModel);
      const supportsEffort = loadedEntry?.supportsEffort ?? isEffortSupported(loadedModel);
      setSelectedModel(sessionId, loadedModel, loadedProvider);
      const effectiveFast = supportsFast && (fast === "true" || (!fast && defFast === "true"));
      const effectiveThinking = thinking === "true" || (!thinking && defThinking === "true");
      setFastMode(sessionId, effectiveFast);
      setThinkingEnabled(sessionId, effectiveThinking);
      applyPlanModeMountDefault(sessionId, defPlan === "true");
      const effectiveEffort = effort ?? defEffort;
      if (effectiveEffort) {
        const normalized = !supportsEffort
          ? "auto"
          : normalizeReasoningLevel(
              effectiveEffort,
              loadedModel,
              reasoningVariantForModel(loadedEntry),
            );
        setEffortLevel(sessionId, normalized);
      }
      setShowThinkingBlocks(sessionId, showThinking === "true" || (!showThinking && defShowThinking === "true"));
      setChromeEnabled(sessionId, chrome === "true" || (!chrome && defChrome === "true"));
      setLoaded(true);
    }
    load();
    return () => { cancelled = true; };
  }, [sessionId, setSelectedModel, setFastMode, setThinkingEnabled, setEffortLevel, setShowThinkingBlocks, setChromeEnabled]);

  const handleModelSelect = useCallback(
    async (model: string, providerId = "anthropic") => {
      if (model !== selectedModel || providerId !== selectedProvider) {
        await applySelectedModel(sessionId, model, providerId);
      }
      setModelSelectorOpen(false);
    },
    [sessionId, selectedModel, selectedProvider, setModelSelectorOpen],
  );

  const togglePlan = useCallback(() => {
    setPlanMode(sessionId, !planMode);
  }, [sessionId, planMode, setPlanMode]);

  // The Cmd/Ctrl+T thinking-mode hotkey lived here as a raw
  // `window.addEventListener("keydown")` listener. It's been removed —
  // Cmd+T is now the registered `global.new-tab` action (see
  // `useKeyboardShortcuts`), and thinking remains toggleable via the
  // ReasoningPill click + the command palette ("Toggle thinking").

  useEffect(() => {
    if (!loaded || !disable1mContext) return;
    if (is1mContextModel(selectedModel)) {
      void applySelectedModel(sessionId, get1mFallback(selectedModel));
    }
  }, [loaded, disable1mContext, selectedModel, sessionId]);

  const currentModel = registry.find(
    (m) => m.id === selectedModel && (m.providerId ?? "anthropic") === selectedProvider,
  );
  const modelLabel = currentModel?.providerLabel
    ? `${currentModel.providerLabel} / ${currentModel.label}`
    : currentModel?.label ?? selectedModel;
  const isExtraUsage = currentModel?.extraUsage ?? false;
  const isMac = isMacHotkeyPlatform();

  if (!loaded) return null;

  return (
    <div className={styles.toolbar}>
      <div className={styles.modelPillWrap}>
        <ToolbarPill
          icon={<Sparkles size={14} className={styles.accentIcon} />}
          label={modelLabel}
          chevron
          onClick={() => setModelSelectorOpen(!modelSelectorOpen)}
          disabled={mutationDisabled}
          title={isExtraUsage ? "Change model (extra usage: 1M context billed at API rates)" : "Change model"}
        >
          {isExtraUsage && <CircleDollarSign size={14} className={styles.extraUsage} />}
        </ToolbarPill>
        {modelSelectorOpen && (
          <ModelSelector
            selected={selectedModel}
            selectedProvider={selectedProvider}
            onSelect={handleModelSelect}
            onClose={() => setModelSelectorOpen(false)}
          />
        )}
      </div>

      <ToolbarPill
        icon={<BookOpen size={14} />}
        label="Plan"
        active={planMode}
        onClick={togglePlan}
        disabled={mutationDisabled}
        {...tooltipAttributes(
          `${planMode ? "Disable" : "Enable"} plan mode`,
          "global.toggle-plan-mode",
          keybindings,
          isMac,
        )}
        ariaPressed={planMode}
      />

      <ReasoningPill sessionId={sessionId} disabled={mutationDisabled} />

      <ClaudeFlagsTooltip resolved={resolvedFlags} />

      <OverflowMenu
        sessionId={sessionId}
        configDisabled={configDisabled}
        sendDisabled={sendDisabled}
        isRunning={isRunning}
        isRemote={isRemote}
      />
    </div>
  );
}
