/**
 * @license
 * Copyright 2026 HopCode Team
 * SPDX-License-Identifier: Apache-2.0
 */
import { useState, useCallback } from 'react';
import { AuthType } from '@hoptrendy/hopcode-core';
import { t } from '../../i18n/index.js';
const DEFAULT_BASE_URLS = {
    [AuthType.USE_OPENAI]: 'https://api.openai.com/v1',
    [AuthType.USE_ANTHROPIC]: 'https://api.anthropic.com/v1',
    [AuthType.USE_GEMINI]: 'https://generativelanguage.googleapis.com',
};
import { shouldShowStep, resolveBaseUrl, getDefaultModelIds, } from '../../auth/providerConfig.js';
import { normalizeModelIds, maskApiKey } from './useAuth.js';
const STEP_ORDER = [
    'protocol',
    'baseUrl',
    'apiKey',
    'models',
    'advancedConfig',
    'review',
];
function getVisibleSteps(config) {
    return STEP_ORDER.filter((step) => {
        if (step === 'review')
            return config.showAdvancedConfig === true;
        return shouldShowStep(config, step);
    });
}
// ---------------------------------------------------------------------------
// Hook
// ---------------------------------------------------------------------------
export function useProviderSetupFlow(onSubmit) {
    const [provider, setProvider] = useState(null);
    const [visibleSteps, setVisibleSteps] = useState([]);
    const [stepIndex, setStepIndex] = useState(0);
    const [protocol, setProtocol] = useState(AuthType.USE_OPENAI);
    const [baseUrl, setBaseUrl] = useState('');
    const [baseUrlOptionIndex, setBaseUrlOptionIndex] = useState(0);
    const [baseUrlError, setBaseUrlError] = useState(null);
    const [apiKey, setApiKey] = useState('');
    const [apiKeyError, setApiKeyError] = useState(null);
    const [modelIds, setModelIds] = useState('');
    const [modelIdsError, setModelIdsError] = useState(null);
    const [thinkingEnabled, setThinkingEnabled] = useState(false);
    const [modalityEnabled, setModalityEnabled] = useState(false);
    const [modalityImage, setModalityImage] = useState(true);
    const [modalityVideo, setModalityVideo] = useState(true);
    const [modalityAudio, setModalityAudio] = useState(true);
    const [modalityPdf, setModalityPdf] = useState(false);
    const [contextWindowSize, setContextWindowSize] = useState('');
    const [focusedConfigIndex, setFocusedConfigIndex] = useState(0);
    const currentStep = visibleSteps[stepIndex] ?? null;
    // -- Lifecycle ------------------------------------------------------------
    const start = useCallback((config, initialProtocol, existingEnv) => {
        setProvider(config);
        const steps = getVisibleSteps(config);
        setVisibleSteps(steps);
        setStepIndex(0);
        const proto = initialProtocol ?? config.protocol;
        setProtocol(proto);
        const defaultUrl = resolveBaseUrl(config) || DEFAULT_BASE_URLS[proto] || '';
        setBaseUrl(defaultUrl);
        setBaseUrlOptionIndex(0);
        setBaseUrlError(null);
        let prefillKey = '';
        if (existingEnv) {
            const envKeyName = typeof config.envKey === 'function'
                ? config.envKey(proto, defaultUrl)
                : config.envKey;
            prefillKey = existingEnv[envKeyName] ?? '';
        }
        setApiKey(prefillKey);
        setApiKeyError(null);
        setModelIds(getDefaultModelIds(config).join(', '));
        setModelIdsError(null);
        setThinkingEnabled(false);
        setModalityEnabled(false);
        setModalityImage(true);
        setModalityVideo(true);
        setModalityAudio(true);
        setModalityPdf(false);
        setContextWindowSize('');
        setFocusedConfigIndex(0);
    }, []);
    const reset = useCallback(() => {
        setProvider(null);
        setVisibleSteps([]);
        setStepIndex(0);
    }, []);
    const goBack = useCallback(() => {
        if (stepIndex > 0) {
            setStepIndex((i) => i - 1);
            return true;
        }
        reset();
        return false;
    }, [stepIndex, reset]);
    const goNext = useCallback(() => {
        setStepIndex((i) => Math.min(i + 1, visibleSteps.length - 1));
    }, [visibleSteps]);
    // -- Step handlers --------------------------------------------------------
    const selectProtocol = useCallback((selectedProtocol) => {
        setProtocol(selectedProtocol);
        const nextBaseUrl = DEFAULT_BASE_URLS[selectedProtocol] ?? '';
        setBaseUrl(nextBaseUrl);
        setApiKey('');
        setApiKeyError(null);
        goNext();
    }, [goNext]);
    const selectBaseUrl = useCallback((selectedUrl) => {
        setBaseUrl(selectedUrl);
        setBaseUrlError(null);
        goNext();
    }, [goNext]);
    const submitBaseUrl = useCallback(() => {
        const trimmed = baseUrl.trim();
        if (!trimmed) {
            setBaseUrlError(t('Base URL cannot be empty.'));
            return false;
        }
        if (!/^https?:\/\//i.test(trimmed)) {
            setBaseUrlError(t('Base URL must start with http:// or https://.'));
            return false;
        }
        setBaseUrlError(null);
        goNext();
        return true;
    }, [baseUrl, goNext]);
    const changeBaseUrl = useCallback((value) => {
        setBaseUrl(value);
        setBaseUrlError(null);
    }, []);
    const changeApiKey = useCallback((value) => {
        setApiKey(value);
        setApiKeyError(null);
    }, []);
    // Shared helper: assemble ProviderSetupInputs from current form state
    const buildCurrentInputs = useCallback((overrides) => ({
        protocol: provider?.protocolOptions ? protocol : undefined,
        baseUrl: baseUrl.trim(),
        apiKey: apiKey.trim(),
        modelIds: normalizeModelIds(modelIds),
        ...overrides,
    }), [provider, protocol, baseUrl, apiKey, modelIds]);
    const submitOrNext = useCallback((overrides) => {
        if (stepIndex >= visibleSteps.length - 1) {
            if (provider)
                void onSubmit(provider, buildCurrentInputs(overrides));
        }
        else {
            goNext();
        }
    }, [stepIndex, visibleSteps, provider, onSubmit, buildCurrentInputs, goNext]);
    const submitApiKey = useCallback((keyOverride) => {
        const trimmed = (keyOverride ?? apiKey).trim();
        if (!trimmed) {
            setApiKeyError(t('API key cannot be empty.'));
            return false;
        }
        if (provider?.validateApiKey) {
            const err = provider.validateApiKey(trimmed, baseUrl);
            if (err) {
                setApiKeyError(err);
                return false;
            }
        }
        setApiKeyError(null);
        setApiKey(trimmed);
        submitOrNext({ apiKey: trimmed });
        return true;
    }, [apiKey, provider, baseUrl, submitOrNext]);
    const highlightBaseUrl = useCallback((url) => {
        if (provider && Array.isArray(provider.baseUrl)) {
            const idx = provider.baseUrl.findIndex((o) => o.url === url);
            setBaseUrlOptionIndex(idx >= 0 ? idx : 0);
        }
    }, [provider]);
    const changeModelIds = useCallback((value) => {
        setModelIds(value);
        setModelIdsError(null);
    }, []);
    const submitModelIds = useCallback(() => {
        const normalized = normalizeModelIds(modelIds);
        if (normalized.length === 0) {
            setModelIdsError(t('Model IDs cannot be empty.'));
            return false;
        }
        setModelIdsError(null);
        submitOrNext({ modelIds: normalized });
        return true;
    }, [modelIds, submitOrNext]);
    const advancedOptionCount = modalityEnabled ? 7 : 3;
    const moveAdvancedFocusUp = useCallback(() => {
        setFocusedConfigIndex((v) => (v <= 0 ? advancedOptionCount - 1 : v - 1));
    }, [advancedOptionCount]);
    const moveAdvancedFocusDown = useCallback(() => {
        setFocusedConfigIndex((v) => (v >= advancedOptionCount - 1 ? 0 : v + 1));
    }, [advancedOptionCount]);
    const toggleFocusedAdvancedOption = useCallback(() => {
        switch (focusedConfigIndex) {
            case 0:
                setThinkingEnabled((v) => !v);
                break;
            case 1:
                setModalityEnabled((v) => !v);
                break;
            case 2:
                setModalityImage((v) => !v);
                break;
            case 3:
                setModalityVideo((v) => !v);
                break;
            case 4:
                setModalityAudio((v) => !v);
                break;
            case 5:
                setModalityPdf((v) => !v);
                break;
            default:
                break;
        }
    }, [focusedConfigIndex]);
    const submitAdvancedConfig = useCallback(() => {
        goNext();
    }, [goNext]);
    // -- Final submit ---------------------------------------------------------
    const changeContextWindowSize = useCallback((value) => {
        setContextWindowSize(value.replace(/[^0-9]/g, ''));
    }, []);
    const submit = useCallback(() => {
        if (!provider)
            return;
        const multimodal = modalityEnabled
            ? {
                image: modalityImage || undefined,
                video: modalityVideo || undefined,
                audio: modalityAudio || undefined,
                pdf: modalityPdf || undefined,
            }
            : undefined;
        const ctxSize = parseInt(contextWindowSize, 10);
        // TODO: add maxTokens input field — type and buildInstallPlan support it but UI is deferred
        const hasAdvanced = thinkingEnabled || modalityEnabled || (ctxSize > 0 && !isNaN(ctxSize));
        const advancedConfig = hasAdvanced
            ? {
                enableThinking: thinkingEnabled || undefined,
                multimodal,
                contextWindowSize: ctxSize > 0 && !isNaN(ctxSize) ? ctxSize : undefined,
            }
            : undefined;
        void onSubmit(provider, buildCurrentInputs({ advancedConfig }));
    }, [
        provider,
        thinkingEnabled,
        modalityEnabled,
        modalityImage,
        modalityVideo,
        modalityAudio,
        modalityPdf,
        contextWindowSize,
        onSubmit,
        buildCurrentInputs,
    ]);
    // -- Preview JSON (for review step) ---------------------------------------
    const getPreviewJson = useCallback(() => {
        if (!provider)
            return '';
        const envKey = typeof provider.envKey === 'function'
            ? provider.envKey(protocol, baseUrl.trim())
            : provider.envKey;
        const normalizedIds = normalizeModelIds(modelIds);
        const masked = maskApiKey(apiKey);
        const genConfig = {};
        if (thinkingEnabled)
            genConfig['extra_body'] = { enable_thinking: true };
        if (modalityEnabled) {
            const mod = {};
            if (modalityImage)
                mod['image'] = true;
            if (modalityVideo)
                mod['video'] = true;
            if (modalityAudio)
                mod['audio'] = true;
            if (modalityPdf)
                mod['pdf'] = true;
            if (Object.keys(mod).length > 0)
                genConfig['modalities'] = mod;
        }
        const ctxSize = parseInt(contextWindowSize, 10);
        if (ctxSize > 0 && !isNaN(ctxSize))
            genConfig['contextWindowSize'] = ctxSize;
        const hasGenConfig = Object.keys(genConfig).length > 0;
        const models = normalizedIds.map((id) => {
            const entry = {
                id,
                name: id,
                baseUrl: baseUrl.trim(),
                envKey,
            };
            if (hasGenConfig)
                entry['generationConfig'] = genConfig;
            return entry;
        });
        return JSON.stringify({
            env: { [envKey]: masked },
            modelProviders: { [protocol]: models },
            security: { auth: { selectedType: protocol } },
            model: { name: normalizedIds[0] },
        }, null, 2);
    }, [
        provider,
        protocol,
        baseUrl,
        apiKey,
        modelIds,
        thinkingEnabled,
        modalityEnabled,
        modalityImage,
        modalityVideo,
        modalityAudio,
        modalityPdf,
        contextWindowSize,
    ]);
    // -- State ----------------------------------------------------------------
    const state = {
        provider,
        step: currentStep,
        stepIndex: stepIndex + 1, // 1-based for display
        totalSteps: visibleSteps.length,
        protocol,
        baseUrl,
        baseUrlOptionIndex,
        baseUrlError,
        apiKey,
        apiKeyError,
        modelIds,
        modelIdsError,
        thinkingEnabled,
        modalityEnabled,
        modalityImage,
        modalityVideo,
        modalityAudio,
        modalityPdf,
        contextWindowSize,
        focusedConfigIndex,
        previewJson: currentStep === 'review' ? getPreviewJson() : '',
    };
    return {
        state,
        start,
        reset,
        goBack,
        selectProtocol,
        selectBaseUrl,
        highlightBaseUrl,
        submitBaseUrl,
        changeBaseUrl,
        changeApiKey,
        submitApiKey,
        changeModelIds,
        submitModelIds,
        moveAdvancedFocusUp,
        moveAdvancedFocusDown,
        toggleFocusedAdvancedOption,
        changeContextWindowSize,
        submitAdvancedConfig,
        submit,
    };
}
//# sourceMappingURL=useProviderSetupFlow.js.map