import { useEffect, useMemo, useState, type ReactNode } from 'react';
import { Brain, Image, ListChecks, Plus, Trash2, Video } from 'lucide-react';
import { Button, Checkbox, Input, Select } from '../../components/ui';
import {
  addCapabilityType,
  defaultCapabilityConfig,
  modelTypeGroup,
  modelTypeLabel,
  removeCapabilityType,
  updateCapabilityConfig,
  type CapabilityEditorState,
} from './base-model-capabilities';

type FieldType =
  | 'boolean'
  | 'number'
  | 'text'
  | 'list'
  | 'numberList'
  | 'range'
  | 'ratioRange'
  | 'scopedList'
  | 'scopedNumberList'
  | 'scopedRange'
  | 'scopedNumber';

type FieldScope = 'mode' | 'resolution' | 'mixed';

type FieldDefinition = {
  key: string;
  label: string;
  hint?: string;
  placeholder?: string;
  type: FieldType;
  scope?: FieldScope;
	fixedOptions?: ValueOption[];
	allowCustom?: boolean;
};

type ValueOption = { label: string; value: string };

const textFields: FieldDefinition[] = [
  { key: 'supportTool', label: '工具调用', hint: 'function calling / tools', type: 'boolean' },
  { key: 'supportStructuredOutput', label: '结构化输出', hint: 'JSON Schema 等输出', type: 'boolean' },
  { key: 'supportThinking', label: '推理能力', hint: '支持 reasoning / thinking 参数', type: 'boolean' },
  { key: 'supportThinkingModeSwitch', label: '思考开关', hint: '可按请求切换', type: 'boolean' },
  { key: 'supportWebSearch', label: '联网搜索', type: 'boolean' },
  { key: 'max_context_tokens', label: '上下文 Token', placeholder: '128000', type: 'number' },
  { key: 'max_input_tokens', label: '最大输入 Token', placeholder: '64000', type: 'number' },
  { key: 'max_output_tokens', label: '最大输出 Token', placeholder: '8192', type: 'number' },
  { key: 'max_thinking_tokens', label: '最大思考 Token', placeholder: '32768', type: 'number' },
  { key: 'thinkingEffortLevels', label: '推理深度', hint: '声明模型支持的 OpenAI reasoning_effort 取值，平台差异由网关适配', placeholder: 'none, minimal, low, medium, high, xhigh', type: 'list' },
];

const apiProtocolField: FieldDefinition = {
	key: 'supportedApiProtocols',
	label: '支持的接口规范',
	hint: '字段缺失时按 OpenAI Chat 处理；Responses 入口会优先选择原生 Responses 候选',
	type: 'list',
	allowCustom: false,
	fixedOptions: [
		{ value: 'openai_chat_completions', label: 'OpenAI Chat' },
		{ value: 'openai_responses', label: 'OpenAI Responses' },
		{ value: 'anthropic_messages', label: 'Anthropic' },
	],
};

const embeddingFields: FieldDefinition[] = [
  { key: 'dimensions', label: '向量维度', placeholder: '1024, 768, 512', type: 'numberList' },
];

const imageFields: FieldDefinition[] = [
  { key: 'support_base64_input', label: 'Base64 输入', type: 'boolean' },
  { key: 'support_url_input', label: 'URL 输入', type: 'boolean' },
  { key: 'support_quality_control', label: '生成质量控制', hint: '支持请求中的 quality 参数', type: 'boolean' },
  { key: 'input_multiple_images', label: '多图输入', type: 'boolean' },
  { key: 'input_max_images_count', label: '最多输入图片', placeholder: '10', type: 'number' },
  { key: 'output_multiple_images', label: '多图输出', type: 'boolean' },
  { key: 'output_max_images_count', label: '最多输出图片', placeholder: '4', type: 'number' },
  { key: 'output_resolutions', label: '输出分辨率', placeholder: '1K, 2K, 4K', type: 'list' },
  { key: 'output_max_size', label: '最大输出尺寸', placeholder: '16777216', type: 'number' },
  { key: 'aspect_ratio_allowed', label: '支持宽高比', placeholder: '16:9, 1:1, 9:16', type: 'list' },
  { key: 'aspect_ratio_range', label: '宽高比范围', hint: '按宽/高数值限制，如 0.125 - 8', placeholder: '0.125 - 8', type: 'ratioRange' },
];

const videoFields: FieldDefinition[] = [
  { key: 'support_base64_input', label: 'Base64 输入', type: 'boolean' },
  { key: 'support_url_input', label: 'URL 输入', type: 'boolean' },
  { key: 'output_resolutions', label: '输出分辨率', hint: '可直接配置，也可按首帧/首尾帧等模式配置', placeholder: '720p, 1080p', type: 'scopedList', scope: 'mode' },
  { key: 'aspect_ratio_allowed', label: '支持宽高比', hint: '支持按分辨率配置可选宽高比', placeholder: '16:9, 9:16, 1:1', type: 'scopedList', scope: 'resolution' },
  { key: 'aspect_ratio_range', label: '宽高比范围', hint: '按宽/高数值限制，如 0.125 - 8', placeholder: '0.125 - 8', type: 'ratioRange' },
  { key: 'duration_range', label: '时长范围', hint: '支持按分辨率或模式配置不同范围', placeholder: '5 - 10', type: 'scopedRange', scope: 'mixed' },
  { key: 'duration_options', label: '可选时长', hint: '与时长范围二选一；只允许这些秒数', placeholder: '5, 10', type: 'scopedNumberList', scope: 'mixed' },
  { key: 'duration_step', label: '时长间隔', hint: '自定义时长按该秒数递增或取整', placeholder: '1', type: 'scopedNumber', scope: 'mixed' },
  { key: 'input_audio', label: '音频输入', type: 'boolean' },
  { key: 'output_audio', label: '输出音频', type: 'boolean' },
  { key: 'output_bgm', label: '背景音乐', type: 'boolean' },
  { key: 'input_first_frame', label: '首帧输入', type: 'boolean' },
  { key: 'input_last_frame', label: '尾帧输入', type: 'boolean' },
  { key: 'input_first_last_frame', label: '首尾帧模式', type: 'boolean' },
  { key: 'input_reference_generate_single', label: '单参考图', type: 'boolean' },
  { key: 'input_reference_generate_multiple', label: '多参考图', type: 'boolean' },
  { key: 'input_smart_multi_frame', label: '智能多帧', type: 'boolean' },
  { key: 'smart_multi_frame_range', label: '智能多帧数量', placeholder: '2 - 9', type: 'range' },
  { key: 'smart_multi_frame_mode', label: '智能多帧模式', placeholder: 'native 或 stitch', type: 'text' },
  { key: 'smart_multi_frame_duration_range', label: '智能多帧每段时长', placeholder: '2 - 7', type: 'range' },
  { key: 'support_video_effect_template', label: '视频特效模板', type: 'boolean' },
  { key: 'supported_modes', label: '支持模式', placeholder: 'text_to_video, image_reference', type: 'list' },
  { key: 'max_videos', label: '最多视频', placeholder: '1', type: 'number' },
  { key: 'max_images', label: '最多图片', placeholder: '4', type: 'number' },
  { key: 'max_audios', label: '最多音频', placeholder: '1', type: 'number' },
  { key: 'max_elements', label: '最多主体', placeholder: '4', type: 'number' },
  { key: 'max_images_and_elements', label: '图片主体合计', placeholder: '4', type: 'number' },
  { key: 'support_instruction_edit', label: '指令编辑', type: 'boolean' },
];

const model3dFields: FieldDefinition[] = [
  { key: 'support_texture', label: '纹理生成', type: 'boolean' },
  { key: 'support_part_generation', label: '分部生成', type: 'boolean' },
  { key: 'support_image_autofix', label: '图片自动优化', type: 'boolean' },
  { key: 'support_quad', label: '四边面输出', type: 'boolean' },
  { key: 'support_smart_low_poly', label: '智能低模', type: 'boolean' },
  { key: 'geometry_quality_options', label: '几何质量', placeholder: 'standard, detailed', type: 'list' },
  { key: 'max_face_limit', label: '三角面上限', placeholder: '20000', type: 'number' },
  { key: 'max_face_limit_quad', label: '四边面上限', placeholder: '10000', type: 'number' },
];

export function BaseModelCapabilityEditor(props: {
  modelType: string;
  typeOptions: string[];
  value: CapabilityEditorState;
  onChange: (value: CapabilityEditorState) => void;
}) {
  const enabledTypes = props.value.types;
  const [activeType, setActiveType] = useState(enabledTypes[0] ?? props.modelType);
  const [pendingType, setPendingType] = useState('');
  const availableTypes = useMemo(
    () => Array.from(new Set([props.modelType, ...props.typeOptions].filter(Boolean))),
    [props.modelType, props.typeOptions],
  );
  const addableTypes = availableTypes.filter((type) => !enabledTypes.includes(type));
  const activeConfig = props.value.typeConfigs[activeType] ?? defaultCapabilityConfig(activeType);
  const fieldGroups = capabilityFieldGroups(activeType);
  const capabilitySummary = useMemo(
    () => summarizeEnabledCapabilities(enabledTypes, props.value.typeConfigs),
    [enabledTypes, props.value.typeConfigs],
  );

  useEffect(() => {
    if (!enabledTypes.includes(activeType)) setActiveType(enabledTypes[0] ?? props.modelType);
  }, [activeType, enabledTypes, props.modelType]);

  function addType() {
    const nextType = pendingType || addableTypes[0];
    if (!nextType) return;
    props.onChange(addCapabilityType(props.value, nextType));
    setActiveType(nextType);
    setPendingType('');
  }

  function removeType(type: string) {
    const next = removeCapabilityType(props.value, type);
    props.onChange(next);
    setActiveType(next.types[0] ?? props.modelType);
  }

  function patchConfig(key: string, value: unknown) {
    const nextConfig = { ...activeConfig };
    if (value === undefined) delete nextConfig[key];
    else nextConfig[key] = value;
    const exclusiveKey = exclusiveCapabilityFields[key];
    if (exclusiveKey && hasMeaningfulValue(value)) delete nextConfig[exclusiveKey];
    props.onChange(updateCapabilityConfig(props.value, activeType, sanitizeCapabilityConfig(nextConfig)));
  }

  return (
    <section className="baseCapabilityEditor spanTwo bg-card text-foreground">
      <header>
        <div>
          <strong>模型能力</strong>
          <span>左侧维护已启用能力，右侧编辑该能力的默认配置。</span>
        </div>
      </header>

      <div className="capabilityWorkbench">
        <aside className="capabilitySidebar">
          <div className="capabilitySidebarTitle">
            <ListChecks size={15} />
            <strong>已启用能力</strong>
          </div>
          <div className="capabilityList">
            {enabledTypes.map((type) => (
              <button className="capabilityListItem" data-active={type === activeType} key={type} type="button" onClick={() => setActiveType(type)}>
                <span>
                  <strong>{modelTypeLabel(type)}</strong>
                  <small>{modelTypeGroup(type)} / {type}</small>
                </span>
                {enabledTypes.length > 1 && (
                  <Trash2
                    size={14}
                    onClick={(event) => {
                      event.stopPropagation();
                      removeType(type);
                    }}
                  />
                )}
              </button>
            ))}
          </div>
          <div className="capabilityAddBox">
            <Select size="sm" value={pendingType} onChange={(event) => setPendingType(event.target.value)}>
              <option value="">{addableTypes.length ? '选择要添加的能力' : '没有可添加能力'}</option>
              {addableTypes.map((type) => <option key={type} value={type}>{modelTypeLabel(type)} / {type}</option>)}
            </Select>
            <Button size="sm" type="button" variant="outline" disabled={!addableTypes.length} onClick={addType}>
              <Plus size={14} />
              添加能力
            </Button>
          </div>
          <div className="capabilitySummary">
            <strong>能力总结</strong>
            <p>{capabilitySummary}</p>
          </div>
        </aside>

        <div className="capabilityFormPanel">
          {fieldGroups.length ? (
            fieldGroups.map((group) => (
              <CapabilityFormGroup key={group.title} icon={group.icon} title={group.title}>
                {group.fields.map((field) => (
                  <CapabilityFormRow
                    key={field.key}
                    config={activeConfig}
                    defaultConfig={defaultCapabilityConfig(activeType)}
                    field={field}
                    onChange={(value) => patchConfig(field.key, value)}
                  />
                ))}
              </CapabilityFormGroup>
            ))
          ) : (
            <div className="capabilityPreserveNote">
              <strong>当前能力暂无通用表单</strong>
              <span>仍会保存该能力条目，并保留原始能力字段；后续可按平台专属能力继续扩展。</span>
            </div>
          )}

          <CapabilityFormGroup icon={<Brain size={15} />} title="保留字段">
            <div className="capabilityPreserveNote">
              <strong>{preservedConfigCount(activeConfig, fieldGroups)} 个未展示字段</strong>
              <span>这些字段保存时会继续保留在 {activeType} 能力配置内。</span>
            </div>
          </CapabilityFormGroup>
        </div>
      </div>
    </section>
  );
}

function CapabilityFormGroup(props: { children: ReactNode; icon: ReactNode; title: string }) {
  return (
    <section className="capabilityFormGroup">
      <header>
        {props.icon}
        <strong>{props.title}</strong>
      </header>
      <div className="capabilityFormRows">{props.children}</div>
    </section>
  );
}

function CapabilityFormRow(props: {
  config: Record<string, unknown>;
  defaultConfig: Record<string, unknown>;
  field: FieldDefinition;
  onChange: (value: unknown) => void;
}) {
  const value = props.config[props.field.key];
  return (
    <div className="capabilityFormRow">
      <div>
        <strong>{props.field.label}</strong>
        {props.field.hint && <small title={props.field.hint}>{props.field.hint}</small>}
      </div>
      <FieldControl
        config={props.config}
        defaultValue={props.defaultConfig[props.field.key]}
        field={props.field}
        value={value}
        onChange={props.onChange}
      />
    </div>
  );
}

function FieldControl(props: {
  config: Record<string, unknown>;
  defaultValue: unknown;
  field: FieldDefinition;
  value: unknown;
  onChange: (value: unknown) => void;
}) {
  if (props.field.type === 'boolean') {
    return <BooleanFieldControl defaultText={booleanDefaultText(props.field, props.defaultValue)} value={props.value} onChange={props.onChange} />;
  }
  if (props.field.type === 'range') {
    const range = Array.isArray(props.value) ? props.value : [];
    return (
      <div className="capabilityRange">
        <Input size="sm" min="0" step="1" type="number" value={stringValue(range[0])} placeholder="最小" onChange={(event) => props.onChange([numberValue(event.target.value), numberValue(range[1])])} />
        <Input size="sm" min="0" step="1" type="number" value={stringValue(range[1])} placeholder="最大" onChange={(event) => props.onChange([numberValue(range[0]), numberValue(event.target.value)])} />
      </div>
    );
  }
  if (props.field.type === 'ratioRange') {
    const range = Array.isArray(props.value) ? props.value : [];
    return (
      <div className="capabilityRange">
        <Input size="sm" min="0" step="0.001" type="number" value={stringValue(range[0])} placeholder="最小宽/高" onChange={(event) => props.onChange([numberValue(event.target.value), numberValue(range[1])])} />
        <Input size="sm" min="0" step="0.001" type="number" value={stringValue(range[1])} placeholder="最大宽/高" onChange={(event) => props.onChange([numberValue(range[0]), numberValue(event.target.value)])} />
      </div>
    );
  }
  if (props.field.type === 'number') {
    return <Input size="sm" min="0" step="1" type="number" value={stringValue(props.value)} placeholder={props.field.placeholder} onChange={(event) => props.onChange(numberValue(event.target.value))} />;
  }
  if (isScopedField(props.field)) {
    return <ScopedFieldControl field={props.field} value={props.value} config={props.config} onChange={props.onChange} />;
  }
  if (props.field.type === 'text') {
    return <Input size="sm" value={stringValue(props.value)} placeholder={props.field.placeholder} onChange={(event) => props.onChange(event.target.value)} />;
  }
  return <MultiValueControl config={props.config} field={props.field} value={props.value} onChange={props.onChange} />;
}

function BooleanFieldControl(props: {
  defaultText: string;
  onChange: (value: unknown) => void;
  value: unknown;
}) {
  return (
    <Select
      className="capabilityBooleanSelect"
      size="sm"
      value={booleanSelectValue(props.value)}
      onChange={(event) => props.onChange(booleanValueFromSelect(event.target.value))}
    >
      <option value="unset">未设置（{props.defaultText}）</option>
      <option value="true">支持</option>
      <option value="false">不支持</option>
    </Select>
  );
}

function ScopedFieldControl(props: {
  config: Record<string, unknown>;
  field: FieldDefinition;
  value: unknown;
  onChange: (value: unknown) => void;
}) {
  const grouped = isPlainRecord(props.value);
  const directValue = grouped ? defaultDirectValue(props.field) : props.value;
  const scopeOptions = scopeOptionsForField(props.field, props.config, props.value);
  const entries = grouped ? Object.entries(props.value as Record<string, unknown>) : [];
  const canGroup = scopeOptions.length > 0 || entries.length > 0;

  function switchMode(nextGrouped: boolean) {
    if (nextGrouped === grouped) return;
    if (!nextGrouped) {
      props.onChange(entries[0]?.[1] ?? defaultDirectValue(props.field));
      return;
    }
    const firstKey = firstAvailableScopeKey(scopeOptions, []);
    props.onChange({ [firstKey]: normalizeScopedValue(props.field, props.value) });
  }

  function setEntryKey(oldKey: string, nextKey: string) {
    if (!nextKey || !grouped) return;
    const next = { ...(props.value as Record<string, unknown>) };
    const current = next[oldKey];
    delete next[oldKey];
    next[nextKey] = current;
    props.onChange(next);
  }

  function setEntryValue(key: string, nextValue: unknown) {
    props.onChange({ ...(props.value as Record<string, unknown>), [key]: nextValue });
  }

  function removeEntry(key: string) {
    const next = { ...(props.value as Record<string, unknown>) };
    delete next[key];
    props.onChange(Object.keys(next).length ? next : defaultDirectValue(props.field));
  }

  function addEntry() {
    const used = entries.map(([key]) => key);
    const nextKey = firstAvailableScopeKey(scopeOptions, used);
    const current = grouped ? (props.value as Record<string, unknown>) : {};
    props.onChange({ ...current, [nextKey]: defaultDirectValue(props.field) });
  }

  return (
    <div className="capabilityScopedControl">
      <div className="capabilitySegmented" role="tablist" aria-label={`${props.field.label}配置方式`}>
        <button type="button" data-active={!grouped} onClick={() => switchMode(false)}>统一配置</button>
        <button type="button" disabled={!canGroup} data-active={grouped} onClick={() => switchMode(true)}>条件分组</button>
      </div>

      {!grouped ? (
        <ScopedValueInput config={props.config} field={props.field} value={directValue} placeholder={props.field.placeholder} onChange={props.onChange} />
      ) : (
        <div className="capabilityScopedRows">
          {entries.map(([key, value]) => (
            <div className="capabilityScopedRow" key={key}>
              <Select size="sm" value={key} onChange={(event) => setEntryKey(key, event.target.value)}>
                {ensureScopeOption(scopeOptions, key).map((option) => (
                  <option key={option.value} value={option.value}>{option.label}</option>
                ))}
              </Select>
              <ScopedValueInput config={props.config} field={props.field} value={value} placeholder={props.field.placeholder} onChange={(nextValue) => setEntryValue(key, nextValue)} />
              <Button type="button" size="icon" variant="ghost" aria-label="删除条件" onClick={() => removeEntry(key)}>
                <Trash2 size={14} />
              </Button>
            </div>
          ))}
          <Button type="button" size="sm" variant="outline" onClick={addEntry}>
            <Plus size={14} />
            添加条件
          </Button>
        </div>
      )}
    </div>
  );
}

function ScopedValueInput(props: {
  config: Record<string, unknown>;
  field: FieldDefinition;
  onChange: (value: unknown) => void;
  placeholder?: string;
  value: unknown;
}) {
  if (props.field.type === 'scopedRange') {
    const range = Array.isArray(props.value) ? props.value : [];
    return (
      <div className="capabilityRange">
        <Input size="sm" min="0" step="1" type="number" value={stringValue(range[0])} placeholder="最小" onChange={(event) => props.onChange([numberValue(event.target.value), numberValue(range[1])])} />
        <Input size="sm" min="0" step="1" type="number" value={stringValue(range[1])} placeholder="最大" onChange={(event) => props.onChange([numberValue(range[0]), numberValue(event.target.value)])} />
      </div>
    );
  }
  if (props.field.type === 'scopedNumber') {
    return <Input size="sm" min="0" step="1" type="number" value={stringValue(props.value)} placeholder={props.placeholder} onChange={(event) => props.onChange(numberValue(event.target.value))} />;
  }
  return <MultiValueControl config={props.config} field={props.field} value={props.value} onChange={props.onChange} />;
}

function MultiValueControl(props: {
  config: Record<string, unknown>;
  field: FieldDefinition;
  onChange: (value: unknown) => void;
  value: unknown;
}) {
  const [customValue, setCustomValue] = useState('');
  const selected = valueArray(props.value);
  const options = multiOptionsForField(props.field, props.config, props.value);
  const selectedSet = new Set(selected);

  function emit(nextValues: string[]) {
    const values = uniqueStrings(nextValues);
    props.onChange(isNumberListField(props.field) ? values.map(Number).filter(Number.isFinite) : values);
  }

  function toggle(value: string) {
    emit(selectedSet.has(value) ? selected.filter((item) => item !== value) : [...selected, value]);
  }

  function addCustom() {
    const values = customValue.split(/[,，]/).map((item) => item.trim()).filter(Boolean);
    if (!values.length) return;
    emit([...selected, ...values]);
    setCustomValue('');
  }

  return (
    <div className="capabilityMultiValue">
      <div className="capabilityMultiOptions">
        {options.map((option) => (
          <label key={option.value} className="capabilityCheckboxOption">
            <Checkbox
              checked={selectedSet.has(option.value)}
              onCheckedChange={() => toggle(option.value)}
            />
            {option.label}
          </label>
        ))}
      </div>
      {props.field.allowCustom !== false ? <div className="capabilityCustomValue">
        <Input
          size="sm"
          value={customValue}
          placeholder={props.field.placeholder ? `自定义：${props.field.placeholder}` : '自定义值'}
          onChange={(event) => setCustomValue(event.target.value)}
          onKeyDown={(event) => {
            if (event.key === 'Enter') {
              event.preventDefault();
              addCustom();
            }
          }}
        />
        <Button className="capabilityAddValueButton" type="button" size="sm" variant="outline" onClick={addCustom}>添加</Button>
      </div> : null}
    </div>
  );
}

type ScopeOption = { label: string; requires?: string; value: string };

const modeScopeOptions: ScopeOption[] = [
  { value: 'input_first_frame', label: '首帧模式 (input_first_frame)', requires: 'input_first_frame' },
  { value: 'input_first_last_frame', label: '首尾帧模式 (input_first_last_frame)', requires: 'input_first_last_frame' },
  { value: 'input_last_frame', label: '尾帧模式 (input_last_frame)', requires: 'input_last_frame' },
  { value: 'input_smart_multi_frame', label: '智能多帧 (input_smart_multi_frame)', requires: 'input_smart_multi_frame' },
];

const videoResolutionOptions = ['480p', '720p', '1080p', '1440p', '2160p'];
const imageResolutionOptions = ['1K', '2K', '3K', '4K', '8K'];
const videoAspectRatioOptions = ['adaptive', '16:9', '9:16', '1:1', '4:3', '3:4'];
const imageAspectRatioOptions = [
  'adaptive',
  '1:1',
  '16:9',
  '9:16',
  '4:3',
  '3:4',
  '3:2',
  '2:3',
  '5:4',
  '4:5',
  '5:3',
  '3:5',
  '21:9',
  '9:21',
  '2:1',
  '1:2',
  '4:1',
  '1:4',
  '8:1',
  '1:8',
  '7:4',
  '4:7',
];
const thinkingEffortOptions = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh'];
const omniVideoModeOptions = ['text_to_video', 'image_reference', 'element_reference', 'first_last_frame', 'video_reference', 'video_edit', 'multi_shot'];
const durationOptionValues = ['1', '2', '3', '4', '5', '6', '8', '10', '15', '20', '25', '30'];
const exclusiveCapabilityFields: Record<string, string> = {
  duration_range: 'duration_options',
  duration_options: 'duration_range',
};

function isScopedField(field: FieldDefinition) {
  return field.type === 'scopedList' || field.type === 'scopedNumberList' || field.type === 'scopedRange' || field.type === 'scopedNumber';
}

function scopeOptionsForField(field: FieldDefinition, config: Record<string, unknown>, value: unknown): ScopeOption[] {
  const options: ScopeOption[] = [];
  if (field.scope === 'mode' || field.scope === 'mixed') {
    options.push(...modeScopeOptions.filter((option) => !option.requires || config[option.requires] === true));
    flattenStringValues(config.supported_modes).forEach((mode) => options.push({ value: mode, label: `${friendlyScopeLabel(mode)} (${mode})` }));
  }
  if (field.scope === 'resolution' || field.scope === 'mixed') {
    [...flattenStringValues(config.output_resolutions), ...videoResolutionOptions].forEach((resolution) => {
      options.push({ value: resolution, label: `${friendlyScopeLabel(resolution)} (${resolution})` });
    });
  }
  if (isPlainRecord(value)) {
    Object.keys(value).forEach((key) => options.push({ value: key, label: `${friendlyScopeLabel(key)} (${key})` }));
  }
  return dedupeScopeOptions(options);
}

function ensureScopeOption(options: ScopeOption[], value: string) {
  if (!value || options.some((option) => option.value === value)) return options;
  return [...options, { value, label: `${friendlyScopeLabel(value)} (${value})` }];
}

function firstAvailableScopeKey(options: ScopeOption[], used: string[]) {
  return options.find((option) => !used.includes(option.value))?.value ?? `condition_${used.length + 1}`;
}

function sanitizeCapabilityConfig(config: Record<string, unknown>) {
  const supportedModeKeys = new Set([
    ...modeScopeOptions.filter((option) => !option.requires || config[option.requires] === true).map((option) => option.value),
    ...flattenStringValues(config.supported_modes),
  ]);
  const keepScopedModeKey = (key: string) => !isKnownModeScopeKey(key) || supportedModeKeys.has(key);
  return Object.fromEntries(
    Object.entries(config).map(([key, value]) => {
      if (!isScopedConfigKey(key) || !isPlainRecord(value)) return [key, value];
      const filtered = Object.fromEntries(Object.entries(value).filter(([scopeKey]) => keepScopedModeKey(scopeKey)));
      if (Object.keys(filtered).length > 0) return [key, filtered];
      return [key, defaultDirectValueForConfigKey(key)];
    }),
  );
}

function isScopedConfigKey(key: string) {
  return key === 'output_resolutions' || key === 'aspect_ratio_allowed' || key === 'duration_range' || key === 'duration_options' || key === 'duration_step';
}

function isKnownModeScopeKey(key: string) {
  return modeScopeOptions.some((option) => option.value === key) || ['text_to_video', 'image_reference', 'element_reference', 'first_last_frame', 'video_reference', 'video_edit', 'multi_shot'].includes(key);
}

function defaultDirectValueForConfigKey(key: string) {
  if (key === 'duration_range') return [0, 0];
  if (key === 'duration_step') return 0;
  return [];
}

function multiOptionsForField(field: FieldDefinition, config: Record<string, unknown>, value: unknown): ValueOption[] {
	if (field.fixedOptions) return field.fixedOptions;
  let options: string[] = [];
  if (field.key === 'output_resolutions') options = field.scope ? videoResolutionOptions : imageResolutionOptions;
  if (field.key === 'aspect_ratio_allowed') options = field.scope ? videoAspectRatioOptions : imageAspectRatioOptions;
  if (field.key === 'supported_modes') options = omniVideoModeOptions;
  if (field.key === 'thinkingEffortLevels') options = thinkingEffortOptions;
  if (field.key === 'duration_options') options = durationOptionValues;
  if (field.key === 'dimensions') options = ['3072', '1536', '1024', '768', '512', '256'];
  if (field.key === 'geometry_quality_options') options = ['standard', 'detailed'];
  options = orderedOptionValues(options, [...valueArray(value), ...flattenStringValues(config[field.key])], field);
  return options.map((item) => ({ value: item, label: friendlyOptionLabel(field, item) }));
}

function orderedOptionValues(baseOptions: string[], extraOptions: string[], field: FieldDefinition) {
  const base = uniqueStrings(baseOptions);
  const baseSet = new Set(base);
  const extras = uniqueStrings(extraOptions).filter((item) => !baseSet.has(item));
  if (field.key === 'duration_options') {
    return uniqueStrings([...base, ...extras]).sort((a, b) => Number(a) - Number(b));
  }
  const sortedExtras = isNumberListField(field)
    ? extras.sort((a, b) => Number(a) - Number(b))
    : extras.sort((a, b) => a.localeCompare(b));
  return [...base, ...sortedExtras];
}

function friendlyOptionLabel(field: FieldDefinition, value: string) {
  if (field.key === 'duration_options') return `${value}秒`;
  if (field.key === 'supported_modes') return friendlyScopeLabel(value);
  return value;
}

function valueArray(value: unknown): string[] {
  if (Array.isArray(value)) return value.map(String).filter(Boolean);
  if (value === undefined || value === null || value === '') return [];
  return [String(value)];
}

function isNumberListField(field: FieldDefinition) {
  return field.type === 'numberList' || field.type === 'scopedNumberList';
}

function friendlyScopeLabel(key: string) {
  const labels: Record<string, string> = {
    input_first_frame: '首帧模式',
    input_first_last_frame: '首尾帧模式',
    input_last_frame: '尾帧模式',
    input_smart_multi_frame: '智能多帧',
    text_to_video: '文生视频',
    image_reference: '图片参考',
    element_reference: '主体参考',
    first_last_frame: '首尾帧',
    video_reference: '视频参考',
    video_edit: '视频编辑',
    multi_shot: '多镜头',
  };
  return labels[key] ?? key;
}

function dedupeScopeOptions(options: ScopeOption[]) {
  const seen = new Set<string>();
  return options.filter((option) => {
    if (!option.value || seen.has(option.value)) return false;
    seen.add(option.value);
    return true;
  });
}

function flattenStringValues(value: unknown): string[] {
  if (Array.isArray(value)) return value.map(String).filter(Boolean);
  if (!isPlainRecord(value)) return [];
  return Object.values(value).flatMap((item) => Array.isArray(item) ? item.map(String).filter(Boolean) : []);
}

function defaultDirectValue(field: FieldDefinition) {
  if (field.type === 'scopedRange') return [0, 0];
  if (field.type === 'scopedNumber') return 0;
  return [];
}

function normalizeScopedValue(field: FieldDefinition, value: unknown) {
  if (isPlainRecord(value)) return Object.values(value)[0] ?? defaultDirectValue(field);
  if (field.type === 'scopedRange') return Array.isArray(value) ? value : defaultDirectValue(field);
  if (field.type === 'scopedNumber') return typeof value === 'number' || typeof value === 'string' ? numberValue(value) : 0;
  return Array.isArray(value) ? value : defaultDirectValue(field);
}

function hasMeaningfulValue(value: unknown): boolean {
  if (value === undefined || value === null || value === '') return false;
  if (Array.isArray(value)) return value.length > 0;
  if (isPlainRecord(value)) return Object.keys(value).length > 0;
  return true;
}

function capabilityFieldGroups(type: string): Array<{ title: string; icon: ReactNode; fields: FieldDefinition[] }> {
  if (isTextType(type)) return [{ title: '文本默认能力', icon: <Brain size={15} />, fields: type === 'text_generate' ? [apiProtocolField, ...textFields] : textFields }];
  if (type === 'text_embedding') return [{ title: '向量默认能力', icon: <Brain size={15} />, fields: embeddingFields }];
  if (isImageType(type)) return [{ title: '图像默认能力', icon: <Image size={15} />, fields: imageFieldsFor(type) }];
  if (isVideoType(type)) return [{ title: '视频默认能力', icon: <Video size={15} />, fields: videoFieldsFor(type) }];
  if (isModel3dType(type)) return [{ title: '3D 默认能力', icon: <Brain size={15} />, fields: model3dFields }];
  return [];
}

function imageFieldsFor(type: string) {
  if (type === 'image_edit') return imageFields;
  return imageFields.filter((field) => !field.key.startsWith('input_'));
}

function videoFieldsFor(type: string) {
  if (type === 'video_generate') return videoFields.filter((field) => !field.key.startsWith('input_') && field.key !== 'supported_modes');
  if (type === 'image_to_video') return videoFields.filter((field) => field.key !== 'supported_modes' && field.key !== 'max_audios');
  if (type === 'video_edit') return videoFields.filter((field) => !field.key.includes('reference_generate') && field.key !== 'supported_modes');
  return videoFields;
}

function preservedConfigCount(config: Record<string, unknown>, groups: Array<{ fields: FieldDefinition[] }>) {
  const shown = new Set(groups.flatMap((group) => group.fields.map((field) => field.key)));
  return Object.keys(config).filter((key) => !shown.has(key)).length;
}

function summarizeEnabledCapabilities(types: string[], typeConfigs: Record<string, Record<string, unknown>>) {
  if (!types.length) return '暂无启用能力，添加能力后会在这里显示模型支持范围。';
  const groups = uniqueStrings(types.map(modelTypeGroup));
  const names = types.map(modelTypeLabel);
  const nameText = names.length > 3 ? `${names.slice(0, 3).join('、')}等 ${names.length} 项能力` : names.join('、');
  const highlights = capabilitySummaryHighlights(types, typeConfigs);
  const base = `已启用 ${types.length} 项能力，覆盖${groups.join('、')}。包含 ${nameText}`;
  return highlights.length ? `${base}；${highlights.join('，')}。` : `${base}。`;
}

function capabilitySummaryHighlights(types: string[], typeConfigs: Record<string, Record<string, unknown>>) {
  const highlights: string[] = [];
	const protocolLabels: Record<string, string> = {
		openai_chat_completions: 'Chat',
		openai_responses: 'Responses',
		anthropic_messages: 'Anthropic',
	};
	const protocols = uniqueStrings(types.flatMap((type) => flattenStringValues(typeConfigs[type]?.supportedApiProtocols)));
	if (protocols.length) highlights.push(`接口 ${protocols.map((item) => protocolLabels[item] ?? item).join('/')}`);
  const textLimits = uniqueStrings(types.flatMap((type) => stringValue(typeConfigs[type]?.max_context_tokens ? typeConfigs[type].max_context_tokens : '').split(',').filter(Boolean)));
  if (textLimits.length) highlights.push(`上下文 ${textLimits[0]} Token`);

  const resolutions = uniqueStrings(types.flatMap((type) => flattenStringValues(typeConfigs[type]?.output_resolutions)));
  if (resolutions.length) highlights.push(`输出分辨率 ${resolutions.slice(0, 4).join('/')}`);

  const aspectRatioRanges = uniqueStrings(types.flatMap((type) => aspectRatioRangeSummaryValues(typeConfigs[type])));
  if (aspectRatioRanges.length) highlights.push(`宽高比 ${aspectRatioRanges.slice(0, 2).join('/')}`);

  const durations = uniqueStrings(types.flatMap((type) => durationSummaryValues(typeConfigs[type])));
  if (durations.length) highlights.push(`时长 ${durations.slice(0, 3).join('/')}`);

  const booleanLabels = types.flatMap((type) => enabledBooleanLabels(typeConfigs[type]));
  if (booleanLabels.length) highlights.push(`支持${uniqueStrings(booleanLabels).slice(0, 3).join('、')}`);

  return highlights.slice(0, 4);
}

function aspectRatioRangeSummaryValues(config?: Record<string, unknown>) {
  const range = config?.aspect_ratio_range;
  if (!Array.isArray(range) || range.length < 2) return [];
  return [`${range[0]}-${range[1]}`];
}

function durationSummaryValues(config?: Record<string, unknown>) {
  if (!config) return [];
  const options = flattenStringValues(config.duration_options).map((item) => `${item}秒`);
  if (options.length) return options;
  const range = config.duration_range;
  if (Array.isArray(range) && range.length >= 2) return [`${range[0]}-${range[1]}秒`];
  if (!isPlainRecord(range)) return [];
  return Object.values(range).flatMap((item) => Array.isArray(item) && item.length >= 2 ? [`${item[0]}-${item[1]}秒`] : []);
}

function enabledBooleanLabels(config?: Record<string, unknown>) {
  if (!config) return [];
  const labels: Record<string, string> = {
    supportTool: '工具调用',
    supportStructuredOutput: '结构化输出',
    supportThinking: '思考能力',
    supportWebSearch: '联网搜索',
    support_base64_input: 'Base64 输入',
    support_url_input: 'URL 输入',
    support_quality_control: '质量控制',
    input_multiple_images: '多图输入',
    output_multiple_images: '多图输出',
    input_audio: '音频输入',
    output_audio: '输出音频',
    output_bgm: '背景音乐',
    input_first_frame: '首帧输入',
    input_first_last_frame: '首尾帧模式',
    input_reference_generate_single: '单参考图',
    input_reference_generate_multiple: '多参考图',
    support_video_effect_template: '视频特效模板',
  };
  return Object.entries(labels).filter(([key]) => config[key] === true).map(([, label]) => label);
}

function isTextType(type: string) {
  return ['text_generate', 'image_analysis', 'video_understanding', 'audio_understanding', 'omni', 'tools_call'].includes(type);
}

function isImageType(type: string) {
  return type === 'image_generate' || type === 'image_edit';
}

function isVideoType(type: string) {
  return ['video_generate', 'image_to_video', 'video_edit', 'omni_video'].includes(type);
}

function isModel3dType(type: string) {
  return ['text_to_model', 'image_to_model', 'multiview_to_model', 'mesh_edit'].includes(type);
}

function numberValue(value: unknown) {
  const parsed = Number(value);
  return Number.isFinite(parsed) ? parsed : 0;
}

function booleanSelectValue(value: unknown) {
  if (value === true) return 'true';
  if (value === false) return 'false';
  return 'unset';
}

function booleanDefaultText(field: FieldDefinition, defaultValue: unknown) {
  if (field.key === 'support_base64_input' || field.key === 'support_url_input') return '默认自动判断';
  return defaultValue === true ? '默认支持' : '默认不支持';
}

function booleanValueFromSelect(value: string) {
  if (value === 'true') return true;
  if (value === 'false') return false;
  return undefined;
}

function stringValue(value: unknown) {
  return value === undefined || value === null ? '' : String(value);
}

function uniqueStrings(values: string[]) {
  return Array.from(new Set(values.map((item) => item.trim()).filter(Boolean)));
}

function isPlainRecord(value: unknown): value is Record<string, unknown> {
  return Boolean(value) && !Array.isArray(value) && typeof value === 'object';
}
