import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useState, useEffect, useMemo, useRef, useCallback } from "react";
import { Button } from "../../../components/ui/button";
import { SettingsPanelLayout } from "../SettingsPanelLayout";
import { Input } from "../../../components/ui/input";
import { Select } from "../../../components/ui/select";
import { Dialog, DialogContent, DialogFooter, } from "../../../components/ui/dialog";
import { StyledDialogTitle } from "../../../components/ui/styled-dialog-title";
import { setupWizardService, } from "../../../setup/services/setupWizardService";
import { CheckCircle, Plus, RefreshCw } from "lucide-react";
import { DeleteIcon } from "../../../components/ui/delete-icon";
import { useEditContext } from "../../client/editContext";
import { useSearchParams } from "../../client/navigation";
import { Splitter } from "../../ui/Splitter";
import { ProviderConfigPanel } from "./ProviderConfigPanel";
import { ProviderIcon, resolveBrand } from "./ProviderIcon";
import { useRequiredSettingsHeaderActions } from "../SettingsHeaderActionsContext";
const SELECTED_PROVIDER_QUERY_PARAM = "providerId";
/**
 * Settings panel for AI Providers configuration.
 * Configure AI providers (Anthropic, OpenAI, OpenRouter, Google Vertex AI).
 */
export function ProvidersPanel() {
    const editContext = useEditContext();
    const setSettingsHeaderActions = useRequiredSettingsHeaderActions();
    const searchParams = useSearchParams();
    const [state, setState] = useState("loading");
    const [providers, setProviders] = useState([]);
    const [providerTypes, setProviderTypes] = useState([]);
    const [error, setError] = useState(null);
    const [showForm, setShowForm] = useState(false);
    const [creating, setCreating] = useState(false);
    const [deleting, setDeleting] = useState(null);
    const [formData, setFormData] = useState({
        type: "",
        name: "",
        apiKey: "",
        connectionString: "",
        baseUrl: "",
    });
    const prevShowFormRef = useRef(false);
    // URL-synced provider selection
    const [urlSelectedProviderId, setUrlSelectedProviderId] = useState(searchParams.get(SELECTED_PROVIDER_QUERY_PARAM) ||
        (typeof window !== "undefined"
            ? new URLSearchParams(window.location.search).get(SELECTED_PROVIDER_QUERY_PARAM)
            : null));
    const [selectedProvider, setSelectedProvider] = useState(null);
    const createEmptyFormData = useCallback(() => ({
        type: "",
        name: "",
        apiKey: "",
        connectionString: "",
        baseUrl: "",
    }), []);
    useEffect(() => {
        const key = searchParams.get(SELECTED_PROVIDER_QUERY_PARAM) ||
            (typeof window !== "undefined"
                ? new URLSearchParams(window.location.search).get(SELECTED_PROVIDER_QUERY_PARAM)
                : null);
        setUrlSelectedProviderId(key);
    }, [searchParams]);
    useEffect(() => {
        if (typeof window === "undefined")
            return;
        const handlePopState = () => {
            setUrlSelectedProviderId(new URLSearchParams(window.location.search).get(SELECTED_PROVIDER_QUERY_PARAM));
        };
        window.addEventListener("popstate", handlePopState);
        return () => window.removeEventListener("popstate", handlePopState);
    }, []);
    useEffect(() => {
        if (!urlSelectedProviderId) {
            if (selectedProvider)
                setSelectedProvider(null);
            return;
        }
        const match = providers.find((p) => p.id === urlSelectedProviderId);
        if (match && selectedProvider?.id !== match.id) {
            setSelectedProvider(match);
        }
    }, [providers, urlSelectedProviderId, selectedProvider]);
    const updateSelectedProviderUrl = useCallback((providerId) => {
        editContext?.updateUrl({
            [SELECTED_PROVIDER_QUERY_PARAM]: providerId || undefined,
        });
        setUrlSelectedProviderId(providerId || null);
    }, [editContext]);
    const handleOpenConfig = (provider) => {
        setSelectedProvider(provider);
        updateSelectedProviderUrl(provider.id);
    };
    const handleCloseConfig = () => {
        setSelectedProvider(null);
        updateSelectedProviderUrl(null);
    };
    // Get the selected provider type's default base URL
    const selectedProviderType = useMemo(() => providerTypes.find((p) => p.providerId === formData.type), [providerTypes, formData.type]);
    const loadData = async () => {
        try {
            setState("loading");
            setError(null);
            const [providersData, providerTypesData] = await Promise.all([
                setupWizardService.getProviders(),
                setupWizardService.getProviderTypes(),
            ]);
            setProviders(providersData);
            setProviderTypes(providerTypesData);
            setState("success");
        }
        catch (e) {
            setState("error");
            setError(e?.message || "Failed to load data");
        }
    };
    const handleCreate = async () => {
        if (!formData.type ||
            !formData.name ||
            (!formData.apiKey && !formData.connectionString)) {
            setError("Provider type, name, and at least one secret source are required");
            return;
        }
        try {
            setCreating(true);
            setError(null);
            const baseUrl = formData.baseUrl || selectedProviderType?.defaultBaseUrl || "";
            await setupWizardService.createProvider({
                ...formData,
                baseUrl,
            });
            setFormData(createEmptyFormData());
            setShowForm(false);
            await loadData();
        }
        catch (e) {
            setError(e?.message || "Failed to create provider");
        }
        finally {
            setCreating(false);
        }
    };
    // Reset form when dialog opens (only when transitioning from closed to open)
    useEffect(() => {
        const wasClosed = !prevShowFormRef.current;
        const isOpen = showForm;
        if (isOpen && wasClosed) {
            setFormData(createEmptyFormData());
            setError(null);
        }
        prevShowFormRef.current = showForm;
    }, [createEmptyFormData, showForm]);
    const handleDelete = (providerId) => {
        editContext?.confirm({
            header: "Delete Provider",
            message: "Are you sure you want to delete this provider?",
            acceptLabel: "Delete",
            showCancel: true,
            accept: async () => {
                try {
                    setDeleting(providerId);
                    setError(null);
                    await setupWizardService.deleteProvider(providerId);
                    await loadData();
                }
                catch (e) {
                    setError(e?.message || "Failed to delete provider");
                }
                finally {
                    setDeleting(null);
                }
            },
        });
    };
    useEffect(() => {
        loadData();
    }, []);
    // Build provider type options
    const providerTypeOptions = useMemo(() => providerTypes.map((p) => ({
        value: p.providerId,
        label: p.displayName,
    })), [providerTypes]);
    const addProviderButton = useMemo(() => (_jsxs(Button, { size: "sm", variant: "default", onClick: () => {
            setFormData(createEmptyFormData());
            setError(null);
            setShowForm(true);
        }, disabled: providerTypes.length === 0, title: "Add provider", children: [_jsx(Plus, { strokeWidth: 1.75, className: "mr-1 h-4 w-4" }), "Add provider"] })), [providerTypes.length, createEmptyFormData]);
    // Surface the primary "Add" action in the settings header bar (desktop only;
    // a mobile fallback lives in the card header below).
    useEffect(() => {
        if (!setSettingsHeaderActions)
            return;
        setSettingsHeaderActions(addProviderButton);
        return () => {
            setSettingsHeaderActions(null);
        };
    }, [addProviderButton, setSettingsHeaderActions]);
    // Build the providers list content
    const providersListContent = (_jsxs(SettingsPanelLayout, { children: [_jsxs("div", { className: "flex flex-col rounded-lg bg-white", children: [_jsx("div", { className: "border-border-default flex justify-end border-b p-4 md:hidden", children: addProviderButton }), providerTypes.length === 0 && state === "success" && (_jsx("div", { className: "border-feedback-orange bg-feedback-orange-light text-feedback-orange mx-4 mt-4 mb-3 rounded border p-3 text-xs", children: "No provider types are available. Please check the server configuration." })), error && !showForm && (_jsx("div", { className: "border-feedback-red bg-feedback-red-light text-feedback-red mx-4 mt-4 mb-3 rounded border p-2 text-xs whitespace-pre-wrap", children: error })), _jsx("div", { className: "px-4 py-3", children: providers.length === 0 && state === "success" ? (_jsx("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: _jsx("p", { className: "text-neutral-grey-50 text-sm", children: "No providers configured yet." }) })) : (_jsx("div", { className: "divide-border-default divide-y", children: providers.map((provider) => {
                                const providerType = providerTypes.find((p) => p.providerId === provider.type);
                                const brand = resolveBrand(provider.type, providerType?.displayName, provider.name);
                                const providerTypeDisplayName = providerType?.displayName ||
                                    brand?.label ||
                                    provider.type ||
                                    "Unknown";
                                const isSelected = selectedProvider?.id === provider.id;
                                // Fall back to the provider type's default endpoint when no
                                // base URL is stored on the provider record itself.
                                const displayBaseUrl = provider.baseUrl || providerType?.defaultBaseUrl || "";
                                const isDefaultBaseUrl = !provider.baseUrl && !!displayBaseUrl;
                                return (_jsxs("div", { role: "button", tabIndex: 0, onClick: () => handleOpenConfig(provider), onKeyDown: (e) => {
                                        if (e.key === "Enter" || e.key === " ") {
                                            e.preventDefault();
                                            handleOpenConfig(provider);
                                        }
                                    }, className: `group focus-visible:ring-feedback-blue flex cursor-pointer items-center gap-3 px-3 py-3 text-sm transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-inset ${isSelected
                                        ? "bg-neutral-grey-5"
                                        : "hover:bg-neutral-grey-5 bg-white"}`, children: [_jsx(ProviderIcon, { providerId: provider.type, displayName: providerTypeDisplayName, providerName: provider.name, size: 24 }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [_jsx("span", { className: "text-neutral-grey-100 truncate font-medium", children: provider.name }), _jsx("span", { className: "bg-neutral-grey-5 badge-pad-sm text-neutral-grey-50 shrink-0 rounded text-[10px] font-medium", children: providerTypeDisplayName })] }), displayBaseUrl && (_jsxs("div", { className: `text-neutral-grey-50 mt-0.5 truncate font-mono text-xs ${isDefaultBaseUrl ? "italic" : ""}`, title: isDefaultBaseUrl
                                                        ? `${displayBaseUrl} (provider type default)`
                                                        : displayBaseUrl, children: [displayBaseUrl, isDefaultBaseUrl && (_jsx("span", { className: "not-italic", children: " (default)" }))] }))] }), _jsx("div", { className: "flex shrink-0 items-center gap-0.5 opacity-0 transition-opacity group-focus-within:opacity-100 group-hover:opacity-100", children: _jsx(Button, { size: "sm", variant: "ghost", onClick: (e) => {
                                                    e.stopPropagation();
                                                    handleDelete(provider.id);
                                                }, disabled: deleting === provider.id, title: "Delete provider", className: "text-neutral-grey-50 hover:bg-neutral-grey-5 hover:text-neutral-grey-50", children: deleting === provider.id ? (_jsx(RefreshCw, { strokeWidth: 1, className: "h-3.5 w-3.5 animate-spin" })) : (_jsx(DeleteIcon, { size: "md" })) }) })] }, provider.id));
                            }) })) })] }), _jsx(Dialog, { open: showForm, onOpenChange: (open) => {
                    setShowForm(open);
                    if (open) {
                        setFormData(createEmptyFormData());
                        setError(null);
                    }
                }, children: _jsxs(DialogContent, { className: "max-w-xl", children: [_jsx(StyledDialogTitle, { icon: _jsx(Plus, { strokeWidth: 1 }), title: "Add Provider" }), _jsxs("div", { className: "flex flex-col gap-6 p-8", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: "provider-type", className: "text-neutral-grey-100 mb-1 block text-sm font-medium", children: "Provider Type" }), _jsx(Select, { id: "provider-type", value: formData.type, onValueChange: (value) => {
                                                const providerType = providerTypes.find((p) => p.providerId === value);
                                                setFormData((prev) => ({
                                                    ...prev,
                                                    type: value,
                                                    name: prev.name || providerType?.displayName || value,
                                                }));
                                            }, options: providerTypeOptions, placeholder: "Select provider type" })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "provider-name", className: "text-neutral-grey-100 mb-1 block text-sm font-medium", children: "Name" }), _jsx(Input, { id: "provider-name", value: formData.name, onChange: (e) => setFormData({ ...formData, name: e.target.value }), placeholder: "My Provider" })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "provider-config-value-input", className: "text-neutral-grey-100 mb-1 block text-sm font-medium", children: "API Key (optional)" }), _jsx(Input, { id: "provider-config-value-input", type: "text", name: "provider-config-value", autoComplete: "off", autoCapitalize: "none", spellCheck: false, className: formData.apiKey ? "[-webkit-text-security:disc]" : undefined, value: formData.apiKey || "", onChange: (e) => setFormData({ ...formData, apiKey: e.target.value }), placeholder: "sk-..." })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "provider-connection-string-input", className: "text-neutral-grey-100 mb-1 block text-sm font-medium", children: "Connection String Name (optional)" }), _jsx(Input, { id: "provider-connection-string-input", type: "text", value: formData.connectionString || "", onChange: (e) => setFormData({
                                                ...formData,
                                                connectionString: e.target.value,
                                            }), placeholder: "parhelia.ai.provider.<providerId>" }), _jsx("p", { className: "text-neutral-grey-50 mt-1 text-xs", children: "Provide at least one secret source. Runtime resolution is Sitecore first, then ConnectionStrings.config." })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "provider-baseurl", className: "text-neutral-grey-100 mb-1 block text-sm font-medium", children: "Base URL (optional)" }), _jsx(Input, { id: "provider-baseurl", value: formData.baseUrl, onChange: (e) => setFormData({ ...formData, baseUrl: e.target.value }), placeholder: selectedProviderType?.defaultBaseUrl || "" })] }), error && (_jsx("div", { className: "border-feedback-red bg-feedback-red-light text-feedback-red rounded border p-3 text-sm", children: error }))] }), _jsxs(DialogFooter, { className: "px-6 pb-6", children: [_jsx(Button, { variant: "outline", onClick: () => {
                                        setShowForm(false);
                                        setFormData(createEmptyFormData());
                                        setError(null);
                                    }, children: "Cancel" }), _jsx(Button, { onClick: handleCreate, disabled: creating ||
                                        !formData.name ||
                                        (!formData.apiKey && !formData.connectionString) ||
                                        !formData.type, children: creating ? (_jsxs(_Fragment, { children: [_jsx(RefreshCw, { strokeWidth: 1, className: "mr-2 h-4 w-4 animate-spin" }), "Creating..."] })) : (_jsxs(_Fragment, { children: [_jsx(CheckCircle, { strokeWidth: 1, className: "mr-2 h-4 w-4" }), "Create"] })) })] })] }) })] }));
    // Build splitter panels - only show config panel when a provider is selected
    const panels = selectedProvider?.id
        ? [
            {
                name: "providers-list",
                defaultSize: "auto",
                content: providersListContent,
                className: "overflow-hidden",
            },
            {
                name: "provider-config",
                defaultSize: 400,
                content: (_jsx(ProviderConfigPanel, { itemId: selectedProvider.id, title: `Configure: ${selectedProvider.name || "Provider"}`, onClose: handleCloseConfig }, selectedProvider.id)),
                className: "overflow-hidden",
            },
        ]
        : [
            {
                name: "providers-list",
                defaultSize: "auto",
                content: providersListContent,
                className: "overflow-hidden",
            },
        ];
    return (_jsx(Splitter, { panels: panels, localStorageKey: "providers-panel-splitter", direction: "horizontal", className: "h-full" }));
}
export default ProvidersPanel;
//# sourceMappingURL=ProvidersPanel.js.map