import { useMemo, useState, type FormEvent } from 'react';
import { FileText, Image, Pencil, Plus, RotateCcw, Trash2, Video } from 'lucide-react';
import type { PricingRule, PricingRuleInput, PricingRuleSet, PricingRuleSetUpsertRequest } from '@easyai-ai-gateway/contracts';
import { Badge, Button, Card, CardContent, CardHeader, CardTitle, ConfirmDialog, FormDialog, Input, Label, Select } from '../../components/ui';
import type { LoadState } from '../../types';
import { unitLabel } from './PricingEditorControls';
import { createDefaultPricingRules, KeyValueEditor, PricingRuleVisualEditor } from './PricingRuleVisualEditor';

type PricingForm = {
  ruleSetKey: string;
  name: string;
  description: string;
  category: string;
  currency: string;
  status: string;
  metadata: Record<string, unknown>;
  rules: PricingRuleInput[];
};

const categories = ['default', 'custom', 'provider', 'model'];
const statuses = ['active', 'deprecated', 'hidden'];
const currencies = ['resource', 'credit', 'cny', 'usd'];

export function PricingRulesPanel(props: {
  message: string;
  pricingRuleSets: PricingRuleSet[];
  state: LoadState;
  onDeletePricingRuleSet: (ruleSetId: string) => Promise<void>;
  onSavePricingRuleSet: (input: PricingRuleSetUpsertRequest, ruleSetId?: string) => Promise<void>;
}) {
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editingId, setEditingId] = useState('');
  const [form, setForm] = useState<PricingForm>(() => createEmptyForm());
  const [localError, setLocalError] = useState('');
  const [query, setQuery] = useState('');
  const [pendingDeleteRuleSet, setPendingDeleteRuleSet] = useState<PricingRuleSet | null>(null);
  const filtered = useMemo(() => {
    const keyword = query.trim().toLowerCase();
    if (!keyword) return props.pricingRuleSets;
    return props.pricingRuleSets.filter((item) => `${item.ruleSetKey} ${item.name} ${item.description ?? ''}`.toLowerCase().includes(keyword));
  }, [props.pricingRuleSets, query]);

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

  function openCreateDialog() {
    setEditingId('');
    setForm(createEmptyForm());
    setLocalError('');
    setDialogOpen(true);
  }

  function editRuleSet(ruleSet: PricingRuleSet) {
    setEditingId(ruleSet.id);
    setForm(ruleSetToForm(ruleSet));
    setLocalError('');
    setDialogOpen(true);
  }

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

  function updateCurrency(currency: string) {
    setForm({ ...form, currency, rules: ensureRules(form.rules, currency) });
  }

  async function deleteRuleSet(ruleSet: PricingRuleSet) {
    if (isDefaultRuleSet(ruleSet)) {
      setLocalError('默认计价规则不能删除。');
      return;
    }
    try {
      await props.onDeletePricingRuleSet(ruleSet.id);
      setPendingDeleteRuleSet(null);
      if (editingId === ruleSet.id) closeDialog();
    } catch (err) {
      setLocalError(err instanceof Error ? err.message : '定价规则删除失败');
    }
  }

  return (
    <div className="pageStack">
      <Card>
        <CardHeader>
          <CardTitle>定价规则</CardTitle>
          <Badge variant="secondary">{props.pricingRuleSets.length}</Badge>
        </CardHeader>
        <CardContent>
          <div className="providerToolbar">
            <p>规则集可包含文本、图像、视频等多个计价条目，平台或平台模型绑定规则集后再通过折扣率整体调价。</p>
            <Button type="button" onClick={openCreateDialog}><Plus size={15} />新增规则</Button>
          </div>
          <div className="modelCatalogFilters">
            <Input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="搜索规则名称 / key" />
          </div>
          {(props.message || localError) && <p className="formMessage">{localError || props.message}</p>}
        </CardContent>
      </Card>

      <section className="pricingRuleGrid">
        {filtered.map((ruleSet) => (
          <article className="pricingRuleCard" key={ruleSet.id}>
            <header>
              <div>
                <strong>{ruleSet.name}</strong>
                <span>{ruleSet.ruleSetKey}</span>
              </div>
              <Badge variant={ruleSet.status === 'active' ? 'success' : 'secondary'}>{ruleSet.status}</Badge>
            </header>
            <p>{ruleSet.description || '未填写说明'}</p>
            <div className="providerCatalogMeta">
              <span>{ruleSet.category}</span>
              <span>{ruleSet.currency}</span>
              <span>{pricingRuleSummaries(ruleSet).length} 条计价规则</span>
            </div>
            <div className="pricingRuleItems">
              {pricingRuleSummaries(ruleSet).map((item) => (
                <span key={item.label}>
                  <strong>{pricingRuleSummaryIcon(item.kind)}{item.label}</strong>
                  <em>{item.value}</em>
                </span>
              ))}
            </div>
            <div className="providerCatalogActions">
              <Button type="button" variant="outline" size="sm" onClick={() => editRuleSet(ruleSet)}><Pencil size={14} />修改</Button>
              <Button
                type="button"
                variant="destructive"
                size="sm"
                disabled={isDefaultRuleSet(ruleSet)}
                title={isDefaultRuleSet(ruleSet) ? '默认计价规则不能删除' : undefined}
                onClick={() => setPendingDeleteRuleSet(ruleSet)}
              >
                <Trash2 size={14} />
                删除
              </Button>
            </div>
          </article>
        ))}
        {!filtered.length && (
          <Card><CardContent className="emptyState"><strong>暂无定价规则</strong></CardContent></Card>
        )}
      </section>

      <FormDialog
        ariaLabel={editingId ? '编辑定价规则' : '新增定价规则'}
        bodyClassName="pricingRuleFormBody"
        className="pricingRuleDialog"
        eyebrow={editingId ? 'Edit Pricing Rule Set' : 'New Pricing Rule Set'}
        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>
          </>
        )}
        open={dialogOpen}
        title={editingId ? '编辑定价规则' : '新增定价规则'}
        onClose={closeDialog}
        onSubmit={submit}
      >
        <Label>规则 Key<Input value={form.ruleSetKey} onChange={(event) => setForm({ ...form, ruleSetKey: event.target.value })} /></Label>
        <Label>名称<Input value={form.name} onChange={(event) => setForm({ ...form, name: event.target.value })} /></Label>
        <Label className="spanTwo">说明<Input value={form.description} onChange={(event) => setForm({ ...form, description: event.target.value })} /></Label>
        <Label>类型<Select value={form.category} onChange={(event) => setForm({ ...form, category: event.target.value })}>{categories.map((item) => <option value={item} key={item}>{item}</option>)}</Select></Label>
        <Label>货币<Select value={form.currency} onChange={(event) => updateCurrency(event.target.value)}>{currencies.map((item) => <option value={item} key={item}>{item}</option>)}</Select></Label>
        <Label>状态<Select value={form.status} onChange={(event) => setForm({ ...form, status: event.target.value })}>{statuses.map((item) => <option value={item} key={item}>{item}</option>)}</Select></Label>
        <PricingRuleVisualEditor currency={form.currency} rules={form.rules} onChange={(rules) => setForm({ ...form, rules })} />
        <KeyValueEditor className="spanTwo" title="规则集元数据" value={form.metadata} onChange={(metadata) => setForm({ ...form, metadata })} />
      </FormDialog>
      <ConfirmDialog
        confirmLabel="删除规则"
        description="已绑定的平台或模型会清空规则绑定，删除后不可恢复。"
        loading={props.state === 'loading'}
        open={Boolean(pendingDeleteRuleSet)}
        title={`确认删除定价规则 ${pendingDeleteRuleSet?.name ?? ''}？`}
        onCancel={() => setPendingDeleteRuleSet(null)}
        onConfirm={() => pendingDeleteRuleSet ? deleteRuleSet(pendingDeleteRuleSet) : undefined}
      />
    </div>
  );
}

function createEmptyForm(currency = 'resource'): PricingForm {
  return {
    ruleSetKey: '',
    name: '',
    description: '',
    category: 'custom',
    currency,
    status: 'active',
    metadata: {},
    rules: createDefaultPricingRules(currency),
  };
}

function ruleSetToForm(ruleSet: PricingRuleSet): PricingForm {
  return {
    ruleSetKey: ruleSet.ruleSetKey,
    name: ruleSet.name,
    description: ruleSet.description ?? '',
    category: ruleSet.category,
    currency: ruleSet.currency,
    status: ruleSet.status,
    metadata: ruleSet.metadata ?? {},
    rules: (ruleSet.rules ?? []).map(ruleToInput),
  };
}

function ruleToInput(rule: PricingRule): PricingRuleInput {
  return {
    ruleKey: rule.ruleKey,
    displayName: rule.displayName,
    resourceType: rule.resourceType,
    unit: rule.unit,
    basePrice: rule.basePrice,
    currency: rule.currency,
    baseWeight: rule.baseWeight ?? {},
    dynamicWeight: rule.dynamicWeight ?? {},
    calculatorType: rule.calculatorType,
    dimensionSchema: rule.dimensionSchema ?? {},
    formulaConfig: rule.formulaConfig ?? {},
    priority: rule.priority,
    status: rule.status,
    metadata: rule.metadata ?? {},
  };
}

function formToPayload(form: PricingForm): PricingRuleSetUpsertRequest {
  const rules = ensureRules(form.rules, form.currency).map((rule, index) => ({
    ...rule,
    displayName: rule.displayName?.trim() || `${rule.resourceType} 计价`,
    priority: rule.priority ?? (index + 1) * 10,
    ruleKey: rule.ruleKey?.trim() || `${rule.resourceType}_${index + 1}`,
  }));
  return {
    ruleSetKey: form.ruleSetKey.trim(),
    name: form.name.trim(),
    description: form.description.trim(),
    category: form.category,
    currency: form.currency,
    status: form.status,
    metadata: form.metadata,
    rules,
  };
}

type PricingRuleSummary = {
  kind: 'text' | 'image' | 'video' | 'custom';
  label: string;
  value: string;
};

function pricingRuleSummaries(ruleSet: PricingRuleSet): PricingRuleSummary[] {
  const rules = ruleSet.rules ?? [];
  const textTotal = rules.find((rule) => rule.resourceType === 'text_total' || rule.ruleKey === 'text');
  const textInput = rules.find((rule) => rule.resourceType === 'text_input');
  const textCachedInput = rules.find(
    (rule) => rule.resourceType === 'text_cached_input',
  );
  const textOutput = rules.find((rule) => rule.resourceType === 'text_output');
  const image = rules.find((rule) => rule.resourceType === 'image');
  const video = rules.find((rule) => rule.resourceType === 'video');
  const items: PricingRuleSummary[] = [];
  if (textTotal || textInput || textCachedInput || textOutput) {
    const inputPrice = Number(textTotal?.formulaConfig?.inputTokenPrice ?? textInput?.basePrice ?? textTotal?.basePrice ?? 0);
    const cachedInputPrice = Number(
      textTotal?.formulaConfig?.cachedInputTokenPrice ??
        textTotal?.formulaConfig?.inputCacheHitTokenPrice ??
        textCachedInput?.basePrice ??
        inputPrice,
    );
    const outputPrice = Number(textTotal?.formulaConfig?.outputTokenPrice ?? textOutput?.basePrice ?? 0);
    items.push({
      kind: 'text',
      label: '文本',
      value: `输入 ${formatPrice(inputPrice)} / 缓存输入 ${formatPrice(cachedInputPrice)} / 输出 ${formatPrice(outputPrice)} / 1K Token`,
    });
  }
  if (image) items.push({ kind: 'image', label: '图像', value: `${formatPrice(image.basePrice)} / ${unitLabel(image.unit)}` });
  if (video) items.push({ kind: 'video', label: '视频', value: `${formatPrice(video.basePrice)} / ${unitLabel(video.unit)}` });
  if (items.length) return items;
  return rules.slice(0, 3).map((rule) => ({
    kind: 'custom',
    label: rule.displayName || rule.resourceType,
    value: `${formatPrice(rule.basePrice)} / ${unitLabel(rule.unit)}`,
  }));
}

function pricingRuleSummaryIcon(kind: PricingRuleSummary['kind']) {
  if (kind === 'image') return <Image size={14} />;
  if (kind === 'video') return <Video size={14} />;
  return <FileText size={14} />;
}

function formatPrice(value: number) {
  if (!Number.isFinite(value)) return '0';
  return Number(value.toFixed(4)).toString();
}

function isDefaultRuleSet(ruleSet: PricingRuleSet) {
  return ruleSet.ruleSetKey === 'default-multimodal-v1';
}

function ensureRules(rules: PricingRuleInput[], currency: string): PricingRuleInput[] {
  const sourceRules = rules.length ? rules : createDefaultPricingRules(currency);
  return sourceRules.map((rule) => ({ ...rule, currency }));
}
