import { jsx, jsxs } from "react/jsx-runtime";
import {
  useState,
  useEffect,
  forwardRef,
  useImperativeHandle,
  useCallback,
  useRef
} from "react";
import { Box, Text } from "ink";
import {
  saveCustomModel,
  deleteCustomModel,
  saveProviderApiKey,
  getProviderKeyStatus,
  resolveApiKeyForProvider,
  determineApiKeyStorage
} from "@dexto/agent-management";
import { logger } from "@dexto/core";
import {
  getProviderConfig,
  getAvailableProviders,
  getProviderByMenuIndex,
  runAsyncValidation
} from "./custom-model-wizard/provider-config.js";
import {
  ProviderSelector,
  WizardStepInput,
  SetupInfoBanner,
  ApiKeyStep
} from "./custom-model-wizard/shared/index.js";
import LocalModelWizard from "./custom-model-wizard/LocalModelWizard.js";
const CustomModelWizard = forwardRef(
  function CustomModelWizard2({ isVisible, onComplete, onClose, initialModel }, ref) {
    const [selectedProvider, setSelectedProvider] = useState(null);
    const [providerIndex, setProviderIndex] = useState(0);
    const [currentStep, setCurrentStep] = useState(0);
    const [values, setValues] = useState({});
    const [currentInput, setCurrentInput] = useState("");
    const [error, setError] = useState(null);
    const [isSaving, setIsSaving] = useState(false);
    const [isValidating, setIsValidating] = useState(false);
    const [originalName, setOriginalName] = useState(null);
    const isEditing = initialModel !== null && initialModel !== void 0;
    const localModelWizardRef = useRef(null);
    const providerConfig = selectedProvider ? getProviderConfig(selectedProvider) : null;
    const allWizardSteps = providerConfig?.steps ?? [];
    const getVisibleSteps = useCallback(
      (currentValues) => {
        return allWizardSteps.filter(
          (step) => !step.condition || step.condition(currentValues)
        );
      },
      [allWizardSteps]
    );
    const visibleSteps = getVisibleSteps(values);
    const currentStepConfig = visibleSteps[currentStep];
    useEffect(() => {
      if (isVisible) {
        if (initialModel) {
          const provider = initialModel.provider ?? "openai-compatible";
          const providers = getAvailableProviders();
          setSelectedProvider(provider);
          setOriginalName(initialModel.name);
          setValues({
            name: initialModel.name,
            baseURL: initialModel.baseURL ?? "",
            displayName: initialModel.displayName ?? "",
            maxInputTokens: initialModel.maxInputTokens?.toString() ?? "",
            reasoningPreset: initialModel.reasoning?.variant ?? "",
            apiKey: initialModel.apiKey ?? "",
            filePath: initialModel.filePath ?? ""
          });
          setCurrentStep(0);
          setCurrentInput(initialModel.name);
          const idx = providers.indexOf(provider);
          setProviderIndex(idx >= 0 ? idx : 0);
        } else {
          setSelectedProvider(null);
          setOriginalName(null);
          setProviderIndex(0);
          setCurrentStep(0);
          setValues({});
          setCurrentInput("");
        }
        setError(null);
        setIsSaving(false);
        setIsValidating(false);
      }
    }, [isVisible, initialModel]);
    const handleProviderSelect = useCallback(() => {
      const provider = getProviderByMenuIndex(providerIndex);
      if (provider) {
        setSelectedProvider(provider);
        setCurrentStep(0);
        setCurrentInput("");
        setError(null);
      }
    }, [providerIndex]);
    const handleNext = useCallback(async () => {
      if (!currentStepConfig || !selectedProvider || isSaving || isValidating) return;
      const value = currentInput.trim();
      if (currentStepConfig.validate) {
        const validationError = currentStepConfig.validate(value);
        if (validationError) {
          setError(validationError);
          return;
        }
      } else if (currentStepConfig.required && !value) {
        setError(`${currentStepConfig.label} is required`);
        return;
      }
      const asyncError = await (async () => {
        setIsValidating(true);
        setError(null);
        try {
          return await runAsyncValidation(
            selectedProvider,
            currentStepConfig.field,
            value
          );
        } finally {
          setIsValidating(false);
        }
      })();
      if (asyncError) {
        setError(asyncError);
        return;
      }
      const newValues = { ...values, [currentStepConfig.field]: value };
      setValues(newValues);
      setError(null);
      setCurrentInput("");
      const updatedVisibleSteps = getVisibleSteps(newValues);
      if (currentStep >= updatedVisibleSteps.length - 1) {
        await saveModel(newValues);
      } else {
        const nextStep = currentStep + 1;
        setCurrentStep(nextStep);
        const nextStepConfig = updatedVisibleSteps[nextStep];
        const nextValue = nextStepConfig ? newValues[nextStepConfig.field] : void 0;
        setCurrentInput(nextValue ?? "");
      }
    }, [
      currentInput,
      currentStep,
      currentStepConfig,
      getVisibleSteps,
      isSaving,
      isValidating,
      selectedProvider,
      values
    ]);
    const saveModel = useCallback(
      async (finalValues) => {
        if (!selectedProvider || !providerConfig) return;
        const model = providerConfig.buildModel(finalValues, selectedProvider);
        const userEnteredKey = finalValues.apiKey?.trim();
        const providerKeyStatus = getProviderKeyStatus(selectedProvider);
        const existingProviderKey = resolveApiKeyForProvider(
          selectedProvider
        );
        const keyStorage = determineApiKeyStorage(
          selectedProvider,
          userEnteredKey,
          providerKeyStatus.hasApiKey,
          existingProviderKey
        );
        if (keyStorage.saveToProviderEnvVar && userEnteredKey) {
          try {
            await saveProviderApiKey(
              selectedProvider,
              userEnteredKey,
              process.cwd()
            );
          } catch (err) {
            logger.warn(
              `Failed to save provider API key: ${err instanceof Error ? err.message : "Unknown error"}`
            );
            keyStorage.saveAsPerModel = true;
          }
        }
        if (keyStorage.saveAsPerModel && userEnteredKey) {
          model.apiKey = userEnteredKey;
        }
        setIsSaving(true);
        try {
          if (originalName && originalName !== model.name) {
            try {
              await deleteCustomModel(originalName);
            } catch (err) {
              logger.warn(
                `Failed to delete old model "${originalName}" during rename: ${err instanceof Error ? err.message : String(err)}`
              );
            }
          }
          await saveCustomModel(model);
          onComplete(model);
        } catch (err) {
          logger.error(
            `Failed to save custom model: ${err instanceof Error ? err.message : "Unknown error"}`
          );
          setError(
            `Failed to save: ${err instanceof Error ? err.message : "Unknown error"}`
          );
          setIsSaving(false);
        }
      },
      [selectedProvider, providerConfig, originalName, onComplete]
    );
    const handleBack = useCallback(() => {
      if (currentStep > 0) {
        setCurrentStep(currentStep - 1);
        const prevStep = visibleSteps[currentStep - 1];
        if (prevStep) {
          setCurrentInput(values[prevStep.field] || "");
        }
        setError(null);
      } else if (selectedProvider) {
        setSelectedProvider(null);
        setError(null);
      } else {
        onClose();
      }
    }, [currentStep, onClose, selectedProvider, values, visibleSteps]);
    useImperativeHandle(
      ref,
      () => ({
        handleInput: (input, key) => {
          if (!isVisible || isSaving || isValidating) return false;
          if (selectedProvider === "local" && localModelWizardRef.current) {
            return localModelWizardRef.current.handleInput(input, key);
          }
          if (key.escape) {
            handleBack();
            return true;
          }
          if (!selectedProvider) {
            const providers = getAvailableProviders();
            if (key.upArrow) {
              setProviderIndex(
                (prev) => prev > 0 ? prev - 1 : providers.length - 1
              );
              return true;
            }
            if (key.downArrow) {
              setProviderIndex(
                (prev) => prev < providers.length - 1 ? prev + 1 : 0
              );
              return true;
            }
            if (key.return) {
              handleProviderSelect();
              return true;
            }
            return true;
          }
          if (key.return) {
            void handleNext();
            return true;
          }
          if (key.backspace || key.delete) {
            setCurrentInput((prev) => prev.slice(0, -1));
            setError(null);
            return true;
          }
          if (input && !key.ctrl && !key.meta) {
            setCurrentInput((prev) => prev + input);
            setError(null);
            return true;
          }
          return false;
        }
      }),
      [
        isVisible,
        isSaving,
        isValidating,
        handleBack,
        handleNext,
        handleProviderSelect,
        selectedProvider
      ]
    );
    if (!isVisible) return null;
    if (!selectedProvider) {
      return /* @__PURE__ */ jsx(ProviderSelector, { selectedIndex: providerIndex, isEditing });
    }
    if (selectedProvider === "local") {
      return /* @__PURE__ */ jsx(
        LocalModelWizard,
        {
          ref: localModelWizardRef,
          isVisible,
          onComplete,
          onClose: () => {
            setSelectedProvider(null);
          }
        }
      );
    }
    if (!currentStepConfig || !providerConfig) return null;
    return /* @__PURE__ */ jsxs(
      Box,
      {
        flexDirection: "column",
        borderStyle: "round",
        borderColor: "green",
        paddingX: 1,
        marginTop: 1,
        children: [
          /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
            /* @__PURE__ */ jsx(Text, { bold: true, color: "green", children: isEditing ? "Edit Custom Model" : "Add Custom Model" }),
            /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
              " ",
              "(",
              providerConfig.displayName,
              ") Step ",
              currentStep + 1,
              "/",
              visibleSteps.length
            ] })
          ] }),
          providerConfig.setupInfo && currentStep === 0 && /* @__PURE__ */ jsx(
            SetupInfoBanner,
            {
              title: providerConfig.setupInfo.title,
              description: providerConfig.setupInfo.description,
              docsUrl: providerConfig.setupInfo.docsUrl
            }
          ),
          /* @__PURE__ */ jsx(
            WizardStepInput,
            {
              step: currentStepConfig,
              currentInput,
              error,
              isValidating,
              isSaving,
              additionalContent: currentStepConfig.field === "apiKey" ? /* @__PURE__ */ jsx(ApiKeyStep, { provider: selectedProvider }) : void 0
            }
          ),
          /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
            "Enter to continue \u2022 Esc to",
            " ",
            currentStep > 0 ? "go back" : "back to provider"
          ] }) })
        ]
      }
    );
  }
);
var CustomModelWizard_default = CustomModelWizard;
export {
  CustomModelWizard_default as default
};
