import { useEffect, useMemo, useState } from 'react';
import { Boxes, Check, Search, X } from 'lucide-react';
import type { ModelCatalogFilterOption, ModelCatalogItem, ModelCatalogPermission } from '@easyai-ai-gateway/contracts';
import type { ConsoleData } from '../app-state';
import { Card, CardContent, Input } from '../components/ui';

export function ModelsPage(props: { data: ConsoleData }) {
  const catalog = props.data.modelCatalog;
  const [query, setQuery] = useState('');
  const [provider, setProvider] = useState('all');
  const [capability, setCapability] = useState('all');
  const providerOptions = catalog.filters.providers.length ? catalog.filters.providers : [{ value: 'all', label: '全部', count: catalog.items.length }];
  const capabilityOptions = catalog.filters.capabilities.length ? catalog.filters.capabilities : [{ value: 'all', label: '全部', count: catalog.items.length }];

  useEffect(() => {
    if (!providerOptions.some((item) => item.value === provider)) setProvider('all');
  }, [provider, providerOptions]);

  useEffect(() => {
    if (!capabilityOptions.some((item) => item.value === capability)) setCapability('all');
  }, [capability, capabilityOptions]);

  const filteredModels = useMemo(() => {
    const normalizedQuery = query.trim().toLowerCase();
    return catalog.items.filter((model) => {
      const matchedProvider = provider === 'all' || model.providerKeys.includes(provider);
      const matchedCapability = capability === 'all' || modelMatchesCapability(model, capability);
      const matchedQuery = !normalizedQuery || [
        model.alias,
        model.displayName,
        model.modelName,
        model.description,
        ...model.providers.map((item) => item.name),
        ...model.capabilityTags,
      ]
        .filter(Boolean)
        .join(' ')
        .toLowerCase()
        .includes(normalizedQuery);
      return matchedProvider && matchedCapability && matchedQuery;
    });
  }, [capability, catalog.items, provider, query]);

  return (
    <div className="modelsPage">
      <aside className="modelFilters">
        <FilterGroup
          title="模型能力"
          items={capabilityOptions}
          value={capability}
          onChange={setCapability}
        />
        <FilterGroup
          title="模型厂商"
          items={providerOptions}
          value={provider}
          onChange={setProvider}
        />
      </aside>

      <main className="modelsContent">
        <div className="modelsToolbar">
          <div className="searchField modelHeaderSearch" role="search">
            <Search size={16} />
            <Input
              aria-label="搜索模型"
              size="sm"
              value={query}
              onChange={(event) => setQuery(event.target.value)}
              placeholder="模型名称、能力或厂商"
            />
          </div>
        </div>

        <section className="modelCards">
          {filteredModels.map((model) => (
            <ModelCard model={model} key={model.id} />
          ))}
          {!filteredModels.length && (
            <Card>
              <CardContent className="emptyState">
                <Boxes size={18} />
                <strong>没有匹配的模型</strong>
              </CardContent>
            </Card>
          )}
        </section>
      </main>
    </div>
  );
}

function FilterGroup(props: {
  items: ModelCatalogFilterOption[];
  title: string;
  value: string;
  onChange: (value: string) => void;
}) {
  return (
    <section className="filterGroup">
      <h3>{props.title}</h3>
      <div className="filterChips">
        {props.items.map((item) => (
          <button
            type="button"
            className="filterChip"
            data-active={props.value === item.value}
            key={item.value}
            onClick={() => props.onChange(item.value)}
          >
            <FilterIcon item={item} />
            <span>{item.label}</span>
            <em>{item.count}</em>
          </button>
        ))}
      </div>
    </section>
  );
}

function FilterIcon(props: { item: ModelCatalogFilterOption }) {
  if (props.item.iconPath) {
    return (
      <span className="filterChipIcon">
        <img src={props.item.iconPath} alt="" />
      </span>
    );
  }
  if (props.item.value === 'all') return null;
  return <span className="filterChipIcon">{providerInitials(props.item.label)}</span>;
}

function ModelCard(props: { model: ModelCatalogItem }) {
  const description = props.model.description || '暂无模型描述';
  const pricing = modelCardPricing(props.model.pricing);
  return (
    <Card className="modelCard">
      <CardContent>
        <div className="modelCardTop">
          <ModelIcon iconPath={props.model.iconPath} label={props.model.displayName || props.model.alias} />
          <div className="modelCardHeaderText">
            <strong>{props.model.displayName || props.model.alias}</strong>
            <p className="modelCardDescription text-xs" title={description}>{description}</p>
          </div>
        </div>

        <div className="modelCardIntro">
          <div className="modelTags">
            {props.model.capabilityTags.map((tag) => <span className="text-xs" key={tag}>{tag}</span>)}
          </div>
        </div>

        <dl className="modelCardFacts text-xs">
          <div>
            <dt>源</dt>
            <dd title={props.model.source.title}>{props.model.source.label}</dd>
          </div>
          <div>
            <dt>折扣率</dt>
            <dd title={props.model.discount.title}>{props.model.discount.label}</dd>
          </div>
          <div className="modelCardFactRateLimit">
            <dt>限流</dt>
            <dd title={props.model.rateLimits.title}>{props.model.rateLimits.label}</dd>
          </div>
          <div>
            <dt>权限要求</dt>
            <dd title={props.model.permission.title}>
              <PermissionValue permission={props.model.permission} />
            </dd>
          </div>
          <div className="modelCardFactFull">
            <dt>{pricing.label}</dt>
            <dd title={pricing.title}>{pricing.lines.join('；')}</dd>
          </div>
        </dl>
      </CardContent>
    </Card>
  );
}

function modelCardPricing(pricing: ModelCatalogItem['pricing']) {
  const hasFiveSecondBasis = pricing.lines.some((line) => line.includes('5秒基准'));
  if (!hasFiveSecondBasis) {
    return {
      label: '模型定价',
      lines: pricing.lines,
      title: pricing.title,
    };
  }
  const lines = pricing.lines.map(stripFiveSecondBasis).filter(Boolean);
  const title = stripFiveSecondBasis(pricing.title || pricing.lines.join('；'));
  return {
    label: '模型定价(每5秒)',
    lines: lines.length ? lines : pricing.lines,
    title: title || pricing.title,
  };
}

function stripFiveSecondBasis(value: string) {
  return value
    .replace(/（5秒基准）/g, '')
    .replace(/\s*\/\s*5秒基准/g, '')
    .trim();
}

function PermissionValue(props: { permission: ModelCatalogPermission }) {
  const allowGroups = props.permission.allowGroups ?? [];
  const denyGroups = props.permission.denyGroups ?? [];
  if (!allowGroups.length && !denyGroups.length) {
    return <span>{props.permission.label}</span>;
  }
  return (
    <span className="modelPermissionTags">
      {allowGroups.map((group) => (
        <span className="modelPermissionTag modelPermissionTagAllow" key={`allow-${group}`}>
          <Check aria-hidden="true" className="modelPermissionIcon" />
          <span>{group}</span>
        </span>
      ))}
      {denyGroups.map((group) => (
        <span className="modelPermissionTag modelPermissionTagDeny" key={`deny-${group}`}>
          <X aria-hidden="true" className="modelPermissionIcon" />
          <span>{group}</span>
        </span>
      ))}
    </span>
  );
}

function ModelIcon(props: { iconPath?: string; label: string }) {
  if (props.iconPath) {
    return (
      <div className="modelIcon modelIconImage">
        <img src={props.iconPath} alt="" />
      </div>
    );
  }
  return <div className="modelIcon">{providerInitials(props.label)}</div>;
}

function modelMatchesCapability(model: ModelCatalogItem, capability: string) {
  if (model.modelType.some((type) => modelTypeMatchesCapability(type, capability))) return true;
  if (model.capabilityTags.some((tag) => capabilityValueForTag(tag) === capability)) return true;
  return false;
}

function modelTypeMatchesCapability(value: string, capability: string) {
  return canonicalCapabilityValue(value) === capability;
}

function canonicalCapabilityValue(value: string) {
  const type = value.trim().toLowerCase().replaceAll('-', '_');
  if (type === 'embedding') return 'text_embedding';
  if (type === 'rerank' || type === 'reranks') return 'text_rerank';
  if (type === 'model') return 'model_3d';
  return type;
}

function capabilityValueForTag(tag: string) {
  const values: Record<string, string> = {
    工具调用: 'tools_call',
    全模态: 'omni',
    全模态视频: 'omni_video',
    多模态: 'multimodal',
    推理: 'reasoning',
    结构化输出: 'structured_output',
    数字人: 'digital_human',
    重排序: 'text_rerank',
    '3D 模型': 'model_3d',
    '文生 3D': 'text_to_model',
    '图生 3D': 'image_to_model',
    '多视角 3D': 'multiview_to_model',
    '3D 模型编辑': 'mesh_edit',
  };
  return values[tag] ?? '';
}

function providerInitials(label: string) {
  return label
    .split(/\s+/)
    .map((part) => part[0])
    .join('')
    .slice(0, 2)
    .toUpperCase() || 'AI';
}
