import { useMemo, useState, type FormEvent } from 'react';
import { Pencil, Plus, RotateCcw, Trash2 } from 'lucide-react';
import type {
  BaseModelCatalogItem,
  BaseModelUpsertRequest,
  CatalogProvider,
  PricingRuleSet,
  RuntimePolicySet,
} from '@easyai-ai-gateway/contracts';
import { Badge, Button, Card, CardContent, CardHeader, CardTitle, ConfirmDialog, FormDialog, FormItem, Label, Input, Select, Textarea } from '../../components/ui';
import type { LoadState } from '../../types';
import { BaseModelCapabilityEditor } from './BaseModelCapabilityEditor';
import {
  addCapabilityType,
  capabilitiesFromForm,
  capabilitiesToForm,
  createCapabilityEditorState,
  platformModelTypeDefinitions,
  removeCapabilityType,
  syncPrimaryCapability,
  type CapabilityEditorState,
} from './base-model-capabilities';
import { ModelCatalogCard } from './ModelCatalogCard';

type ModelForm = {
  providerKey: string;
  canonicalModelKey: string;
  providerModelName: string;
  modelAlias: string;
  status: string;
  pricingRuleSetId: string;
  runtimePolicySetId: string;
  runtimePolicyOverrideJson: string;
  pricingVersion: string;
  capabilities: CapabilityEditorState;
  billingJson: string;
  rateLimitJson: string;
  metadataJson: string;
};

const statuses = ['active', 'deprecated', 'hidden'];
const fallbackTypes = platformModelTypeDefinitions.map((item) => item.key);

function createEmptyForm(modelType = 'text_generate'): ModelForm {
  return {
    providerKey: '',
    canonicalModelKey: '',
    providerModelName: '',
    modelAlias: '',
    status: 'active',
    pricingRuleSetId: '',
    runtimePolicySetId: '',
    runtimePolicyOverrideJson: '{}',
    pricingVersion: '1',
    capabilities: createCapabilityEditorState(modelType),
    billingJson: '{}',
    rateLimitJson: '{}',
    metadataJson: '{}',
  };
}

export function BaseModelCatalogPanel(props: {
  baseModels: BaseModelCatalogItem[];
  message: string;
  pricingRuleSets: PricingRuleSet[];
  providers: CatalogProvider[];
  runtimePolicySets: RuntimePolicySet[];
  state: LoadState;
  onDeleteBaseModel: (baseModelId: string) => Promise<void>;
  onResetAllBaseModels: () => Promise<void>;
  onResetBaseModel: (baseModelId: string) => Promise<void>;
  onSaveBaseModel: (input: BaseModelUpsertRequest, baseModelId?: string) => Promise<void>;
}) {
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editingId, setEditingId] = useState('');
  const [form, setForm] = useState<ModelForm>(() => createEmptyForm());
  const [localError, setLocalError] = useState('');
  const [query, setQuery] = useState('');
  const [providerFilter, setProviderFilter] = useState('all');
  const [typeFilter, setTypeFilter] = useState('all');
  const [pendingDeleteModel, setPendingDeleteModel] = useState<BaseModelCatalogItem | null>(null);
  const [pendingResetModel, setPendingResetModel] = useState<BaseModelCatalogItem | null>(null);
  const [pendingResetAll, setPendingResetAll] = useState(false);

  const providerNames = useMemo(
    () => new Map(props.providers.map((item) => [item.providerKey, item.displayName])),
    [props.providers],
  );
  const typeOptions = useMemo(
    () => Array.from(new Set([...fallbackTypes, ...props.baseModels.flatMap(readModelTypes)])),
    [props.baseModels],
  );
  const providerOptions = useMemo(
    () => Array.from(new Set([...props.providers.map((item) => item.providerKey), ...props.baseModels.map((item) => item.providerKey)])),
    [props.baseModels, props.providers],
  );
  const defaultPricingRuleSetId = useMemo(() => defaultRuleSetId(props.pricingRuleSets), [props.pricingRuleSets]);
  const defaultRuntimePolicySetId = useMemo(() => defaultRuntimePolicyId(props.runtimePolicySets), [props.runtimePolicySets]);
  const systemModelCount = useMemo(() => props.baseModels.filter(isSystemBaseModel).length, [props.baseModels]);
  const customizedSystemModelCount = useMemo(
    () => props.baseModels.filter((item) => isSystemBaseModel(item) && item.customizedAt).length,
    [props.baseModels],
  );
  const filteredModels = useMemo(() => {
    const keyword = query.trim().toLowerCase();
    return props.baseModels.filter((item) => {
      const matchesProvider = providerFilter === 'all' || item.providerKey === providerFilter;
      const matchesType = typeFilter === 'all' || readModelTypes(item).includes(typeFilter);
      const text = `${baseModelAlias(item)} ${item.providerModelName} ${item.canonicalModelKey}`.toLowerCase();
      return matchesProvider && matchesType && (!keyword || text.includes(keyword));
    });
  }, [props.baseModels, providerFilter, query, typeFilter]);

  async function submit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setLocalError('');
    try {
      await props.onSaveBaseModel(formToPayload(form), editingId || undefined);
      closeDialog();
    } catch (err) {
      setLocalError(err instanceof Error ? err.message : '模型保存失败');
    }
  }

  function openCreateDialog() {
    const providerKey = providerOptions[0] ?? '';
    setEditingId('');
    setForm({
      ...createEmptyForm(),
      providerKey,
      canonicalModelKey: providerKey ? `${providerKey}:` : '',
      pricingRuleSetId: defaultPricingRuleSetId,
      runtimePolicySetId: defaultRuntimePolicySetId,
    });
    setDialogOpen(true);
  }

  function editModel(model: BaseModelCatalogItem) {
    setEditingId(model.id);
    setForm({
      ...modelToForm(model),
      pricingRuleSetId: model.pricingRuleSetId || defaultPricingRuleSetId,
      runtimePolicySetId: model.runtimePolicySetId || defaultRuntimePolicySetId,
    });
    setDialogOpen(true);
  }

  function closeDialog() {
    setEditingId('');
    setForm(createEmptyForm());
    setLocalError('');
    setDialogOpen(false);
  }

  async function deleteModel(model: BaseModelCatalogItem) {
    try {
      await props.onDeleteBaseModel(model.id);
      setPendingDeleteModel(null);
      if (editingId === model.id) closeDialog();
    } catch (err) {
      setLocalError(err instanceof Error ? err.message : '模型删除失败');
    }
  }

  async function resetModel(model: BaseModelCatalogItem) {
    try {
      await props.onResetBaseModel(model.id);
      setPendingResetModel(null);
      if (editingId === model.id) closeDialog();
    } catch (err) {
      setLocalError(err instanceof Error ? err.message : '模型重置失败');
    }
  }

  async function resetAllModels() {
    try {
      await props.onResetAllBaseModels();
      setPendingResetAll(false);
      if (editingId) closeDialog();
    } catch (err) {
      setLocalError(err instanceof Error ? err.message : '模型批量重置失败');
    }
  }

  return (
    <div className="pageStack">
      <Card>
        <CardHeader>
          <CardTitle>基准模型库</CardTitle>
          <Badge variant="secondary">{props.baseModels.length}</Badge>
        </CardHeader>
        <CardContent>
          <div className="providerToolbar">
            <p>默认模型来自原 server-main integration-platform，保留模型类型、能力、图标、计费和限流元数据。</p>
            <div className="inlineActions">
              <Button type="button" variant="outline" disabled={!systemModelCount || props.state === 'loading'} onClick={() => setPendingResetAll(true)}>
                <RotateCcw size={15} />
                重置所有
              </Button>
              <Button type="button" onClick={openCreateDialog}>
                <Plus size={15} />
                新增模型
              </Button>
            </div>
          </div>
          <div className="modelCatalogFilters">
            <Input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="搜索模型名称 / canonical key" />
            <Select value={providerFilter} onChange={(event) => setProviderFilter(event.target.value)}>
              <option value="all">全部厂商</option>
              {providerOptions.map((item) => <option value={item} key={item}>{providerNames.get(item) ?? item}</option>)}
            </Select>
            <Select value={typeFilter} onChange={(event) => setTypeFilter(event.target.value)}>
              <option value="all">全部能力</option>
              {typeOptions.map((item) => <option value={item} key={item}>{item}</option>)}
            </Select>
          </div>
          {(props.message || localError) && <p className="formMessage">{localError || props.message}</p>}
        </CardContent>
      </Card>

      <section className="baseModelGrid">
        {filteredModels.map((model) => (
          <ModelCard
            key={model.id}
            model={model}
            pricingRuleSetName={pricingRuleSetName(model.pricingRuleSetId, props.pricingRuleSets)}
            providerName={providerNames.get(model.providerKey)}
            runtimePolicySetName={runtimePolicySetName(model.runtimePolicySetId, props.runtimePolicySets)}
            onDelete={() => setPendingDeleteModel(model)}
            onEdit={() => editModel(model)}
            onReset={() => setPendingResetModel(model)}
          />
        ))}
        {!filteredModels.length && (
          <Card>
            <CardContent className="emptyState">
              <strong>没有匹配的基准模型</strong>
            </CardContent>
          </Card>
        )}
      </section>

      <FormDialog
        ariaLabel={editingId ? '编辑基准模型' : '新增基准模型'}
        className="baseModelDialog"
        eyebrow={editingId ? 'Edit Base Model' : 'New Base Model'}
        footer={(
          <>
            <Button type="submit" disabled={props.state === 'loading'}>
              {editingId ? <Pencil size={15} /> : <Plus size={15} />}
              {editingId ? '保存修改' : '新增模型'}
            </Button>
            <Button type="button" variant="outline" onClick={closeDialog}>
              <RotateCcw size={15} />
              取消
            </Button>
          </>
        )}
        formClassName="baseModelForm"
        open={dialogOpen}
        title={editingId ? '编辑基准模型' : '新增基准模型'}
        onClose={closeDialog}
        onSubmit={submit}
      >
        <FormItem label="Provider">
          <Select value={form.providerKey} onChange={(event) => setForm({ ...form, providerKey: event.target.value })}>
            <option value="">选择厂商</option>
            {providerOptions.map((item) => <option value={item} key={item}>{providerNames.get(item) ?? item}</option>)}
          </Select>
        </FormItem>
        <FormItem label="模型名">
          <Input value={form.providerModelName} onChange={(event) => setForm({ ...form, providerModelName: event.target.value })} />
        </FormItem>
        <FormItem
          description="作为调用和展示的模型名；多个不同平台模型设置同一别名后，可按该别名自动负载。"
          label="模型别名"
        >
          <Input value={form.modelAlias} onChange={(event) => setForm({ ...form, modelAlias: event.target.value })} />
        </FormItem>
        <FormItem className="spanTwo" label="Canonical Key">
          <Input value={form.canonicalModelKey} onChange={(event) => setForm({ ...form, canonicalModelKey: event.target.value })} />
        </FormItem>
        <FormItem label="状态">
          <Select value={form.status} onChange={(event) => setForm({ ...form, status: event.target.value })}>
            {statuses.map((item) => <option value={item} key={item}>{item}</option>)}
          </Select>
        </FormItem>
        <FormItem label="计价规则">
          <Select value={form.pricingRuleSetId || defaultPricingRuleSetId} onChange={(event) => setForm({ ...form, pricingRuleSetId: event.target.value })}>
            {!props.pricingRuleSets.length && <option value="">暂无可用计价规则</option>}
            {props.pricingRuleSets.map((item) => <option value={item.id} key={item.id}>{item.name}</option>)}
          </Select>
        </FormItem>
        <FormItem label="运行策略">
          <Select value={form.runtimePolicySetId || defaultRuntimePolicySetId} onChange={(event) => setForm({ ...form, runtimePolicySetId: event.target.value })}>
            {!props.runtimePolicySets.length && <option value="">暂无可用运行策略</option>}
            {props.runtimePolicySets.map((item) => <option value={item.id} key={item.id}>{item.name}</option>)}
          </Select>
        </FormItem>
        <FormItem label="定价版本">
          <Input value={form.pricingVersion} onChange={(event) => setForm({ ...form, pricingVersion: event.target.value })} />
        </FormItem>
        <BaseModelCapabilityEditor
          modelType={primaryCapabilityType(form.capabilities)}
          typeOptions={typeOptions}
          value={form.capabilities}
          onChange={(capabilities) => setForm({ ...form, capabilities })}
        />
        <JsonField label="基准计费 JSON" value={form.billingJson} onChange={(value) => setForm({ ...form, billingJson: value })} />
        <JsonField label="旧版限流 JSON（兼容字段）" value={form.rateLimitJson} onChange={(value) => setForm({ ...form, rateLimitJson: value })} />
        <JsonField label="运行策略覆盖 JSON" value={form.runtimePolicyOverrideJson} onChange={(value) => setForm({ ...form, runtimePolicyOverrideJson: value })} />
        <JsonField label="元数据 JSON" value={form.metadataJson} onChange={(value) => setForm({ ...form, metadataJson: value })} />
      </FormDialog>
      <ConfirmDialog
        confirmLabel="删除模型"
        description="删除后该基准模型不可恢复，已关联的平台模型可能无法继续跟随基准配置。"
        loading={props.state === 'loading'}
        open={Boolean(pendingDeleteModel)}
        title={`确认删除基准模型 ${baseModelAlias(pendingDeleteModel)}？`}
        onCancel={() => setPendingDeleteModel(null)}
        onConfirm={() => pendingDeleteModel ? deleteModel(pendingDeleteModel) : undefined}
      />
      <ConfirmDialog
        confirmLabel="重置为默认"
        description="系统内置模型会恢复到默认模型库快照，当前手动修改的能力、计价、运行策略和元数据会被默认值覆盖。"
        loading={props.state === 'loading'}
        open={Boolean(pendingResetModel)}
        title={`确认重置 ${baseModelAlias(pendingResetModel)}？`}
        onCancel={() => setPendingResetModel(null)}
        onConfirm={() => pendingResetModel ? resetModel(pendingResetModel) : undefined}
      />
      <ConfirmDialog
        confirmLabel="重置所有"
        description={`将恢复 ${systemModelCount} 个系统内置基准模型的默认快照，其中 ${customizedSystemModelCount} 个显示为已修改。用户添加的模型不会被影响。`}
        loading={props.state === 'loading'}
        open={pendingResetAll}
        title="确认重置所有系统内置模型？"
        onCancel={() => setPendingResetAll(false)}
        onConfirm={resetAllModels}
      />
    </div>
  );
}

function ModelCard(props: {
  model: BaseModelCatalogItem;
  pricingRuleSetName: string;
  providerName?: string;
  runtimePolicySetName: string;
  onDelete: () => void;
  onEdit: () => void;
  onReset: () => void;
}) {
  const types = readModelTypes(props.model);
  const chips = [...types.slice(0, 5), ...(types.length > 5 ? [`+${types.length - 5}`] : [])];
  const isSystem = isSystemBaseModel(props.model);
  return (
    <ModelCatalogCard
      actions={(
        <>
          {isSystem && (
            <Button type="button" variant="outline" size="sm" onClick={props.onReset}>
              <RotateCcw size={14} />
              重置
            </Button>
          )}
          <Button type="button" variant="outline" size="sm" onClick={props.onEdit}>
            <Pencil size={14} />
            修改
          </Button>
          <Button type="button" variant="destructive" size="sm" onClick={props.onDelete}>
            <Trash2 size={14} />
            删除
          </Button>
        </>
      )}
      badges={[
        <Badge key="status" variant={props.model.status === 'active' ? 'success' : 'secondary'}>{props.model.status}</Badge>,
        <Badge key="catalog-type" variant={isSystem ? 'secondary' : 'outline'}>{baseModelCatalogTypeLabel(props.model)}</Badge>,
        ...(isSystem && props.model.customizedAt ? [<Badge key="customized" variant="warning">已修改</Badge>] : []),
      ]}
      chips={chips}
      iconPath={readModelIconPath(props.model)}
      iconText={props.model.providerKey}
      meta={[props.providerName ?? props.model.providerKey, props.pricingRuleSetName, props.runtimePolicySetName, props.model.canonicalModelKey]}
      subtitle={props.model.providerModelName}
      title={baseModelAlias(props.model)}
    />
  );
}

function JsonField(props: { label: string; value: string; onChange: (value: string) => void }) {
  return (
    <Label className="spanTwo">
      {props.label}
      <Textarea value={props.value} onChange={(event) => props.onChange(event.target.value)} rows={5} spellCheck={false} />
    </Label>
  );
}

function modelToForm(model: BaseModelCatalogItem): ModelForm {
  const capabilities = readObject(model.capabilities);
  const metadataTypes = Array.isArray(model.metadata?.originalTypes) ? { originalTypes: model.metadata.originalTypes } : {};
  const modelTypes = readModelTypes(model);
  const capabilityState = capabilitiesToForm({ ...capabilities, ...metadataTypes }, modelTypes[0] ?? 'text_generate');
  return {
    providerKey: model.providerKey,
    canonicalModelKey: model.canonicalModelKey,
    providerModelName: model.providerModelName,
    modelAlias: baseModelAlias(model),
    status: model.status,
    pricingRuleSetId: model.pricingRuleSetId ?? '',
    runtimePolicySetId: model.runtimePolicySetId ?? '',
    pricingVersion: String(model.pricingVersion || 1),
    capabilities: capabilityState,
    billingJson: stringifyJson(model.baseBillingConfig),
    rateLimitJson: stringifyJson(model.defaultRateLimitPolicy),
    runtimePolicyOverrideJson: stringifyJson(model.runtimePolicyOverride),
    metadataJson: stringifyJson(model.metadata),
  };
}

function readModelIconPath(model: BaseModelCatalogItem) {
  return readString(model.metadata?.iconPath) || readString(readRecord(model.metadata?.rawModel)?.icon_path);
}

function baseModelAlias(model?: BaseModelCatalogItem | null) {
  return model?.modelAlias || model?.displayName || model?.providerModelName || '';
}

function primaryCapabilityType(capabilities: CapabilityEditorState) {
  return capabilities.types[0] ?? 'text_generate';
}

function isSystemBaseModel(model: BaseModelCatalogItem) {
  if (model.catalogType) return model.catalogType === 'system';
  return model.metadata?.source === 'server-main.integration-platform' || Boolean(model.metadata?.rawModel || model.metadata?.sourceProviderCode);
}

function baseModelCatalogTypeLabel(model: BaseModelCatalogItem) {
  return isSystemBaseModel(model) ? '系统内置' : '用户添加';
}

function formToPayload(form: ModelForm): BaseModelUpsertRequest {
  const modelTypes = uniqueStrings(form.capabilities.types).filter(Boolean);
  const primaryType = modelTypes[0] ?? 'text_generate';
  const capabilities = syncCapabilityTypes(form.capabilities, modelTypes);
  const modelAlias = form.modelAlias.trim() || form.providerModelName.trim();
  const metadata = parseJsonObject(form.metadataJson, '元数据 JSON');
  return {
    providerKey: form.providerKey.trim(),
    canonicalModelKey: form.canonicalModelKey.trim() || undefined,
    providerModelName: form.providerModelName.trim(),
    modelType: modelTypes.length ? modelTypes : [primaryType],
    modelAlias,
    capabilities: capabilitiesFromForm(syncPrimaryCapability(capabilities, primaryType)),
    baseBillingConfig: parseJsonObject(form.billingJson, '基准计费 JSON'),
    defaultRateLimitPolicy: parseJsonObject(form.rateLimitJson, '限流 JSON'),
    pricingRuleSetId: form.pricingRuleSetId.trim() || undefined,
    runtimePolicySetId: form.runtimePolicySetId.trim() || undefined,
    runtimePolicyOverride: parseJsonObject(form.runtimePolicyOverrideJson, '运行策略覆盖 JSON'),
    metadata: { ...metadata, alias: modelAlias, originalTypes: modelTypes },
    pricingVersion: Number.parseInt(form.pricingVersion, 10) || 1,
    status: form.status,
  };
}

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

function syncCapabilityTypes(state: CapabilityEditorState, modelTypes: string[]): CapabilityEditorState {
  const nextTypes = uniqueStrings(modelTypes).filter(Boolean);
  if (!nextTypes.length) return state;
  let next = state;
  nextTypes.forEach((type) => {
    next = addCapabilityType(next, type);
  });
  next.types
    .filter((type) => !nextTypes.includes(type))
    .forEach((type) => {
      next = removeCapabilityType(next, type);
    });
  return { ...next, types: nextTypes };
}

function readModelTypes(model: BaseModelCatalogItem) {
  if (Array.isArray(model.modelType)) return model.modelType.map(String);
  const values = model.metadata?.originalTypes ?? model.capabilities?.originalTypes;
  if (Array.isArray(values)) return values.map(String);
  return [];
}

function defaultRuleSetId(ruleSets: PricingRuleSet[]) {
  return ruleSets.find((item) => item.ruleSetKey === 'default-multimodal-v1')?.id ?? ruleSets[0]?.id ?? '';
}

function defaultRuntimePolicyId(policySets: RuntimePolicySet[]) {
  return policySets.find((item) => item.policyKey === 'default-runtime-v1')?.id ?? policySets[0]?.id ?? '';
}

function pricingRuleSetName(ruleSetId: string | undefined, ruleSets: PricingRuleSet[]) {
  if (!ruleSetId) return defaultRuleSetId(ruleSets) ? '默认计价规则' : '未绑定计价规则';
  return ruleSets.find((item) => item.id === ruleSetId)?.name ?? '未知计价规则';
}

function runtimePolicySetName(policySetId: string | undefined, policySets: RuntimePolicySet[]) {
  if (!policySetId) return defaultRuntimePolicyId(policySets) ? '默认运行策略' : '未绑定运行策略';
  return policySets.find((item) => item.id === policySetId)?.name ?? '未知运行策略';
}

function parseJsonObject(value: string, label: string) {
  try {
    const parsed = value.trim() ? JSON.parse(value) : {};
    if (!parsed || Array.isArray(parsed) || typeof parsed !== 'object') {
      throw new Error(`${label} 必须是 JSON object`);
    }
    return parsed as Record<string, unknown>;
  } catch (err) {
    if (err instanceof Error && err.message.includes('必须是')) throw err;
    throw new Error(`${label} 格式不正确`);
  }
}

function stringifyJson(value?: object) {
  return JSON.stringify(value ?? {}, null, 2);
}

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

function readString(value: unknown) {
  return typeof value === 'string' ? value : '';
}

function readRecord(value: unknown) {
  return value && !Array.isArray(value) && typeof value === 'object' ? (value as Record<string, unknown>) : undefined;
}
