import type { DimSdkStore } from "#cli/core/store";
import type { ComputedRef, Ref } from "vue";
import { shouldPromptForToolApproval } from "#cli/core/store/approvals";
import { computed, inject, ref, watch } from "vue";
import { DimSdkProviderStateKey } from "../../../provider";
import { dialogSize } from "../../../ui/utils/dialog-sizes";

export function isDialogFlagOpen(flag: unknown): boolean {
  if (typeof flag === "boolean") return flag;
  return Boolean((flag as any)?.value ?? false);
}

export function useChatDialogs(
  opts: Readonly<{
    store: DimSdkStore;
    rows: ComputedRef<number>;
    contentW: ComputedRef<number>;
    focusMode: Ref<"input" | "messages">;

    showSessions: Ref<boolean>;
    showHelp: Ref<boolean>;
    showTimeline: Ref<boolean>;
    showSessionTrace: Ref<boolean>;
    showPinned: Ref<boolean>;
    showSwitchConfirm: Ref<boolean>;
    showConfig: Ref<boolean>;
    showTheme: Ref<boolean>;
    showLanguage: Ref<boolean>;
    showToolApprovals: Ref<boolean>;
    showSkills: Ref<boolean>;
    showToolSettings: Ref<boolean>;
    showMcpSettings: Ref<boolean>;
    showPlugins: Ref<boolean>;
    showPluginConfig: Ref<boolean>;
    showPathPicker: Ref<boolean>;
    showMessageActions: Ref<boolean>;
    showRedoConfirm: Ref<boolean>;
    showRenameSession: Ref<boolean>;
    showConnect: Ref<boolean>;
    showModels: Ref<boolean>;
    showConnectDialog: Ref<boolean>;
    showCustomManage: Ref<boolean>;
    showCustomDeleteConfirm: Ref<boolean>;
    showNextApiOAuth: Ref<boolean>;
    showCustomType: Ref<boolean>;
    showCustomConnectDialog: Ref<boolean>;
    showCustomModelsDialog: Ref<boolean>;
    showCustomModelsFetchDialog: Ref<boolean>;
    showCustomNameDialog: Ref<boolean>;
    showPausedQueueDecision: Ref<boolean>;
    showQueueConfirm: Ref<boolean>;
  }>,
): Readonly<{
  showCommands: Ref<boolean>;
  commandIndex: Ref<number>;
  showApproval: Ref<boolean>;
  showAskUser: Ref<boolean>;
  showExitConfirm: Ref<boolean>;

  activeApproval: ComputedRef<any>;
  approvalW: ComputedRef<number>;
  approvalH: ComputedRef<number>;

  activeAskUser: ComputedRef<any>;
  askUserW: ComputedRef<number>;
  askUserH: ComputedRef<number>;

  configW: ComputedRef<number>;
  configH: ComputedRef<number>;
  languageW: ComputedRef<number>;
  languageH: ComputedRef<number>;
  toolApprovalsW: ComputedRef<number>;
  toolApprovalsH: ComputedRef<number>;
  toolSettingsW: ComputedRef<number>;
  toolSettingsH: ComputedRef<number>;
  mcpSettingsW: ComputedRef<number>;
  mcpSettingsH: ComputedRef<number>;

  smW: ComputedRef<number>;
  smH: ComputedRef<number>;
  mdW: ComputedRef<number>;
  mdH: ComputedRef<number>;

  anyDialogOpen: ComputedRef<boolean>;
  openCommandPalette: () => void;
  closeCommandPalette: () => void;
}> {
  const showCommands = ref(false);
  const commandIndex = ref(0);

  const showApproval = ref(false);
  const showAskUser = ref(false);
  const showExitConfirm = ref(false);

  // Check if the Provider-level exit app dialog is showing
  const providerState = inject(DimSdkProviderStateKey, null as any);
  const providerExitDialogOpen = computed(() => isDialogFlagOpen(providerState?.showExitConfirm));

  const activeApproval = computed(() => opts.store.state.approval.active);
  const approvalSize = computed(() => dialogSize("md", opts.contentW.value, opts.rows.value));
  const approvalW = computed(() => approvalSize.value.w);
  const approvalH = computed(() => approvalSize.value.h);

  const activeAskUser = computed(() =>
    opts.store.state.paused?.kind === "ask_user" ? opts.store.state.paused : null,
  );
  const askUserSize = computed(() => dialogSize("lg", opts.contentW.value, opts.rows.value));
  const askUserW = computed(() => askUserSize.value.w);
  const askUserH = computed(() => askUserSize.value.h);

  const configSize = computed(() => dialogSize("lg", opts.contentW.value, opts.rows.value));
  const configW = computed(() => configSize.value.w);
  const configH = computed(() => configSize.value.h);

  const languageSize = computed(() => dialogSize("md", opts.contentW.value, opts.rows.value));
  const languageW = computed(() => languageSize.value.w);
  const languageH = computed(() => languageSize.value.h);

  const toolApprovalsSize = computed(() => dialogSize("md", opts.contentW.value, opts.rows.value));
  const toolApprovalsW = computed(() => toolApprovalsSize.value.w);
  const toolApprovalsH = computed(() => toolApprovalsSize.value.h);

  const toolSettingsSize = computed(() => dialogSize("md", opts.contentW.value, opts.rows.value));
  const toolSettingsW = computed(() => toolSettingsSize.value.w);
  const toolSettingsH = computed(() => toolSettingsSize.value.h);

  const mcpSettingsSize = computed(() => dialogSize("xl", opts.contentW.value, opts.rows.value));
  const mcpSettingsW = computed(() => mcpSettingsSize.value.w);
  const mcpSettingsH = computed(() => mcpSettingsSize.value.h);

  const smSize = computed(() => dialogSize("sm", opts.contentW.value, opts.rows.value));
  const smW = computed(() => smSize.value.w);
  const smH = computed(() => smSize.value.h);
  const mdSize = computed(() => dialogSize("md", opts.contentW.value, opts.rows.value));
  const mdW = computed(() => mdSize.value.w);
  const mdH = computed(() => mdSize.value.h);

  function shouldShowApprovalDialog(req: any): boolean {
    const mode = String(opts.store.state.approval.mode ?? "auto");
    if (mode === "auto") return false;
    return shouldPromptForToolApproval(req as any);
  }

  watch(
    () => activeApproval.value?.id ?? null,
    () => {
      const req = activeApproval.value;
      if (req && req.status === "pending" && shouldShowApprovalDialog(req))
        showApproval.value = true;
      else showApproval.value = false;
    },
    { immediate: true },
  );

  watch(
    () => opts.store.state.approval.mode,
    () => {
      const req = activeApproval.value;
      if (!req || req.status !== "pending" || !shouldShowApprovalDialog(req))
        showApproval.value = false;
    },
  );

  watch(
    () => activeAskUser.value?.toolCallId ?? null,
    () => {
      showAskUser.value = false;
    },
    { immediate: true },
  );

  const anyDialogOpen = computed(
    () =>
      showCommands.value ||
      opts.showTheme.value ||
      opts.showHelp.value ||
      opts.showSessions.value ||
      opts.showTimeline.value ||
      opts.showSessionTrace.value ||
      opts.showPinned.value ||
      opts.showPausedQueueDecision.value ||
      opts.showQueueConfirm.value ||
      opts.showSwitchConfirm.value ||
      opts.showMessageActions.value ||
      opts.showRedoConfirm.value ||
      opts.showConfig.value ||
      opts.showLanguage.value ||
      opts.showConnect.value ||
      opts.showModels.value ||
      opts.showConnectDialog.value ||
      opts.showNextApiOAuth.value ||
      opts.showCustomManage.value ||
      opts.showCustomDeleteConfirm.value ||
      opts.showCustomType.value ||
      opts.showCustomConnectDialog.value ||
      opts.showCustomModelsDialog.value ||
      opts.showCustomModelsFetchDialog.value ||
      opts.showCustomNameDialog.value ||
      showAskUser.value ||
      opts.showToolApprovals.value ||
      opts.showSkills.value ||
      opts.showToolSettings.value ||
      opts.showMcpSettings.value ||
      opts.showPlugins.value ||
      opts.showPluginConfig.value ||
      opts.showRenameSession.value ||
      opts.showPathPicker.value ||
      showExitConfirm.value ||
      providerExitDialogOpen.value,
  );

  watch(anyDialogOpen, (open) => {
    if (!open) opts.focusMode.value = "input";
  });

  function openCommandPalette(): void {
    showCommands.value = true;
    commandIndex.value = 0;
  }

  function closeCommandPalette(): void {
    showCommands.value = false;
  }

  return {
    showCommands,
    commandIndex,
    showApproval,
    showAskUser,
    showExitConfirm,
    activeApproval,
    approvalW,
    approvalH,
    activeAskUser,
    askUserW,
    askUserH,
    configW,
    configH,
    languageW,
    languageH,
    toolApprovalsW,
    toolApprovalsH,
    toolSettingsW,
    toolSettingsH,
    mcpSettingsW,
    mcpSettingsH,
    smW,
    smH,
    mdW,
    mdH,
    anyDialogOpen,
    openCommandPalette,
    closeCommandPalette,
  };
}
