import React, { useState, useEffect, useRef, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Provider, ProviderCategory, CustomEndpoint } from "../types";
import { AppType } from "../lib/tauri-api";
import {
  updateCommonConfigSnippet,
  hasCommonConfigSnippet,
  getApiKeyFromConfig,
  hasApiKeyField,
  setApiKeyInConfig,
  updateTomlCommonConfigSnippet,
  hasTomlCommonConfigSnippet,
  validateJsonConfig,
  applyTemplateValues,
  extractCodexBaseUrl,
  setCodexBaseUrl as setCodexBaseUrlInConfig,
} from "../utils/providerConfigUtils";
import { providerPresets } from "../config/providerPresets";
import type { TemplateValueConfig } from "../config/providerPresets";
import {
  codexProviderPresets,
  generateThirdPartyAuth,
  generateThirdPartyConfig,
} from "../config/codexProviderPresets";
import PresetSelector from "./ProviderForm/PresetSelector";
import ApiKeyInput from "./ProviderForm/ApiKeyInput";
import ClaudeConfigEditor from "./ProviderForm/ClaudeConfigEditor";
import CodexConfigEditor from "./ProviderForm/CodexConfigEditor";
import KimiModelSelector from "./ProviderForm/KimiModelSelector";
import { X, AlertCircle, Save, Zap } from "lucide-react";
import { isLinux } from "../lib/platform";
import EndpointSpeedTest, {
  EndpointCandidate,
} from "./ProviderForm/EndpointSpeedTest";
// 分类仅用于控制少量交互（如官方禁用 API Key），不显示介绍组件

type TemplateValueMap = Record<string, TemplateValueConfig>;

type TemplatePath = Array<string | number>;

const collectTemplatePaths = (
  source: unknown,
  templateKeys: string[],
  currentPath: TemplatePath = [],
  acc: TemplatePath[] = [],
): TemplatePath[] => {
  if (typeof source === "string") {
    const hasPlaceholder = templateKeys.some((key) =>
      source.includes(`\${${key}}`),
    );
    if (hasPlaceholder) {
      acc.push([...currentPath]);
    }
    return acc;
  }

  if (Array.isArray(source)) {
    source.forEach((item, index) =>
      collectTemplatePaths(item, templateKeys, [...currentPath, index], acc),
    );
    return acc;
  }

  if (source && typeof source === "object") {
    Object.entries(source).forEach(([key, value]) =>
      collectTemplatePaths(value, templateKeys, [...currentPath, key], acc),
    );
  }

  return acc;
};

const getValueAtPath = (source: any, path: TemplatePath) => {
  return path.reduce<any>((acc, key) => {
    if (acc === undefined || acc === null) {
      return undefined;
    }
    return acc[key as keyof typeof acc];
  }, source);
};

const setValueAtPath = (
  target: any,
  path: TemplatePath,
  value: unknown,
): any => {
  if (path.length === 0) {
    return value;
  }

  let current = target;

  for (let i = 0; i < path.length - 1; i++) {
    const key = path[i];
    const nextKey = path[i + 1];
    const isNextIndex = typeof nextKey === "number";

    if (current[key as keyof typeof current] === undefined) {
      current[key as keyof typeof current] = isNextIndex ? [] : {};
    } else {
      const currentValue = current[key as keyof typeof current];
      if (isNextIndex && !Array.isArray(currentValue)) {
        current[key as keyof typeof current] = [];
      } else if (
        !isNextIndex &&
        (typeof currentValue !== "object" || currentValue === null)
      ) {
        current[key as keyof typeof current] = {};
      }
    }

    current = current[key as keyof typeof current];
  }

  const finalKey = path[path.length - 1];
  current[finalKey as keyof typeof current] = value;
  return target;
};

const applyTemplateValuesToConfigString = (
  presetConfig: any,
  currentConfigString: string,
  values: TemplateValueMap,
) => {
  const replacedConfig = applyTemplateValues(presetConfig, values);
  const templateKeys = Object.keys(values);
  if (templateKeys.length === 0) {
    return JSON.stringify(replacedConfig, null, 2);
  }

  const placeholderPaths = collectTemplatePaths(presetConfig, templateKeys);

  try {
    const parsedConfig = currentConfigString.trim()
      ? JSON.parse(currentConfigString)
      : {};
    let targetConfig: any;
    if (Array.isArray(parsedConfig)) {
      targetConfig = [...parsedConfig];
    } else if (parsedConfig && typeof parsedConfig === "object") {
      targetConfig = JSON.parse(JSON.stringify(parsedConfig));
    } else {
      targetConfig = {};
    }

    if (placeholderPaths.length === 0) {
      return JSON.stringify(targetConfig, null, 2);
    }

    let mutatedConfig = targetConfig;

    for (const path of placeholderPaths) {
      const nextValue = getValueAtPath(replacedConfig, path);
      if (path.length === 0) {
        mutatedConfig = nextValue;
      } else {
        setValueAtPath(mutatedConfig, path, nextValue);
      }
    }

    return JSON.stringify(mutatedConfig, null, 2);
  } catch {
    return JSON.stringify(replacedConfig, null, 2);
  }
};

const COMMON_CONFIG_STORAGE_KEY = "cc-switch:common-config-snippet";
const CODEX_COMMON_CONFIG_STORAGE_KEY = "cc-switch:codex-common-config-snippet";
const DEFAULT_COMMON_CONFIG_SNIPPET = `{
  "includeCoAuthoredBy": false
}`;
const DEFAULT_CODEX_COMMON_CONFIG_SNIPPET = `# Common Codex config
# Add your common TOML configuration here`;

interface ProviderFormProps {
  appType?: AppType;
  title: string;
  submitText: string;
  initialData?: Provider;
  showPresets?: boolean;
  onSubmit: (data: Omit<Provider, "id">) => void;
  onClose: () => void;
}

const ProviderForm: React.FC<ProviderFormProps> = ({
  appType = "claude",
  title,
  submitText,
  initialData,
  showPresets = false,
  onSubmit,
  onClose,
}) => {
  const { t } = useTranslation();
  // 对于 Codex，需要分离 auth 和 config
  const isCodex = appType === "codex";

  const [formData, setFormData] = useState({
    name: initialData?.name || "",
    websiteUrl: initialData?.websiteUrl || "",
    settingsConfig: initialData
      ? JSON.stringify(initialData.settingsConfig, null, 2)
      : "",
  });
  const [category, setCategory] = useState<ProviderCategory | undefined>(
    initialData?.category,
  );

  // Claude 模型配置状态
  const [claudeModel, setClaudeModel] = useState("");
  const [claudeSmallFastModel, setClaudeSmallFastModel] = useState("");
  const [baseUrl, setBaseUrl] = useState(""); // 新增：基础 URL 状态
  // 模板变量状态
  const [templateValues, setTemplateValues] = useState<
    Record<string, TemplateValueConfig>
  >({});

  // Codex 特有的状态
  const [codexAuth, setCodexAuthState] = useState("");
  const [codexConfig, setCodexConfigState] = useState("");
  const [codexApiKey, setCodexApiKey] = useState("");
  const [codexBaseUrl, setCodexBaseUrl] = useState("");
  const [isCodexTemplateModalOpen, setIsCodexTemplateModalOpen] =
    useState(false);
  // 新建供应商：收集端点测速弹窗中的“自定义端点”，提交时一次性落盘到 meta.custom_endpoints
  const [draftCustomEndpoints, setDraftCustomEndpoints] = useState<string[]>(
    [],
  );
  // 端点测速弹窗状态
  const [isEndpointModalOpen, setIsEndpointModalOpen] = useState(false);
  const [isCodexEndpointModalOpen, setIsCodexEndpointModalOpen] =
    useState(false);
  // -1 表示自定义，null 表示未选择，>= 0 表示预设索引
  const [selectedCodexPreset, setSelectedCodexPreset] = useState<number | null>(
    showPresets && isCodex ? -1 : null,
  );

  const setCodexAuth = (value: string) => {
    setCodexAuthState(value);
    setCodexAuthError(validateCodexAuth(value));
  };

  const setCodexConfig = (value: string | ((prev: string) => string)) => {
    setCodexConfigState((prev) =>
      typeof value === "function"
        ? (value as (input: string) => string)(prev)
        : value,
    );
  };

  const setCodexCommonConfigSnippet = (value: string) => {
    setCodexCommonConfigSnippetState(value);
  };

  // 初始化 Codex 配置
  useEffect(() => {
    if (isCodex && initialData) {
      const config = initialData.settingsConfig;
      if (typeof config === "object" && config !== null) {
        setCodexAuth(JSON.stringify(config.auth || {}, null, 2));
        setCodexConfig(config.config || "");
        const initialBaseUrl = extractCodexBaseUrl(config.config);
        if (initialBaseUrl) {
          setCodexBaseUrl(initialBaseUrl);
        }
        try {
          const auth = config.auth || {};
          if (auth && typeof auth.OPENAI_API_KEY === "string") {
            setCodexApiKey(auth.OPENAI_API_KEY);
          }
        } catch {
          // ignore
        }
      }
    }
  }, [isCodex, initialData]);

  const [error, setError] = useState("");
  const [useCommonConfig, setUseCommonConfig] = useState(false);
  const [commonConfigSnippet, setCommonConfigSnippet] = useState<string>(() => {
    if (typeof window === "undefined") {
      return DEFAULT_COMMON_CONFIG_SNIPPET;
    }
    try {
      const stored = window.localStorage.getItem(COMMON_CONFIG_STORAGE_KEY);
      if (stored && stored.trim()) {
        return stored;
      }
    } catch {
      // ignore localStorage 读取失败
    }
    return DEFAULT_COMMON_CONFIG_SNIPPET;
  });
  const [commonConfigError, setCommonConfigError] = useState("");
  const [settingsConfigError, setSettingsConfigError] = useState("");
  // 用于跟踪是否正在通过通用配置更新
  const isUpdatingFromCommonConfig = useRef(false);

  // Codex 通用配置状态
  const [useCodexCommonConfig, setUseCodexCommonConfig] = useState(false);
  const [codexCommonConfigSnippet, setCodexCommonConfigSnippetState] =
    useState<string>(() => {
      if (typeof window === "undefined") {
        return DEFAULT_CODEX_COMMON_CONFIG_SNIPPET.trim();
      }
      try {
        const stored = window.localStorage.getItem(
          CODEX_COMMON_CONFIG_STORAGE_KEY,
        );
        if (stored && stored.trim()) {
          return stored.trim();
        }
      } catch {
        // ignore localStorage 读取失败
      }
      return DEFAULT_CODEX_COMMON_CONFIG_SNIPPET.trim();
    });
  const [codexCommonConfigError, setCodexCommonConfigError] = useState("");
  const isUpdatingFromCodexCommonConfig = useRef(false);
  const isUpdatingBaseUrlRef = useRef(false);
  const isUpdatingCodexBaseUrlRef = useRef(false);

  // -1 表示自定义，null 表示未选择，>= 0 表示预设索引
  const [selectedPreset, setSelectedPreset] = useState<number | null>(
    showPresets ? -1 : null,
  );
  const [apiKey, setApiKey] = useState("");
  const [codexAuthError, setCodexAuthError] = useState("");

  // Kimi 模型选择状态
  const [kimiAnthropicModel, setKimiAnthropicModel] = useState("");
  const [kimiAnthropicSmallFastModel, setKimiAnthropicSmallFastModel] =
    useState("");

  const validateSettingsConfig = (value: string): string => {
    const err = validateJsonConfig(value, "配置内容");
    return err ? t("providerForm.configJsonError") : "";
  };

  const validateCodexAuth = (value: string): string => {
    if (!value.trim()) return "";
    try {
      const parsed = JSON.parse(value);
      if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
        return t("providerForm.authJsonRequired");
      }
      return "";
    } catch {
      return t("providerForm.authJsonError");
    }
  };

  const updateSettingsConfigValue = (value: string) => {
    setFormData((prev) => ({
      ...prev,
      settingsConfig: value,
    }));
    setSettingsConfigError(validateSettingsConfig(value));
  };

  // 初始化自定义模式的默认配置
  useEffect(() => {
    if (
      showPresets &&
      selectedPreset === -1 &&
      !initialData &&
      formData.settingsConfig === ""
    ) {
      // 设置自定义模板
      const customTemplate = {
        env: {
          ANTHROPIC_BASE_URL: "https://your-api-endpoint.com",
          ANTHROPIC_AUTH_TOKEN: "",
          // 可选配置
          // ANTHROPIC_MODEL: "your-model-name",
          // ANTHROPIC_SMALL_FAST_MODEL: "your-fast-model-name"
        },
      };
      const templateString = JSON.stringify(customTemplate, null, 2);

      updateSettingsConfigValue(templateString);
      setApiKey("");
    }
  }, []); // 只在组件挂载时执行一次

  // 初始化时检查通用配置片段
  useEffect(() => {
    if (initialData) {
      if (!isCodex) {
        const configString = JSON.stringify(
          initialData.settingsConfig,
          null,
          2,
        );
        const hasCommon = hasCommonConfigSnippet(
          configString,
          commonConfigSnippet,
        );
        setUseCommonConfig(hasCommon);
        setSettingsConfigError(validateSettingsConfig(configString));

        // 初始化模型配置（编辑模式）
        if (
          initialData.settingsConfig &&
          typeof initialData.settingsConfig === "object"
        ) {
          const config = initialData.settingsConfig as {
            env?: Record<string, any>;
          };
          if (config.env) {
            setClaudeModel(config.env.ANTHROPIC_MODEL || "");
            setClaudeSmallFastModel(
              config.env.ANTHROPIC_SMALL_FAST_MODEL || "",
            );
            setBaseUrl(config.env.ANTHROPIC_BASE_URL || ""); // 初始化基础 URL

            // 初始化 Kimi 模型选择
            setKimiAnthropicModel(config.env.ANTHROPIC_MODEL || "");
            setKimiAnthropicSmallFastModel(
              config.env.ANTHROPIC_SMALL_FAST_MODEL || "",
            );
          }
        }
      } else {
        // Codex 初始化时检查 TOML 通用配置
        const hasCommon = hasTomlCommonConfigSnippet(
          codexConfig,
          codexCommonConfigSnippet,
        );
        setUseCodexCommonConfig(hasCommon);
      }
    }
  }, [
    initialData,
    commonConfigSnippet,
    codexCommonConfigSnippet,
    isCodex,
    codexConfig,
  ]);

  // 当选择预设变化时，同步类别
  useEffect(() => {
    if (!showPresets) return;
    if (!isCodex) {
      if (selectedPreset !== null && selectedPreset >= 0) {
        const preset = providerPresets[selectedPreset];
        setCategory(
          preset?.category || (preset?.isOfficial ? "official" : undefined),
        );
      } else if (selectedPreset === -1) {
        setCategory("custom");
      }
    } else {
      if (selectedCodexPreset !== null && selectedCodexPreset >= 0) {
        const preset = codexProviderPresets[selectedCodexPreset];
        setCategory(
          preset?.category || (preset?.isOfficial ? "official" : undefined),
        );
      } else if (selectedCodexPreset === -1) {
        setCategory("custom");
      }
    }
  }, [showPresets, isCodex, selectedPreset, selectedCodexPreset]);

  // 与 JSON 配置保持基础 URL 同步（Claude 第三方/自定义）
  useEffect(() => {
    if (isCodex) return;
    const currentCategory = category ?? initialData?.category;
    if (currentCategory !== "third_party" && currentCategory !== "custom") {
      return;
    }
    if (isUpdatingBaseUrlRef.current) {
      return;
    }
    try {
      const config = JSON.parse(formData.settingsConfig || "{}");
      const envUrl: unknown = config?.env?.ANTHROPIC_BASE_URL;
      if (typeof envUrl === "string" && envUrl && envUrl !== baseUrl) {
        setBaseUrl(envUrl.trim());
      }
    } catch {
      // ignore JSON parse errors
    }
  }, [isCodex, category, initialData, formData.settingsConfig, baseUrl]);

  // 与 TOML 配置保持基础 URL 同步（Codex 第三方/自定义）
  useEffect(() => {
    if (!isCodex) return;
    const currentCategory = category ?? initialData?.category;
    if (currentCategory !== "third_party" && currentCategory !== "custom") {
      return;
    }
    if (isUpdatingCodexBaseUrlRef.current) {
      return;
    }
    const extracted = extractCodexBaseUrl(codexConfig) || "";
    if (extracted !== codexBaseUrl) {
      setCodexBaseUrl(extracted);
    }
  }, [isCodex, category, initialData, codexConfig, codexBaseUrl]);

  // 同步本地存储的通用配置片段
  useEffect(() => {
    if (typeof window === "undefined") return;
    try {
      if (commonConfigSnippet.trim()) {
        window.localStorage.setItem(
          COMMON_CONFIG_STORAGE_KEY,
          commonConfigSnippet,
        );
      } else {
        window.localStorage.removeItem(COMMON_CONFIG_STORAGE_KEY);
      }
    } catch {
      // ignore
    }
  }, [commonConfigSnippet]);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    setError("");

    if (!formData.name) {
      setError(t("providerForm.fillSupplierName"));
      return;
    }

    let settingsConfig: Record<string, any>;

    if (isCodex) {
      const currentAuthError = validateCodexAuth(codexAuth);
      setCodexAuthError(currentAuthError);
      if (currentAuthError) {
        setError(currentAuthError);
        return;
      }
      // Codex: 仅要求 auth.json 必填；config.toml 可为空
      if (!codexAuth.trim()) {
        setError(t("providerForm.fillAuthJson"));
        return;
      }

      try {
        const authJson = JSON.parse(codexAuth);

        // 非官方预设强制要求 OPENAI_API_KEY
        if (selectedCodexPreset !== null) {
          const preset = codexProviderPresets[selectedCodexPreset];
          const isOfficial = Boolean(preset?.isOfficial);
          if (!isOfficial) {
            const key =
              typeof authJson.OPENAI_API_KEY === "string"
                ? authJson.OPENAI_API_KEY.trim()
                : "";
            if (!key) {
              setError(t("providerForm.fillApiKey"));
              return;
            }
          }
        }

        settingsConfig = {
          auth: authJson,
          config: codexConfig ?? "",
        };
      } catch (err) {
        setError(t("providerForm.authJsonError"));
        return;
      }
    } else {
      const currentSettingsError = validateSettingsConfig(
        formData.settingsConfig,
      );
      setSettingsConfigError(currentSettingsError);
      if (currentSettingsError) {
        setError(t("providerForm.configJsonError"));
        return;
      }

      if (selectedTemplatePreset && templateValueEntries.length > 0) {
        for (const [key, config] of templateValueEntries) {
          const entry = templateValues[key];
          const resolvedValue = (
            entry?.editorValue ??
            entry?.defaultValue ??
            config.defaultValue ??
            ""
          ).trim();
          if (!resolvedValue) {
            setError(t("providerForm.fillParameter", { label: config.label }));
            return;
          }
        }
      }
      // Claude: 原有逻辑
      if (!formData.settingsConfig.trim()) {
        setError(t("providerForm.fillConfigContent"));
        return;
      }

      try {
        settingsConfig = JSON.parse(formData.settingsConfig);
      } catch (err) {
        setError(t("providerForm.configJsonError"));
        return;
      }
    }

    // 构造基础提交数据
    const basePayload: Omit<Provider, "id"> = {
      name: formData.name,
      websiteUrl: formData.websiteUrl,
      settingsConfig,
      // 仅在用户选择了预设或手动选择“自定义”时持久化分类
      ...(category ? { category } : {}),
    };

    // 若为"新建供应商"，将端点候选一并随提交落盘到 meta.custom_endpoints：
    // - 用户在弹窗中新增的自定义端点（draftCustomEndpoints，已去重）
    // - 预设中的 endpointCandidates（若存在）
    // - 当前选中的基础 URL（baseUrl/codexBaseUrl）
    if (!initialData) {
      const urlSet = new Set<string>();
      const push = (raw?: string) => {
        const url = (raw || "").trim().replace(/\/+$/, "");
        if (url) urlSet.add(url);
      };

      // 自定义端点（仅来自用户新增）
      for (const u of draftCustomEndpoints) push(u);

      // 预设端点候选
      if (!isCodex) {
        if (
          selectedPreset !== null &&
          selectedPreset >= 0 &&
          selectedPreset < providerPresets.length
        ) {
          const preset = providerPresets[selectedPreset] as any;
          if (Array.isArray(preset?.endpointCandidates)) {
            for (const u of preset.endpointCandidates as string[]) push(u);
          }
        }
        // 当前 Claude 基础地址
        push(baseUrl);
      } else {
        if (
          selectedCodexPreset !== null &&
          selectedCodexPreset >= 0 &&
          selectedCodexPreset < codexProviderPresets.length
        ) {
          const preset = codexProviderPresets[selectedCodexPreset] as any;
          if (Array.isArray(preset?.endpointCandidates)) {
            for (const u of preset.endpointCandidates as string[]) push(u);
          }
        }
        // 当前 Codex 基础地址
        push(codexBaseUrl);
      }

      const urls = Array.from(urlSet.values());
      if (urls.length > 0) {
        const now = Date.now();
        const customMap: Record<string, CustomEndpoint> = {};
        for (const url of urls) {
          if (!customMap[url]) {
            customMap[url] = { url, addedAt: now, lastUsed: undefined };
          }
        }
        onSubmit({ ...basePayload, meta: { custom_endpoints: customMap } });
        return;
      }
    }

    onSubmit(basePayload);
  };

  const handleChange = (
    e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
  ) => {
    const { name, value } = e.target;

    if (name === "settingsConfig") {
      // 只有在不是通过通用配置更新时，才检查并同步选择框状态
      if (!isUpdatingFromCommonConfig.current) {
        const hasCommon = hasCommonConfigSnippet(value, commonConfigSnippet);
        setUseCommonConfig(hasCommon);
      }

      // 同步 API Key 输入框显示与值
      const parsedKey = getApiKeyFromConfig(value);
      setApiKey(parsedKey);

      // 不再从 JSON 自动提取或覆盖官网地址，只更新配置内容
      updateSettingsConfigValue(value);
    } else {
      setFormData((prev) => ({
        ...prev,
        [name]: value,
      }));
    }
  };

  // 处理通用配置开关
  const handleCommonConfigToggle = (checked: boolean) => {
    const { updatedConfig, error: snippetError } = updateCommonConfigSnippet(
      formData.settingsConfig,
      commonConfigSnippet,
      checked,
    );

    if (snippetError) {
      setCommonConfigError(snippetError);
      if (snippetError.includes("配置 JSON 解析失败")) {
        setSettingsConfigError(t("providerForm.configJsonError"));
      }
      setUseCommonConfig(false);
      return;
    }

    setCommonConfigError("");
    setUseCommonConfig(checked);
    // 标记正在通过通用配置更新
    isUpdatingFromCommonConfig.current = true;
    updateSettingsConfigValue(updatedConfig);
    // 在下一个事件循环中重置标记
    setTimeout(() => {
      isUpdatingFromCommonConfig.current = false;
    }, 0);
  };

  const handleCommonConfigSnippetChange = (value: string) => {
    const previousSnippet = commonConfigSnippet;
    setCommonConfigSnippet(value);

    if (!value.trim()) {
      setCommonConfigError("");
      if (useCommonConfig) {
        const { updatedConfig } = updateCommonConfigSnippet(
          formData.settingsConfig,
          previousSnippet,
          false,
        );
        // 直接更新 formData，不通过 handleChange
        updateSettingsConfigValue(updatedConfig);
        setUseCommonConfig(false);
      }
      return;
    }

    // 验证JSON格式
    const validationError = validateJsonConfig(value, "通用配置片段");
    if (validationError) {
      setCommonConfigError(validationError);
    } else {
      setCommonConfigError("");
    }

    // 若当前启用通用配置且格式正确，需要替换为最新片段
    if (useCommonConfig && !validationError) {
      const removeResult = updateCommonConfigSnippet(
        formData.settingsConfig,
        previousSnippet,
        false,
      );
      if (removeResult.error) {
        setCommonConfigError(removeResult.error);
        if (removeResult.error.includes("配置 JSON 解析失败")) {
          setSettingsConfigError(t("providerForm.configJsonError"));
        }
        return;
      }
      const addResult = updateCommonConfigSnippet(
        removeResult.updatedConfig,
        value,
        true,
      );

      if (addResult.error) {
        setCommonConfigError(addResult.error);
        if (addResult.error.includes("配置 JSON 解析失败")) {
          setSettingsConfigError(t("providerForm.configJsonError"));
        }
        return;
      }

      // 标记正在通过通用配置更新，避免触发状态检查
      isUpdatingFromCommonConfig.current = true;
      updateSettingsConfigValue(addResult.updatedConfig);
      // 在下一个事件循环中重置标记
      setTimeout(() => {
        isUpdatingFromCommonConfig.current = false;
      }, 0);
    }

    // 保存通用配置到 localStorage
    if (!validationError && typeof window !== "undefined") {
      try {
        window.localStorage.setItem(COMMON_CONFIG_STORAGE_KEY, value);
      } catch {
        // ignore localStorage 写入失败
      }
    }
  };

  const applyPreset = (preset: (typeof providerPresets)[0], index: number) => {
    let appliedSettingsConfig = preset.settingsConfig;
    let initialTemplateValues: TemplateValueMap = {};

    if (preset.templateValues) {
      initialTemplateValues = Object.fromEntries(
        Object.entries(preset.templateValues).map(([key, config]) => [
          key,
          {
            ...config,
            editorValue: config.editorValue
              ? config.editorValue
              : (config.defaultValue ?? ""),
          },
        ]),
      );
      appliedSettingsConfig = applyTemplateValues(
        preset.settingsConfig,
        initialTemplateValues,
      );
    }

    setTemplateValues(initialTemplateValues);

    const configString = JSON.stringify(appliedSettingsConfig, null, 2);

    setFormData({
      name: preset.name,
      websiteUrl: preset.websiteUrl,
      settingsConfig: configString,
    });
    setSettingsConfigError(validateSettingsConfig(configString));
    setCategory(
      preset.category || (preset.isOfficial ? "official" : undefined),
    );

    // 设置选中的预设
    setSelectedPreset(index);

    // 清空 API Key 输入框，让用户重新输入
    setApiKey("");

    // 同步通用配置状态
    const hasCommon = hasCommonConfigSnippet(configString, commonConfigSnippet);
    setUseCommonConfig(hasCommon);
    setCommonConfigError("");

    // 如果预设包含模型配置，初始化模型输入框
    if (appliedSettingsConfig && typeof appliedSettingsConfig === "object") {
      const config = appliedSettingsConfig as { env?: Record<string, any> };
      if (config.env) {
        setClaudeModel(config.env.ANTHROPIC_MODEL || "");
        setClaudeSmallFastModel(config.env.ANTHROPIC_SMALL_FAST_MODEL || "");
        const presetBaseUrl =
          typeof config.env.ANTHROPIC_BASE_URL === "string"
            ? config.env.ANTHROPIC_BASE_URL
            : "";
        setBaseUrl(presetBaseUrl);

        // 如果是 Kimi 预设，同步 Kimi 模型选择
        if (preset.name?.includes("Kimi")) {
          setKimiAnthropicModel(config.env.ANTHROPIC_MODEL || "");
          setKimiAnthropicSmallFastModel(
            config.env.ANTHROPIC_SMALL_FAST_MODEL || "",
          );
        }
      } else {
        setClaudeModel("");
        setClaudeSmallFastModel("");
        setBaseUrl("");
      }
    }
  };

  // 处理点击自定义按钮
  const handleCustomClick = () => {
    setSelectedPreset(-1);
    setTemplateValues({});

    // 设置自定义模板
    const customTemplate = {
      env: {
        ANTHROPIC_BASE_URL: "https://your-api-endpoint.com",
        ANTHROPIC_AUTH_TOKEN: "",
        // 可选配置
        // ANTHROPIC_MODEL: "your-model-name",
        // ANTHROPIC_SMALL_FAST_MODEL: "your-fast-model-name"
      },
    };
    const templateString = JSON.stringify(customTemplate, null, 2);

    setFormData({
      name: "",
      websiteUrl: "",
      settingsConfig: templateString,
    });
    setSettingsConfigError(validateSettingsConfig(templateString));
    setApiKey("");
    setBaseUrl("https://your-api-endpoint.com"); // 设置默认的基础 URL
    setUseCommonConfig(false);
    setCommonConfigError("");
    setClaudeModel("");
    setClaudeSmallFastModel("");
    setKimiAnthropicModel("");
    setKimiAnthropicSmallFastModel("");
    setCategory("custom");
  };

  // Codex: 应用预设
  const applyCodexPreset = (
    preset: (typeof codexProviderPresets)[0],
    index: number,
  ) => {
    const authString = JSON.stringify(preset.auth || {}, null, 2);
    setCodexAuth(authString);
    setCodexConfig(preset.config || "");
    const presetBaseUrl = extractCodexBaseUrl(preset.config);
    if (presetBaseUrl) {
      setCodexBaseUrl(presetBaseUrl);
    }

    setFormData((prev) => ({
      ...prev,
      name: preset.name,
      websiteUrl: preset.websiteUrl,
    }));

    setSelectedCodexPreset(index);
    setCategory(
      preset.category || (preset.isOfficial ? "official" : undefined),
    );

    // 清空 API Key，让用户重新输入
    setCodexApiKey("");
  };

  // Codex: 处理点击自定义按钮
  const handleCodexCustomClick = () => {
    setSelectedCodexPreset(-1);

    // 设置自定义模板
    const customAuth = generateThirdPartyAuth("");
    const customConfig = generateThirdPartyConfig(
      "custom",
      "https://your-api-endpoint.com/v1",
      "gpt-5-codex",
    );

    setFormData({
      name: "",
      websiteUrl: "",
      settingsConfig: "",
    });
    setSettingsConfigError(validateSettingsConfig(""));
    setCodexAuth(JSON.stringify(customAuth, null, 2));
    setCodexConfig(customConfig);
    setCodexApiKey("");
    setCodexBaseUrl("https://your-api-endpoint.com/v1");
    setCategory("custom");
  };

  // 处理 API Key 输入并自动更新配置
  const handleApiKeyChange = (key: string) => {
    setApiKey(key);

    const configString = setApiKeyInConfig(
      formData.settingsConfig,
      key.trim(),
      { createIfMissing: selectedPreset !== null && selectedPreset !== -1 },
    );

    // 更新表单配置
    updateSettingsConfigValue(configString);

    // 同步通用配置开关
    const hasCommon = hasCommonConfigSnippet(configString, commonConfigSnippet);
    setUseCommonConfig(hasCommon);
  };

  // 处理基础 URL 变化
  const handleBaseUrlChange = (url: string) => {
    const sanitized = url.trim().replace(/\/+$/, "");
    setBaseUrl(sanitized);
    isUpdatingBaseUrlRef.current = true;

    try {
      const config = JSON.parse(formData.settingsConfig || "{}");
      if (!config.env) {
        config.env = {};
      }
      config.env.ANTHROPIC_BASE_URL = sanitized;

      updateSettingsConfigValue(JSON.stringify(config, null, 2));
    } catch {
      // ignore
    } finally {
      setTimeout(() => {
        isUpdatingBaseUrlRef.current = false;
      }, 0);
    }
  };

  const handleCodexBaseUrlChange = (url: string) => {
    const sanitized = url.trim().replace(/\/+$/, "");
    setCodexBaseUrl(sanitized);

    if (!sanitized) {
      return;
    }

    isUpdatingCodexBaseUrlRef.current = true;
    setCodexConfig((prev) => setCodexBaseUrlInConfig(prev, sanitized));
    setTimeout(() => {
      isUpdatingCodexBaseUrlRef.current = false;
    }, 0);
  };

  // Codex: 处理 API Key 输入并写回 auth.json
  const handleCodexApiKeyChange = (key: string) => {
    setCodexApiKey(key);
    try {
      const auth = JSON.parse(codexAuth || "{}");
      auth.OPENAI_API_KEY = key.trim();
      setCodexAuth(JSON.stringify(auth, null, 2));
    } catch {
      // ignore
    }
  };

  // Codex: 处理通用配置开关
  const handleCodexCommonConfigToggle = (checked: boolean) => {
    const snippet = codexCommonConfigSnippet.trim();
    const { updatedConfig, error: snippetError } =
      updateTomlCommonConfigSnippet(codexConfig, snippet, checked);

    if (snippetError) {
      setCodexCommonConfigError(snippetError);
      setUseCodexCommonConfig(false);
      return;
    }

    setCodexCommonConfigError("");
    setUseCodexCommonConfig(checked);
    // 标记正在通过通用配置更新
    isUpdatingFromCodexCommonConfig.current = true;
    setCodexConfig(updatedConfig);
    // 在下一个事件循环中重置标记
    setTimeout(() => {
      isUpdatingFromCodexCommonConfig.current = false;
    }, 0);
  };

  // Codex: 处理通用配置片段变化
  const handleCodexCommonConfigSnippetChange = (value: string) => {
    const previousSnippet = codexCommonConfigSnippet.trim();
    const sanitizedValue = value.trim();
    setCodexCommonConfigSnippet(value);

    if (!sanitizedValue) {
      setCodexCommonConfigError("");
      if (useCodexCommonConfig) {
        const { updatedConfig } = updateTomlCommonConfigSnippet(
          codexConfig,
          previousSnippet,
          false,
        );
        setCodexConfig(updatedConfig);
        setUseCodexCommonConfig(false);
      }
      return;
    }

    // TOML 不需要验证 JSON 格式，直接更新
    if (useCodexCommonConfig) {
      const removeResult = updateTomlCommonConfigSnippet(
        codexConfig,
        previousSnippet,
        false,
      );
      const addResult = updateTomlCommonConfigSnippet(
        removeResult.updatedConfig,
        sanitizedValue,
        true,
      );

      if (addResult.error) {
        setCodexCommonConfigError(addResult.error);
        return;
      }

      // 标记正在通过通用配置更新
      isUpdatingFromCodexCommonConfig.current = true;
      setCodexConfig(addResult.updatedConfig);
      // 在下一个事件循环中重置标记
      setTimeout(() => {
        isUpdatingFromCodexCommonConfig.current = false;
      }, 0);
    }

    // 保存 Codex 通用配置到 localStorage
    if (typeof window !== "undefined") {
      try {
        window.localStorage.setItem(
          CODEX_COMMON_CONFIG_STORAGE_KEY,
          sanitizedValue,
        );
      } catch {
        // ignore localStorage 写入失败
      }
    }
  };

  // Codex: 处理 config 变化
  const handleCodexConfigChange = (value: string) => {
    if (!isUpdatingFromCodexCommonConfig.current) {
      const hasCommon = hasTomlCommonConfigSnippet(
        value,
        codexCommonConfigSnippet,
      );
      setUseCodexCommonConfig(hasCommon);
    }
    setCodexConfig(value);
    if (!isUpdatingCodexBaseUrlRef.current) {
      const extracted = extractCodexBaseUrl(value) || "";
      if (extracted !== codexBaseUrl) {
        setCodexBaseUrl(extracted);
      }
    }
  };

  // 根据当前配置决定是否展示 API Key 输入框
  // 自定义模式(-1)也需要显示 API Key 输入框
  const showApiKey =
    selectedPreset !== null ||
    (!showPresets && hasApiKeyField(formData.settingsConfig));

  const normalizedCategory = category ?? initialData?.category;
  const shouldShowSpeedTest =
    normalizedCategory === "third_party" || normalizedCategory === "custom";

  const selectedTemplatePreset =
    !isCodex &&
    selectedPreset !== null &&
    selectedPreset >= 0 &&
    selectedPreset < providerPresets.length
      ? providerPresets[selectedPreset]
      : null;

  const templateValueEntries: Array<[string, TemplateValueConfig]> =
    selectedTemplatePreset?.templateValues
      ? (Object.entries(selectedTemplatePreset.templateValues) as Array<
          [string, TemplateValueConfig]
        >)
      : [];

  // 判断当前选中的预设是否是官方
  const isOfficialPreset =
    (selectedPreset !== null &&
      selectedPreset >= 0 &&
      (providerPresets[selectedPreset]?.isOfficial === true ||
        providerPresets[selectedPreset]?.category === "official")) ||
    category === "official";

  // 判断当前选中的预设是否是 Kimi
  const isKimiPreset =
    selectedPreset !== null &&
    selectedPreset >= 0 &&
    providerPresets[selectedPreset]?.name?.includes("Kimi");

  // 判断当前编辑的是否是 Kimi 提供商（通过名称或配置判断）
  const isEditingKimi =
    initialData &&
    (formData.name.includes("Kimi") ||
      formData.name.includes("kimi") ||
      (formData.settingsConfig.includes("api.moonshot.cn") &&
        formData.settingsConfig.includes("ANTHROPIC_MODEL")));

  // 综合判断是否应该显示 Kimi 模型选择器
  const shouldShowKimiSelector = isKimiPreset || isEditingKimi;

  const claudeSpeedTestEndpoints = useMemo<EndpointCandidate[]>(() => {
    if (isCodex) return [];
    const map = new Map<string, EndpointCandidate>();
    const add = (url?: string) => {
      if (!url) return;
      const sanitized = url.trim().replace(/\/+$/, "");
      if (!sanitized || map.has(sanitized)) return;
      map.set(sanitized, { url: sanitized });
    };

    if (baseUrl) {
      add(baseUrl);
    }

    if (initialData && typeof initialData.settingsConfig === "object") {
      const envUrl = (initialData.settingsConfig as any)?.env
        ?.ANTHROPIC_BASE_URL;
      if (typeof envUrl === "string") {
        add(envUrl);
      }
    }

    if (
      selectedPreset !== null &&
      selectedPreset >= 0 &&
      selectedPreset < providerPresets.length
    ) {
      const preset = providerPresets[selectedPreset];
      const presetEnv = (preset.settingsConfig as any)?.env?.ANTHROPIC_BASE_URL;
      if (typeof presetEnv === "string") {
        add(presetEnv);
      }
      // 合并预设内置的请求地址候选
      if (Array.isArray((preset as any).endpointCandidates)) {
        ((preset as any).endpointCandidates as string[]).forEach((u) => add(u));
      }
    }

    return Array.from(map.values());
  }, [isCodex, baseUrl, initialData, selectedPreset]);

  const codexSpeedTestEndpoints = useMemo<EndpointCandidate[]>(() => {
    if (!isCodex) return [];
    const map = new Map<string, EndpointCandidate>();
    const add = (url?: string) => {
      if (!url) return;
      const sanitized = url.trim().replace(/\/+$/, "");
      if (!sanitized || map.has(sanitized)) return;
      map.set(sanitized, { url: sanitized });
    };

    if (codexBaseUrl) {
      add(codexBaseUrl);
    }

    const initialCodexConfig =
      initialData && typeof initialData.settingsConfig?.config === "string"
        ? (initialData.settingsConfig as any).config
        : "";
    const existing = extractCodexBaseUrl(initialCodexConfig);
    if (existing) {
      add(existing);
    }

    if (
      selectedCodexPreset !== null &&
      selectedCodexPreset >= 0 &&
      selectedCodexPreset < codexProviderPresets.length
    ) {
      const preset = codexProviderPresets[selectedCodexPreset];
      const presetBase = extractCodexBaseUrl(preset?.config || "");
      if (presetBase) {
        add(presetBase);
      }
      // 合并预设内置的请求地址候选
      if (Array.isArray((preset as any)?.endpointCandidates)) {
        ((preset as any).endpointCandidates as string[]).forEach((u) => add(u));
      }
    }

    return Array.from(map.values());
  }, [isCodex, codexBaseUrl, initialData, selectedCodexPreset]);

  // 判断是否显示"获取 API Key"链接（国产官方、聚合站和第三方显示）
  const shouldShowApiKeyLink =
    !isCodex &&
    !isOfficialPreset &&
    (category === "cn_official" ||
      category === "aggregator" ||
      category === "third_party" ||
      (selectedPreset !== null &&
        selectedPreset >= 0 &&
        (providerPresets[selectedPreset]?.category === "cn_official" ||
          providerPresets[selectedPreset]?.category === "aggregator" ||
          providerPresets[selectedPreset]?.category === "third_party")));

  // 获取当前供应商的网址
  const getCurrentWebsiteUrl = () => {
    if (selectedPreset !== null && selectedPreset >= 0) {
      const preset = providerPresets[selectedPreset];
      if (!preset) return "";
      // 仅第三方供应商使用专用 apiKeyUrl，其余使用官网地址
      return preset.category === "third_party"
        ? preset.apiKeyUrl || preset.websiteUrl || ""
        : preset.websiteUrl || "";
    }
    return formData.websiteUrl || "";
  };

  // 获取 Codex 当前供应商的网址
  const getCurrentCodexWebsiteUrl = () => {
    if (selectedCodexPreset !== null && selectedCodexPreset >= 0) {
      const preset = codexProviderPresets[selectedCodexPreset];
      if (!preset) return "";
      // 仅第三方供应商使用专用 apiKeyUrl，其余使用官网地址
      return preset.category === "third_party"
        ? preset.apiKeyUrl || preset.websiteUrl || ""
        : preset.websiteUrl || "";
    }
    return formData.websiteUrl || "";
  };

  // Codex: 控制显示 API Key 与官方标记
  const getCodexAuthApiKey = (authString: string): string => {
    try {
      const auth = JSON.parse(authString || "{}");
      return typeof auth.OPENAI_API_KEY === "string" ? auth.OPENAI_API_KEY : "";
    } catch {
      return "";
    }
  };

  // 自定义模式(-1)不显示独立的 API Key 输入框
  const showCodexApiKey =
    (selectedCodexPreset !== null && selectedCodexPreset !== -1) ||
    (!showPresets && getCodexAuthApiKey(codexAuth) !== "");

  // 不再渲染分类介绍组件，避免造成干扰

  const isCodexOfficialPreset =
    (selectedCodexPreset !== null &&
      selectedCodexPreset >= 0 &&
      (codexProviderPresets[selectedCodexPreset]?.isOfficial === true ||
        codexProviderPresets[selectedCodexPreset]?.category === "official")) ||
    category === "official";

  // 判断是否显示 Codex 的"获取 API Key"链接（国产官方、聚合站和第三方显示）
  const shouldShowCodexApiKeyLink =
    isCodex &&
    !isCodexOfficialPreset &&
    (category === "cn_official" ||
      category === "aggregator" ||
      category === "third_party" ||
      (selectedCodexPreset !== null &&
        selectedCodexPreset >= 0 &&
        (codexProviderPresets[selectedCodexPreset]?.category ===
          "cn_official" ||
          codexProviderPresets[selectedCodexPreset]?.category ===
            "aggregator" ||
          codexProviderPresets[selectedCodexPreset]?.category ===
            "third_party")));

  // 处理模型输入变化，自动更新 JSON 配置
  const handleModelChange = (
    field: "ANTHROPIC_MODEL" | "ANTHROPIC_SMALL_FAST_MODEL",
    value: string,
  ) => {
    if (field === "ANTHROPIC_MODEL") {
      setClaudeModel(value);
    } else {
      setClaudeSmallFastModel(value);
    }

    // 更新 JSON 配置
    try {
      const currentConfig = formData.settingsConfig
        ? JSON.parse(formData.settingsConfig)
        : { env: {} };
      if (!currentConfig.env) currentConfig.env = {};

      if (value.trim()) {
        currentConfig.env[field] = value.trim();
      } else {
        delete currentConfig.env[field];
      }

      updateSettingsConfigValue(JSON.stringify(currentConfig, null, 2));
    } catch (err) {
      // 如果 JSON 解析失败，不做处理
    }
  };

  // Kimi 模型选择处理函数
  const handleKimiModelChange = (
    field: "ANTHROPIC_MODEL" | "ANTHROPIC_SMALL_FAST_MODEL",
    value: string,
  ) => {
    if (field === "ANTHROPIC_MODEL") {
      setKimiAnthropicModel(value);
    } else {
      setKimiAnthropicSmallFastModel(value);
    }

    // 更新配置 JSON
    try {
      const currentConfig = JSON.parse(formData.settingsConfig || "{}");
      if (!currentConfig.env) currentConfig.env = {};
      currentConfig.env[field] = value;

      const updatedConfigString = JSON.stringify(currentConfig, null, 2);
      updateSettingsConfigValue(updatedConfigString);
    } catch (err) {
      console.error("更新 Kimi 模型配置失败:", err);
    }
  };

  // 初始时从配置中同步 API Key（编辑模式）
  useEffect(() => {
    if (!initialData) return;
    const parsedKey = getApiKeyFromConfig(
      JSON.stringify(initialData.settingsConfig),
    );
    if (parsedKey) setApiKey(parsedKey);
  }, [initialData]);

  // 支持按下 ESC 关闭弹窗
  useEffect(() => {
    const onKeyDown = (e: KeyboardEvent) => {
      if (e.key === "Escape") {
        // 若有子弹窗（端点测速/模板向导）处于打开状态，则交由子弹窗自身处理，避免级联关闭
        if (
          isEndpointModalOpen ||
          isCodexEndpointModalOpen ||
          isCodexTemplateModalOpen
        ) {
          return;
        }
        e.preventDefault();
        onClose();
      }
    };
    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  }, [
    onClose,
    isEndpointModalOpen,
    isCodexEndpointModalOpen,
    isCodexTemplateModalOpen,
  ]);

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center"
      onMouseDown={(e) => {
        if (e.target === e.currentTarget) onClose();
      }}
    >
      {/* Backdrop */}
      <div
        className={`absolute inset-0 bg-black/50 dark:bg-black/70${
          isLinux() ? "" : " backdrop-blur-sm"
        }`}
      />

      {/* Modal */}
      <div className="relative bg-white dark:bg-gray-900 rounded-xl shadow-lg max-w-3xl w-full mx-4 max-h-[90vh] overflow-hidden flex flex-col">
        {/* Header */}
        <div className="flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-800">
          <h2 className="text-xl font-semibold text-gray-900 dark:text-gray-100">
            {title}
          </h2>
          <button
            type="button"
            onClick={onClose}
            className="p-1 text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-md transition-colors"
            aria-label="关闭"
          >
            <X size={18} />
          </button>
        </div>

        <form onSubmit={handleSubmit} className="flex flex-col flex-1 min-h-0">
          <div className="flex-1 overflow-auto p-6 space-y-6">
            {error && (
              <div className="flex items-center gap-3 p-4 bg-red-100 dark:bg-red-900/20 border border-red-500/20 dark:border-red-500/30 rounded-lg">
                <AlertCircle
                  size={20}
                  className="text-red-500 dark:text-red-400 flex-shrink-0"
                />
                <p className="text-red-500 dark:text-red-400 text-sm font-medium">
                  {error}
                </p>
              </div>
            )}

            {showPresets && !isCodex && (
              <PresetSelector
                presets={providerPresets}
                selectedIndex={selectedPreset}
                onSelectPreset={(index) =>
                  applyPreset(providerPresets[index], index)
                }
                onCustomClick={handleCustomClick}
              />
            )}

            {showPresets && isCodex && (
              <PresetSelector
                presets={codexProviderPresets}
                selectedIndex={selectedCodexPreset}
                onSelectPreset={(index) =>
                  applyCodexPreset(codexProviderPresets[index], index)
                }
                onCustomClick={handleCodexCustomClick}
                renderCustomDescription={() => (
                  <>
                    {t("providerForm.manualConfig")}
                    <button
                      type="button"
                      onClick={() => setIsCodexTemplateModalOpen(true)}
                      className="text-blue-400 dark:text-blue-500 hover:text-blue-500 dark:hover:text-blue-400 transition-colors ml-1"
                    >
                      {t("providerForm.useConfigWizard")}
                    </button>
                  </>
                )}
              />
            )}

            <div className="space-y-2">
              <label
                htmlFor="name"
                className="block text-sm font-medium text-gray-900 dark:text-gray-100"
              >
                {t("providerForm.supplierNameRequired")}
              </label>
              <input
                type="text"
                id="name"
                name="name"
                value={formData.name}
                onChange={handleChange}
                placeholder={t("providerForm.supplierNamePlaceholder")}
                required
                autoComplete="off"
                className="w-full px-3 py-2 border border-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 focus:border-blue-500 dark:focus:border-blue-400 transition-colors"
              />
            </div>

            <div className="space-y-2">
              <label
                htmlFor="websiteUrl"
                className="block text-sm font-medium text-gray-900 dark:text-gray-100"
              >
                {t("providerForm.websiteUrl")}
              </label>
              <input
                type="url"
                id="websiteUrl"
                name="websiteUrl"
                value={formData.websiteUrl}
                onChange={handleChange}
                placeholder={t("providerForm.websiteUrlPlaceholder")}
                autoComplete="off"
                className="w-full px-3 py-2 border border-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 focus:border-blue-500 dark:focus:border-blue-400 transition-colors"
              />
            </div>

            {!isCodex && showApiKey && (
              <div className="space-y-1">
                <ApiKeyInput
                  value={apiKey}
                  onChange={handleApiKeyChange}
                  required={!isOfficialPreset}
                  placeholder={
                    isOfficialPreset
                      ? t("providerForm.officialNoApiKey")
                      : shouldShowKimiSelector
                        ? t("providerForm.kimiApiKeyHint")
                        : t("providerForm.apiKeyAutoFill")
                  }
                  disabled={isOfficialPreset}
                />
                {shouldShowApiKeyLink && getCurrentWebsiteUrl() && (
                  <div className="-mt-1 pl-1">
                    <a
                      href={getCurrentWebsiteUrl()}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-xs text-blue-400 dark:text-blue-500 hover:text-blue-500 dark:hover:text-blue-400 transition-colors"
                    >
                      {t("providerForm.getApiKey")}
                    </a>
                  </div>
                )}
              </div>
            )}

            {!isCodex &&
              selectedTemplatePreset &&
              templateValueEntries.length > 0 && (
                <div className="space-y-3">
                  <h3 className="text-sm font-semibold text-gray-900 dark:text-gray-100">
                    {t("providerForm.parameterConfig", {
                      name: selectedTemplatePreset.name.trim(),
                    })}
                  </h3>
                  <div className="space-y-4">
                    {templateValueEntries.map(([key, config]) => (
                      <div key={key} className="space-y-2">
                        <label className="sr-only" htmlFor={`template-${key}`}>
                          {config.label}
                        </label>
                        <input
                          id={`template-${key}`}
                          type="text"
                          required
                          placeholder={`${config.label} *`}
                          value={
                            templateValues[key]?.editorValue ??
                            config.editorValue ??
                            config.defaultValue ??
                            ""
                          }
                          onChange={(e) => {
                            const newValue = e.target.value;
                            setTemplateValues((prev) => {
                              const prevEntry = prev[key];
                              const nextEntry: TemplateValueConfig = {
                                ...config,
                                ...(prevEntry ?? {}),
                                editorValue: newValue,
                              };
                              const nextValues: TemplateValueMap = {
                                ...prev,
                                [key]: nextEntry,
                              };

                              if (selectedTemplatePreset) {
                                try {
                                  const configString =
                                    applyTemplateValuesToConfigString(
                                      selectedTemplatePreset.settingsConfig,
                                      formData.settingsConfig,
                                      nextValues,
                                    );
                                  setFormData((prevForm) => ({
                                    ...prevForm,
                                    settingsConfig: configString,
                                  }));
                                  setSettingsConfigError(
                                    validateSettingsConfig(configString),
                                  );
                                } catch (err) {
                                  console.error("更新模板值失败:", err);
                                }
                              }

                              return nextValues;
                            });
                          }}
                          aria-label={config.label}
                          autoComplete="off"
                          className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
                        />
                      </div>
                    ))}
                  </div>
                </div>
              )}

            {!isCodex && shouldShowSpeedTest && (
              <div className="space-y-2">
                <div className="flex items-center justify-between">
                  <label
                    htmlFor="baseUrl"
                    className="block text-sm font-medium text-gray-900 dark:text-gray-100"
                  >
                    {t("providerForm.apiEndpoint")}
                  </label>
                  <button
                    type="button"
                    onClick={() => setIsEndpointModalOpen(true)}
                    className="flex items-center gap-1 text-xs text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 transition-colors"
                  >
                    <Zap className="h-3.5 w-3.5" />
                    {t("providerForm.manageAndTest")}
                  </button>
                </div>
                <input
                  type="url"
                  id="baseUrl"
                  value={baseUrl}
                  onChange={(e) => handleBaseUrlChange(e.target.value)}
                  placeholder={t("providerForm.apiEndpointPlaceholder")}
                  autoComplete="off"
                  className="w-full px-3 py-2 border border-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 focus:border-blue-500 dark:focus:border-blue-400 transition-colors"
                />
                <div className="p-3 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700 rounded-lg">
                  <p className="text-xs text-amber-600 dark:text-amber-400">
                    {t("providerForm.apiHint")}
                  </p>
                </div>
              </div>
            )}

            {/* 端点测速弹窗 - Claude */}
            {!isCodex && shouldShowSpeedTest && isEndpointModalOpen && (
              <EndpointSpeedTest
                appType={appType}
                providerId={initialData?.id}
                value={baseUrl}
                onChange={handleBaseUrlChange}
                initialEndpoints={claudeSpeedTestEndpoints}
                visible={isEndpointModalOpen}
                onClose={() => setIsEndpointModalOpen(false)}
                onCustomEndpointsChange={setDraftCustomEndpoints}
              />
            )}

            {!isCodex && shouldShowKimiSelector && (
              <KimiModelSelector
                apiKey={apiKey}
                anthropicModel={kimiAnthropicModel}
                anthropicSmallFastModel={kimiAnthropicSmallFastModel}
                onModelChange={handleKimiModelChange}
                disabled={isOfficialPreset}
              />
            )}

            {isCodex && showCodexApiKey && (
              <div className="space-y-1">
                <ApiKeyInput
                  id="codexApiKey"
                  label="API Key"
                  value={codexApiKey}
                  onChange={handleCodexApiKeyChange}
                  placeholder={
                    isCodexOfficialPreset
                      ? t("providerForm.codexOfficialNoApiKey")
                      : t("providerForm.codexApiKeyAutoFill")
                  }
                  disabled={isCodexOfficialPreset}
                  required={
                    selectedCodexPreset !== null &&
                    selectedCodexPreset >= 0 &&
                    !isCodexOfficialPreset
                  }
                />
                {shouldShowCodexApiKeyLink && getCurrentCodexWebsiteUrl() && (
                  <div className="-mt-1 pl-1">
                    <a
                      href={getCurrentCodexWebsiteUrl()}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-xs text-blue-400 dark:text-blue-500 hover:text-blue-500 dark:hover:text-blue-400 transition-colors"
                    >
                      {t("providerForm.getApiKey")}
                    </a>
                  </div>
                )}
              </div>
            )}

            {isCodex && shouldShowSpeedTest && (
              <div className="space-y-2">
                <div className="flex items-center justify-between">
                  <label
                    htmlFor="codexBaseUrl"
                    className="block text-sm font-medium text-gray-900 dark:text-gray-100"
                  >
                    {t("codexConfig.apiUrlLabel")}
                  </label>
                  <button
                    type="button"
                    onClick={() => setIsCodexEndpointModalOpen(true)}
                    className="flex items-center gap-1 text-xs text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 transition-colors"
                  >
                    <Zap className="h-3.5 w-3.5" />
                    {t("providerForm.manageAndTest")}
                  </button>
                </div>
                <input
                  type="url"
                  id="codexBaseUrl"
                  value={codexBaseUrl}
                  onChange={(e) => handleCodexBaseUrlChange(e.target.value)}
                  placeholder={t("providerForm.codexApiEndpointPlaceholder")}
                  autoComplete="off"
                  className="w-full px-3 py-2 border border-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 focus:border-blue-500 dark:focus:border-blue-400 transition-colors"
                />
                <div className="p-3 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700 rounded-lg">
                  <p className="text-xs text-amber-600 dark:text-amber-400">
                    {t("providerForm.codexApiHint")}
                  </p>
                </div>
              </div>
            )}

            {/* 端点测速弹窗 - Codex */}
            {isCodex && shouldShowSpeedTest && isCodexEndpointModalOpen && (
              <EndpointSpeedTest
                appType={appType}
                providerId={initialData?.id}
                value={codexBaseUrl}
                onChange={handleCodexBaseUrlChange}
                initialEndpoints={codexSpeedTestEndpoints}
                visible={isCodexEndpointModalOpen}
                onClose={() => setIsCodexEndpointModalOpen(false)}
                onCustomEndpointsChange={setDraftCustomEndpoints}
              />
            )}

            {/* Claude 或 Codex 的配置部分 */}
            {isCodex ? (
              <CodexConfigEditor
                authValue={codexAuth}
                configValue={codexConfig}
                onAuthChange={setCodexAuth}
                onConfigChange={handleCodexConfigChange}
                onAuthBlur={() => {
                  try {
                    const auth = JSON.parse(codexAuth || "{}");
                    const key =
                      typeof auth.OPENAI_API_KEY === "string"
                        ? auth.OPENAI_API_KEY
                        : "";
                    setCodexApiKey(key);
                  } catch {
                    // ignore
                  }
                }}
                useCommonConfig={useCodexCommonConfig}
                onCommonConfigToggle={handleCodexCommonConfigToggle}
                commonConfigSnippet={codexCommonConfigSnippet}
                onCommonConfigSnippetChange={
                  handleCodexCommonConfigSnippetChange
                }
                commonConfigError={codexCommonConfigError}
                authError={codexAuthError}
                isCustomMode={selectedCodexPreset === -1}
                onWebsiteUrlChange={(url) => {
                  setFormData((prev) => ({
                    ...prev,
                    websiteUrl: url,
                  }));
                }}
                onNameChange={(name) => {
                  setFormData((prev) => ({
                    ...prev,
                    name,
                  }));
                }}
                isTemplateModalOpen={isCodexTemplateModalOpen}
                setIsTemplateModalOpen={setIsCodexTemplateModalOpen}
              />
            ) : (
              <>
                {/* 可选的模型配置输入框 - 仅在非官方且非 Kimi 时显示 */}
                {!isOfficialPreset && !shouldShowKimiSelector && (
                  <div className="space-y-4">
                    <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                      <div className="space-y-2">
                        <label
                          htmlFor="anthropicModel"
                          className="block text-sm font-medium text-gray-900 dark:text-gray-100"
                        >
                          {t("providerForm.mainModel")}
                        </label>
                        <input
                          type="text"
                          id="anthropicModel"
                          value={claudeModel}
                          onChange={(e) =>
                            handleModelChange("ANTHROPIC_MODEL", e.target.value)
                          }
                          placeholder={t("providerForm.mainModelPlaceholder")}
                          autoComplete="off"
                          className="w-full px-3 py-2 border border-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 focus:border-blue-500 dark:focus:border-blue-400 transition-colors"
                        />
                      </div>

                      <div className="space-y-2">
                        <label
                          htmlFor="anthropicSmallFastModel"
                          className="block text-sm font-medium text-gray-900 dark:text-gray-100"
                        >
                          {t("providerForm.fastModel")}
                        </label>
                        <input
                          type="text"
                          id="anthropicSmallFastModel"
                          value={claudeSmallFastModel}
                          onChange={(e) =>
                            handleModelChange(
                              "ANTHROPIC_SMALL_FAST_MODEL",
                              e.target.value,
                            )
                          }
                          placeholder={t("providerForm.fastModelPlaceholder")}
                          autoComplete="off"
                          className="w-full px-3 py-2 border border-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 focus:border-blue-500 dark:focus:border-blue-400 transition-colors"
                        />
                      </div>
                    </div>

                    <div className="p-3 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700 rounded-lg">
                      <p className="text-xs text-amber-600 dark:text-amber-400">
                        {t("providerForm.modelHint")}
                      </p>
                    </div>
                  </div>
                )}

                <ClaudeConfigEditor
                  value={formData.settingsConfig}
                  onChange={(value) =>
                    handleChange({
                      target: { name: "settingsConfig", value },
                    } as React.ChangeEvent<HTMLTextAreaElement>)
                  }
                  useCommonConfig={useCommonConfig}
                  onCommonConfigToggle={handleCommonConfigToggle}
                  commonConfigSnippet={commonConfigSnippet}
                  onCommonConfigSnippetChange={handleCommonConfigSnippetChange}
                  commonConfigError={commonConfigError}
                  configError={settingsConfigError}
                />
              </>
            )}
          </div>

          {/* Footer */}
          <div className="flex items-center justify-end gap-3 p-6 border-t border-gray-200 dark:border-gray-800 bg-gray-100 dark:bg-gray-800">
            <button
              type="button"
              onClick={onClose}
              className="px-4 py-2 text-sm font-medium text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 hover:bg-white dark:hover:bg-gray-700 rounded-lg transition-colors"
            >
              {t("common.cancel")}
            </button>
            <button
              type="submit"
              className="px-4 py-2 bg-blue-500 dark:bg-blue-600 text-white rounded-lg hover:bg-blue-600 dark:hover:bg-blue-700 transition-colors text-sm font-medium flex items-center gap-2"
            >
              <Save className="w-4 h-4" />
              {submitText}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
};

export default ProviderForm;
