import type { Accessor } from "solid-js"
import type {
  Preferences,
  ExpansionPreference,
  ToolInputsVisibilityPreference,
} from "../../stores/preferences"
import type { Command } from "../commands"
import { tGlobal } from "../i18n"
import { runtimeEnv } from "../runtime-env"

export type BehaviorSettingKind = "toggle" | "enum"

export type BehaviorToggleSetting = {
  kind: "toggle"
  id: string
  titleKey: string
  subtitleKey: string
  get: (preferences: Preferences) => boolean
  set: (next: boolean) => void
  disabled?: () => boolean
}

export type BehaviorEnumSetting<T extends string = string> = {
  kind: "enum"
  id: string
  titleKey: string
  subtitleKey: string
  get: (preferences: Preferences) => T
  set: (next: T) => void
  options: Array<{ value: T; labelKey: string }>
  disabled?: () => boolean
}

export type BehaviorSetting = BehaviorToggleSetting | BehaviorEnumSetting

export type BehaviorRegistryActions = {
  preferences: Accessor<Preferences>
  updatePreferences?: (updates: Partial<Preferences>) => void
  toggleShowThinkingBlocks: () => void
  toggleKeyboardShortcutHints: () => void
  toggleShowTimelineTools: () => void
  toggleUsageMetrics: () => void
  toggleAutoCleanupBlankSessions: () => void
  togglePromptSubmitOnEnter: () => void
  setDiffViewMode: (mode: "split" | "unified") => void
  setToolOutputExpansion: (mode: ExpansionPreference) => void
  setDiagnosticsExpansion: (mode: ExpansionPreference) => void
  setThinkingBlocksExpansion: (mode: ExpansionPreference) => void
  setToolInputsVisibility: (mode: ToolInputsVisibilityPreference) => void
}

function splitKeywords(key: string): string[] {
  return tGlobal(key)
    .split(",")
    .map((value) => value.trim())
    .filter(Boolean)
}

function setBooleanByToggle(getCurrent: () => boolean, toggle: () => void, next: boolean) {
  if (getCurrent() === next) return
  toggle()
}

export function getBehaviorSettings(actions: BehaviorRegistryActions): BehaviorSetting[] {
  const prefs = actions.preferences
  const updatePreferences = actions.updatePreferences

  return [
    {
      kind: "toggle",
      id: "behavior.keyboardShortcutHints",
      titleKey: "settings.behavior.keyboardHints.title",
      subtitleKey: "settings.behavior.keyboardHints.subtitle",
      get: (p) => Boolean(p.showKeyboardShortcutHints ?? true),
      set: (next) => {
        if (updatePreferences) {
          updatePreferences({ showKeyboardShortcutHints: next })
          return
        }
        setBooleanByToggle(
          () => Boolean(prefs().showKeyboardShortcutHints ?? true),
          actions.toggleKeyboardShortcutHints,
          next,
        )
      },
      disabled: () => runtimeEnv.host === "web",
    },
    {
      kind: "toggle",
      id: "behavior.thinkingBlocks",
      titleKey: "settings.behavior.thinking.title",
      subtitleKey: "settings.behavior.thinking.subtitle",
      get: (p) => Boolean(p.showThinkingBlocks),
      set: (next) => {
        if (updatePreferences) {
          updatePreferences({ showThinkingBlocks: next })
          return
        }
        setBooleanByToggle(
          () => Boolean(prefs().showThinkingBlocks),
          actions.toggleShowThinkingBlocks,
          next,
        )
      },
    },
    {
      kind: "enum",
      id: "behavior.thinkingBlocksDefault",
      titleKey: "settings.behavior.thinkingDefault.title",
      subtitleKey: "settings.behavior.thinkingDefault.subtitle",
      get: (p) => (p.thinkingBlocksExpansion ?? "expanded") as ExpansionPreference,
      set: (next) => {
        if (updatePreferences) {
          updatePreferences({ thinkingBlocksExpansion: next as ExpansionPreference })
          return
        }
        actions.setThinkingBlocksExpansion(next as ExpansionPreference)
      },
      options: [
        { value: "expanded", labelKey: "commands.common.expanded" },
        { value: "collapsed", labelKey: "commands.common.collapsed" },
      ],
    },
    {
      kind: "toggle",
      id: "behavior.timelineToolCalls",
      titleKey: "settings.behavior.timelineTools.title",
      subtitleKey: "settings.behavior.timelineTools.subtitle",
      get: (p) => Boolean(p.showTimelineTools),
      set: (next) => {
        if (updatePreferences) {
          updatePreferences({ showTimelineTools: next })
          return
        }
        setBooleanByToggle(
          () => Boolean(prefs().showTimelineTools),
          actions.toggleShowTimelineTools,
          next,
        )
      },
    },
    {
      kind: "enum",
      id: "behavior.diffViewMode",
      titleKey: "settings.behavior.diffView.title",
      subtitleKey: "settings.behavior.diffView.subtitle",
      get: (p) => (p.diffViewMode ?? "split") as "split" | "unified",
      set: (next) => {
        if (updatePreferences) {
          updatePreferences({ diffViewMode: next as "split" | "unified" })
          return
        }
        actions.setDiffViewMode(next as "split" | "unified")
      },
      options: [
        { value: "split", labelKey: "settings.behavior.diffView.option.split" },
        { value: "unified", labelKey: "settings.behavior.diffView.option.unified" },
      ],
    },
    {
      kind: "enum",
      id: "behavior.toolOutputsDefault",
      titleKey: "settings.behavior.toolOutputsDefault.title",
      subtitleKey: "settings.behavior.toolOutputsDefault.subtitle",
      get: (p) => (p.toolOutputExpansion ?? "expanded") as ExpansionPreference,
      set: (next) => {
        if (updatePreferences) {
          updatePreferences({ toolOutputExpansion: next as ExpansionPreference })
          return
        }
        actions.setToolOutputExpansion(next as ExpansionPreference)
      },
      options: [
        { value: "expanded", labelKey: "commands.common.expanded" },
        { value: "collapsed", labelKey: "commands.common.collapsed" },
      ],
    },
    {
      kind: "enum",
      id: "behavior.diagnosticsDefault",
      titleKey: "settings.behavior.diagnosticsDefault.title",
      subtitleKey: "settings.behavior.diagnosticsDefault.subtitle",
      get: (p) => (p.diagnosticsExpansion ?? "expanded") as ExpansionPreference,
      set: (next) => {
        if (updatePreferences) {
          updatePreferences({ diagnosticsExpansion: next as ExpansionPreference })
          return
        }
        actions.setDiagnosticsExpansion(next as ExpansionPreference)
      },
      options: [
        { value: "expanded", labelKey: "commands.common.expanded" },
        { value: "collapsed", labelKey: "commands.common.collapsed" },
      ],
    },
    {
      kind: "enum",
      id: "behavior.toolInputsVisibility",
      titleKey: "settings.behavior.toolInputsVisibility.title",
      subtitleKey: "settings.behavior.toolInputsVisibility.subtitle",
      get: (p) => (p.toolInputsVisibility ?? "hidden") as ToolInputsVisibilityPreference,
      set: (next) => {
        if (updatePreferences) {
          updatePreferences({ toolInputsVisibility: next as ToolInputsVisibilityPreference })
          return
        }
        actions.setToolInputsVisibility(next as ToolInputsVisibilityPreference)
      },
      options: [
        { value: "hidden", labelKey: "commands.common.hidden" },
        { value: "collapsed", labelKey: "commands.common.collapsed" },
        { value: "expanded", labelKey: "commands.common.expanded" },
      ],
    },
    {
      kind: "toggle",
      id: "behavior.usageMetrics",
      titleKey: "settings.behavior.usageMetrics.title",
      subtitleKey: "settings.behavior.usageMetrics.subtitle",
      get: (p) => Boolean(p.showUsageMetrics ?? true),
      set: (next) => {
        if (updatePreferences) {
          updatePreferences({ showUsageMetrics: next })
          return
        }
        setBooleanByToggle(
          () => Boolean(prefs().showUsageMetrics ?? true),
          actions.toggleUsageMetrics,
          next,
        )
      },
    },
    {
      kind: "toggle",
      id: "behavior.autoCleanupBlankSessions",
      titleKey: "settings.behavior.autoCleanup.title",
      subtitleKey: "settings.behavior.autoCleanup.subtitle",
      get: (p) => Boolean(p.autoCleanupBlankSessions),
      set: (next) => {
        if (updatePreferences) {
          updatePreferences({ autoCleanupBlankSessions: next })
          return
        }
        setBooleanByToggle(
          () => Boolean(prefs().autoCleanupBlankSessions),
          actions.toggleAutoCleanupBlankSessions,
          next,
        )
      },
    },
    {
      kind: "toggle",
      id: "behavior.promptSubmitOnEnter",
      titleKey: "settings.behavior.promptSubmit.title",
      subtitleKey: "settings.behavior.promptSubmit.subtitle",
      get: (p) => Boolean(p.promptSubmitOnEnter),
      set: (next) => {
        if (updatePreferences) {
          updatePreferences({ promptSubmitOnEnter: next })
          return
        }
        setBooleanByToggle(
          () => Boolean(prefs().promptSubmitOnEnter),
          actions.togglePromptSubmitOnEnter,
          next,
        )
      },
    },
  ]
}

export function getBehaviorCommands(actions: BehaviorRegistryActions): Command[] {
  return [
    {
      id: "prompt-submit-shortcut",
      label: () =>
        actions.preferences().promptSubmitOnEnter
          ? tGlobal("commands.promptSubmitShortcut.label.swapped")
          : tGlobal("commands.promptSubmitShortcut.label.default"),
      description: () => tGlobal("commands.promptSubmitShortcut.description"),
      category: "Input & Focus",
      keywords: () => splitKeywords("commands.promptSubmitShortcut.keywords"),
      action: actions.togglePromptSubmitOnEnter,
    },
    {
      id: "thinking",
      label: () =>
        tGlobal(
          actions.preferences().showThinkingBlocks
            ? "commands.thinkingBlocks.label.hide"
            : "commands.thinkingBlocks.label.show",
        ),
      description: () => tGlobal("commands.thinkingBlocks.description"),
      category: "System",
      keywords: () => ["/thinking", ...splitKeywords("commands.thinkingBlocks.keywords")],
      action: actions.toggleShowThinkingBlocks,
    },
    {
      id: "timeline-tools",
      label: () =>
        tGlobal(
          actions.preferences().showTimelineTools
            ? "commands.timelineToolCalls.label.hide"
            : "commands.timelineToolCalls.label.show",
        ),
      description: () => tGlobal("commands.timelineToolCalls.description"),
      category: "System",
      keywords: () => splitKeywords("commands.timelineToolCalls.keywords"),
      action: actions.toggleShowTimelineTools,
    },
    {
      id: "keyboard-shortcut-hints",
      label: () =>
        tGlobal(
          actions.preferences().showKeyboardShortcutHints
            ? "commands.keyboardShortcutHints.label.hide"
            : "commands.keyboardShortcutHints.label.show",
        ),
      description: () =>
        tGlobal(
          runtimeEnv.host === "web"
            ? "commands.keyboardShortcutHints.description.disabledWeb"
            : "commands.keyboardShortcutHints.description",
        ),
      category: "System",
      keywords: () => splitKeywords("commands.keyboardShortcutHints.keywords"),
      disabled: () => runtimeEnv.host === "web",
      action: actions.toggleKeyboardShortcutHints,
    },
    {
      id: "thinking-default-visibility",
      label: () => {
        const mode = actions.preferences().thinkingBlocksExpansion ?? "expanded"
        const state = mode === "expanded" ? tGlobal("commands.common.expanded") : tGlobal("commands.common.collapsed")
        return tGlobal("commands.thinkingBlocksDefault.label", { state })
      },
      description: () => tGlobal("commands.thinkingBlocksDefault.description"),
      category: "System",
      keywords: () => ["/thinking", ...splitKeywords("commands.thinkingBlocksDefault.keywords")],
      action: () => {
        const mode = actions.preferences().thinkingBlocksExpansion ?? "expanded"
        const next: ExpansionPreference = mode === "expanded" ? "collapsed" : "expanded"
        actions.setThinkingBlocksExpansion(next)
      },
    },
    {
      id: "diff-view-split",
      label: () => {
        const prefix = (actions.preferences().diffViewMode || "split") === "split" ? "✓ " : ""
        return `${prefix}${tGlobal("commands.diffViewSplit.label")}`
      },
      description: () => tGlobal("commands.diffViewSplit.description"),
      category: "System",
      keywords: () => splitKeywords("commands.diffViewSplit.keywords"),
      action: () => actions.setDiffViewMode("split"),
    },
    {
      id: "diff-view-unified",
      label: () => {
        const prefix = (actions.preferences().diffViewMode || "split") === "unified" ? "✓ " : ""
        return `${prefix}${tGlobal("commands.diffViewUnified.label")}`
      },
      description: () => tGlobal("commands.diffViewUnified.description"),
      category: "System",
      keywords: () => splitKeywords("commands.diffViewUnified.keywords"),
      action: () => actions.setDiffViewMode("unified"),
    },
    {
      id: "tool-output-default-visibility",
      label: () => {
        const mode = actions.preferences().toolOutputExpansion || "expanded"
        const state = mode === "expanded" ? tGlobal("commands.common.expanded") : tGlobal("commands.common.collapsed")
        return tGlobal("commands.toolOutputsDefault.label", { state })
      },
      description: () => tGlobal("commands.toolOutputsDefault.description"),
      category: "System",
      keywords: () => splitKeywords("commands.toolOutputsDefault.keywords"),
      action: () => {
        const mode = actions.preferences().toolOutputExpansion || "expanded"
        const next: ExpansionPreference = mode === "expanded" ? "collapsed" : "expanded"
        actions.setToolOutputExpansion(next)
      },
    },
    {
      id: "diagnostics-default-visibility",
      label: () => {
        const mode = actions.preferences().diagnosticsExpansion || "expanded"
        const state = mode === "expanded" ? tGlobal("commands.common.expanded") : tGlobal("commands.common.collapsed")
        return tGlobal("commands.diagnosticsDefault.label", { state })
      },
      description: () => tGlobal("commands.diagnosticsDefault.description"),
      category: "System",
      keywords: () => splitKeywords("commands.diagnosticsDefault.keywords"),
      action: () => {
        const mode = actions.preferences().diagnosticsExpansion || "expanded"
        const next: ExpansionPreference = mode === "expanded" ? "collapsed" : "expanded"
        actions.setDiagnosticsExpansion(next)
      },
    },
    {
      id: "tool-inputs-visibility",
      label: () => {
        const mode = actions.preferences().toolInputsVisibility || "hidden"
        const state =
          mode === "expanded"
            ? tGlobal("commands.common.expanded")
            : mode === "collapsed"
              ? tGlobal("commands.common.collapsed")
              : tGlobal("commands.common.hidden")
        return tGlobal("commands.toolInputsVisibility.label", { state })
      },
      description: () => tGlobal("commands.toolInputsVisibility.description"),
      category: "System",
      keywords: () => splitKeywords("commands.toolInputsVisibility.keywords"),
      action: () => {
        const mode = actions.preferences().toolInputsVisibility || "hidden"
        const next: ToolInputsVisibilityPreference =
          mode === "hidden" ? "collapsed" : mode === "collapsed" ? "expanded" : "hidden"
        actions.setToolInputsVisibility(next)
      },
    },
    {
      id: "token-usage-visibility",
      label: () => {
        const visible = actions.preferences().showUsageMetrics ?? true
        const state = visible ? tGlobal("commands.common.visible") : tGlobal("commands.common.hidden")
        return tGlobal("commands.tokenUsageDisplay.label", { state })
      },
      description: () => tGlobal("commands.tokenUsageDisplay.description"),
      category: "System",
      keywords: () => splitKeywords("commands.tokenUsageDisplay.keywords"),
      action: actions.toggleUsageMetrics,
    },
    {
      id: "auto-cleanup-blank-sessions",
      label: () => {
        const enabled = actions.preferences().autoCleanupBlankSessions
        const state = enabled ? tGlobal("commands.common.enabled") : tGlobal("commands.common.disabled")
        return tGlobal("commands.autoCleanupBlankSessions.label", { state })
      },
      description: () => tGlobal("commands.autoCleanupBlankSessions.description"),
      category: "System",
      keywords: () => splitKeywords("commands.autoCleanupBlankSessions.keywords"),
      action: actions.toggleAutoCleanupBlankSessions,
    },
  ]
}

export function registerBehaviorCommands(register: (command: Command) => void, actions: BehaviorRegistryActions) {
  const commands = getBehaviorCommands(actions)
  commands.forEach((command) => register(command))
}
