import Avatar from './Avatar';
import Icon from './Icon';
import { CardLoadingSkeleton } from './Skeleton';
import Tag from './Tag';
import Tooltip from './Tooltip';
import duanRanAvatar from './team-avatar-assets/duan-ran.png';

const DEFAULT_STATS = [
  { iconName: 'users-01-stroked', value: '1,289', tooltip: '近 7 天触达用户数' },
  { iconName: 'message-chat-square-stroked', value: '1,289', tooltip: '近 7 天累计会话量' },
  { iconName: 'hearts-stroked', value: '276', tooltip: '近 7 天收藏或点赞次数' },
];

const DEFAULT_TAGS = ['标签', '标签'];
const DEFAULT_DATA_TITLE = '智能服务近7天趋势分析';
const DEFAULT_DATA_DESCRIPTION = '针对指定业务场景下智能服务核心指标、运行路径、渠道等进行趋势分析，并输出总结报告';
const DEFAULT_PRODUCT_TITLE = '海底捞门店通用双人套餐';
const DEFAULT_PRODUCT_DESCRIPTION = '数量 1 · ¥128.00 · 月售 2,361';
const DEFAULT_PRODUCT_STATUS = '已使用';
const DEFAULT_INFO_TITLE = '抖音 AI 创作助手';
const DEFAULT_INFO_DESCRIPTION = '抖音官方 AI 创作能力，支持短视频脚本、标题推荐、封面文案和热点灵感生成，帮助创作者提升内容生产效率。';
const DEFAULT_INFO_META = '段然';
const DEFAULT_INFO_BADGE = '官方能力';
const DEFAULT_INFO_ICON_TONE = 'pink';
const DEFAULT_INFO_ICON_STYLE = 'inverse';
const DEFAULT_INFO_BADGE_VARIANT = 'purple';
const DEFAULT_INFO_ICON = 'magic-wand-01-stroked';
const DEFAULT_INFO_META_AVATAR = duanRanAvatar;
const DEFAULT_INFO_LAYOUT = 'icon-right';
const DEFAULT_DATA_ICON_VISIBLE = 'hidden';
const DEFAULT_DATA_ICON_TONE = 'blue';
const DEFAULT_DATA_ICON_STYLE = 'inverse';
const DEFAULT_ANIMATED_TITLE = '智能策略生成';
const DEFAULT_ANIMATED_DESCRIPTION = '基于业务目标、历史数据和运营规则，自动生成可执行策略建议。';
const DEFAULT_ANIMATED_ICON = 'magic-wand-01-stroked';
const DEFAULT_ANIMATED_BADGE = 'AI 推荐';
const DEFAULT_ANIMATED_ACTION_TEXT = '立即体验';
const DEFAULT_INFO3_TITLE = '抖音生服订单已签收后还能申请退款吗？';
const DEFAULT_INFO3_DESCRIPTION = '已签收订单仍可在 7 天无理由保障期内发起退款，需提供商品照片或服务异常说明，平台介入后通常 24h 内出结果。';
const DEFAULT_INFO3_STATUS = '生效';
const DEFAULT_INFO3_META_ITEMS = [
  { iconName: 'tag-01-stroked', value: 'QA' },
  { iconName: 'clock-stroked', value: '2026-04-21 10:30' },
];
const DEFAULT_INFO_STATS = [
  { iconName: 'users-01-stroked', value: '128.6K', tooltip: '累计启用该能力的创作者数量' },
  { iconName: 'star-01-stroked', value: '4.9', tooltip: '用户综合评分，满分 5 分' },
  { iconName: 'check-circle-stroked', value: '98.6%', tooltip: '近 30 天内容生成任务成功完成率' },
];
const DEFAULT_PRODUCT_IMAGE_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(
  "<svg xmlns='http://www.w3.org/2000/svg' width='96' height='96' viewBox='0 0 96 96'><defs><linearGradient id='g' x1='0' y1='0' x2='1' y2='1'><stop offset='0%' stop-color='#2B90D9'/><stop offset='100%' stop-color='#0A355A'/></linearGradient></defs><rect width='96' height='96' fill='url(#g)'/><circle cx='72' cy='24' r='10' fill='rgba(255,255,255,0.28)'/><path d='M0 66C13 52 25 49 38 56C50 62 59 60 69 51C76 45 85 43 96 45V96H0Z' fill='rgba(255,255,255,0.24)'/></svg>"
)}`;

/* ── 卡片容器 ── */
const CARD_SURFACE = [
  'tfds-card',
  'group flex w-full',
  'rounded-xl border p-5',
  'transition-shadow tfds-motion-ui-normal',
  'hover:shadow-card',
].join(' ');

const CARD_INTERACTIVE = [
  'cursor-pointer',
  'focus:outline-none',
  'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blueGrey-300',
].join(' ');

const DATA_CARD = 'min-h-[var(--size-card-min-height)] flex-col justify-between gap-7';
const PRODUCT_CARD_SHELL = [
  'box-border !p-[12px] gap-[12px] !rounded-md hover:!shadow-none',
  '[&_.tfds-tag.bg-white]:hidden',
].join(' ');
const PRODUCT_CARD = `${PRODUCT_CARD_SHELL} flex-row items-center`;
const INFO_CARD_BASE = 'box-border min-h-[148px] w-full min-w-0 p-6 [&_.tfds-tag.bg-white]:hidden';
const INFO_CARD_ICON_LEFT = `${INFO_CARD_BASE} flex flex-row items-start gap-6`;
const INFO_CARD_ICON_RIGHT = `${INFO_CARD_BASE} flex flex-col`;

const CARD_VARIANT_CLASS = {
  white: 'border-white bg-card-secondary hover:border-white hover:bg-surface',
};

const CARD_VARIANT_STYLE = {
  grey: {
    backgroundColor: 'var(--color-blueGrey-100)',
    borderColor: 'var(--color-blueGrey-300)',
  },
};

/* ── 内容区 ── */
const CONTENT = 'flex w-full flex-col items-start gap-4';
const COPY = 'flex w-full flex-col items-start gap-2';
const TITLE = 'm-0 w-full text-base [font-weight:var(--font-semibold)] leading-card-title text-foreground';
const DESCRIPTION = 'm-0 w-full text-sm font-normal leading-card-copy text-foreground-muted';
const DATA_TAGS = 'flex flex-wrap items-center gap-2';
const DATA_ICON_ROW = 'flex w-full items-start gap-5';
const DATA_CONTENT_INNER = 'flex min-w-0 flex-1 flex-col items-start gap-4';
const DATA_ICON_FRAME_BASE = 'inline-flex h-12 w-12 shrink-0 items-center justify-center rounded-xl border';

/* ── 数据行 ── */
const STATS = 'flex flex-wrap items-center gap-5';
const STAT = 'inline-flex items-center gap-2 text-xs font-normal leading-4 text-foreground-muted';

function renderMetricItem({ iconName, value, tooltip, description }, index, className = STAT) {
  const statTooltip = tooltip || description;
  const statNode = (
    <span
      className={className}
      tabIndex={statTooltip ? 0 : undefined}
    >
      <Icon name={iconName} size={14} />
      <span>{value}</span>
    </span>
  );

  if (!statTooltip) {
    return (
      <span key={`${iconName}-${value}-${index}`}>
        {statNode}
      </span>
    );
  }

  return (
    <Tooltip
      key={`${iconName}-${value}-${index}`}
      content={statTooltip}
      placement="top"
      triggerClassName="inline-flex"
    >
      {statNode}
    </Tooltip>
  );
}

/* ── 商品卡片 ── */
const PRODUCT_IMAGE_FRAME = [
  'relative h-14 w-14 shrink-0 overflow-hidden',
  '[border-radius:var(--radius-lg)] border border-white bg-surface shadow-sm',
].join(' ');
const PRODUCT_IMAGE = 'h-full w-full object-cover';
const PRODUCT_BODY = 'flex h-14 min-w-0 flex-1 flex-col justify-center gap-2';
const PRODUCT_HEADER = 'flex min-w-0 items-start justify-between gap-3';
const PRODUCT_HEADER_ICON_RIGHT = 'flex min-w-0 items-center gap-2 [&>h3]:flex-initial';
const PRODUCT_CARD_ICON_RIGHT = `${PRODUCT_CARD_SHELL} flex-row-reverse items-center`;
const PRODUCT_TITLE = 'm-0 line-clamp-1 min-w-0 flex-1 text-base [font-weight:var(--font-semibold)] leading-card-title text-foreground';
const PRODUCT_DESCRIPTION = 'm-0 line-clamp-1 text-sm font-normal leading-card-copy text-foreground-muted';

/* ── 信息卡片1 ── */
const INFO_ICON_FRAME_BASE = 'inline-flex h-12 w-12 shrink-0 items-center justify-center rounded-[var(--radius-lg)] border';
const INFO_ICON_TONE_CLASS = {
  pink: 'border-pink-100 bg-pink-50 text-pink-600',
  blue: 'border-blue-100 bg-blue-50 text-blue-600',
  green: 'border-green-100 bg-green-50 text-green-600',
  orange: 'border-orange-100 bg-orange-50 text-orange-600',
  purple: 'border-purple-100 bg-purple-50 text-purple-600',
  brand: 'border-brand-100 bg-brand-50 text-brand-600',
  grey: 'border-border-default bg-fill text-blueGrey-600',
};
const INFO_ICON_TONE_HOVER_CLASS = [
  'transition-colors tfds-motion-ui-normal',
  'group-hover:bg-[var(--tfds-card-info-icon-hover-bg)]',
  'group-hover:border-transparent',
  'group-hover:text-white',
].join(' ');
const INFO_ICON_TONE_HOVER_STYLE = {
  pink: { '--tfds-card-info-icon-hover-bg': 'var(--color-pink-500)' },
  blue: { '--tfds-card-info-icon-hover-bg': 'var(--color-blue-500)' },
  green: { '--tfds-card-info-icon-hover-bg': 'var(--color-green-500)' },
  orange: { '--tfds-card-info-icon-hover-bg': 'var(--color-orange-500)' },
  purple: { '--tfds-card-info-icon-hover-bg': 'var(--color-purple-500)' },
  brand: { '--tfds-card-info-icon-hover-bg': 'var(--color-brand-500)' },
  grey: { '--tfds-card-info-icon-hover-bg': 'var(--color-black)' },
};
const INFO_ICON_STYLE_CLASS = {
  tone: null,
  inverse: 'border-black bg-black text-white',
};
const INFO_BADGE_VARIANTS = new Set([
  'brand',
  'red',
  'orange',
  'yellow',
  'green',
  'cyan',
  'blue',
  'purple',
  'pink',
  'teal',
  'grey',
  'white',
  'ai',
]);
const INFO_BODY = 'flex w-full min-w-0 flex-1 flex-col gap-5';
const INFO_HEADER = 'flex min-w-0 flex-col gap-2';
const INFO_HEADER_ROW = 'flex min-w-0 flex-wrap items-center gap-2';
const INFO_TITLE = 'm-0 min-w-0 max-w-full flex-initial line-clamp-1 text-base [font-weight:var(--font-semibold)] leading-card-title text-foreground';
const INFO_DESCRIPTION = 'm-0 w-full min-w-0 text-sm font-normal leading-5 text-foreground-muted line-clamp-2';
/** icon-right：网格为图标预留 48px 列 + 24px 间距，标题/徽标在左列 flex-wrap，避免与图标重叠 */
const INFO_HEADER_ICON_RIGHT_GRID = [
  'grid w-full min-w-0 items-start',
  'gap-x-6 gap-y-2',
  'grid-cols-[minmax(0,1fr)_3rem]',
].join(' ');
const INFO_HEADER_ICON_RIGHT_COPY = 'col-start-1 flex min-w-0 flex-col gap-2';
const INFO_HEADER_ICON_RIGHT_TITLE_ROW = 'flex min-w-0 flex-wrap items-center gap-2';
const INFO_HEADER_ICON_RIGHT_ICON = 'col-start-2 row-start-1 shrink-0 justify-self-end';
/** 底栏：身份区 + 指标区同一行；窄卡时 flex-wrap 换行，禁止固定高度裁切 */
const INFO_FOOTER = 'flex w-full min-w-0 flex-row flex-wrap items-center gap-x-5 gap-y-2';
const INFO_META = 'inline-flex min-h-4 shrink-0 items-center gap-2 text-xs font-normal leading-4 text-foreground-muted';
const INFO_META_AVATAR = [
  'shrink-0',
  '[&>img]:!scale-100',
  '[&>img]:!translate-y-0',
  '[&>img]:!object-center',
].join(' ');
const INFO_STATS = 'flex min-w-0 flex-1 flex-wrap items-center justify-end gap-x-5 gap-y-2';
const INFO_STAT = [
  'inline-flex h-4 items-center gap-2',
  'text-xs font-normal leading-4 text-foreground-muted',
  '[&>svg]:block [&>svg]:shrink-0',
].join(' ');

/* ── 信息卡片2 ── */
const ANIMATED_CARD = [
  'relative min-h-[180px] flex-col overflow-hidden p-6',
  'focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-blueGrey-300',
].join(' ');
const ANIMATED_CONTENT = 'relative z-10 flex min-h-0 flex-1 flex-col justify-between gap-5';
const ANIMATED_HEADER = 'flex items-start gap-4';
const ANIMATED_ICON_FRAME = [
  'inline-flex h-12 w-12 shrink-0 items-center justify-center rounded-[var(--radius-lg)] border',
  'transition-colors tfds-motion-ui-normal',
  'group-hover:[--tfds-card-animated-icon-bg:var(--tfds-card-animated-icon-hover-bg)]',
  'group-hover:[--tfds-card-animated-icon-border:transparent]',
  'group-hover:[--tfds-card-animated-icon-color:var(--color-white)]',
].join(' ');
const ANIMATED_COPY = 'flex min-w-0 flex-col gap-2';
const ANIMATED_TITLE = 'm-0 line-clamp-1 text-base [font-weight:var(--font-semibold)] leading-card-title text-foreground';
const ANIMATED_DESCRIPTION = 'm-0 line-clamp-2 text-sm font-normal leading-card-copy text-foreground-muted';
const ANIMATED_SLOT = 'min-w-0 flex-1 text-sm leading-card-copy text-foreground-secondary';
const ANIMATED_FOOTER = 'flex items-center justify-between gap-4';
const ANIMATED_TONE_STYLE = {
  brand: {
    '--tfds-card-animated-accent': 'var(--color-brand-600)',
    '--tfds-card-animated-icon-bg': 'var(--color-brand-50)',
    '--tfds-card-animated-icon-border': 'var(--color-brand-100)',
    '--tfds-card-animated-icon-color': 'var(--color-brand-700)',
    '--tfds-card-animated-icon-hover-bg': 'var(--color-brand-500)',
  },
  blue: {
    '--tfds-card-animated-accent': 'var(--color-blue-600)',
    '--tfds-card-animated-icon-bg': 'var(--color-blue-50)',
    '--tfds-card-animated-icon-border': 'var(--color-blue-100)',
    '--tfds-card-animated-icon-color': 'var(--color-blue-700)',
    '--tfds-card-animated-icon-hover-bg': 'var(--color-blue-500)',
  },
  purple: {
    '--tfds-card-animated-accent': 'var(--color-purple-600)',
    '--tfds-card-animated-icon-bg': 'var(--color-purple-50)',
    '--tfds-card-animated-icon-border': 'var(--color-purple-100)',
    '--tfds-card-animated-icon-color': 'var(--color-purple-700)',
    '--tfds-card-animated-icon-hover-bg': 'var(--color-purple-500)',
  },
  green: {
    '--tfds-card-animated-accent': 'var(--color-green-600)',
    '--tfds-card-animated-icon-bg': 'var(--color-green-50)',
    '--tfds-card-animated-icon-border': 'var(--color-green-100)',
    '--tfds-card-animated-icon-color': 'var(--color-green-700)',
    '--tfds-card-animated-icon-hover-bg': 'var(--color-green-500)',
  },
  orange: {
    '--tfds-card-animated-accent': 'var(--color-orange-600)',
    '--tfds-card-animated-icon-bg': 'var(--color-orange-50)',
    '--tfds-card-animated-icon-border': 'var(--color-orange-100)',
    '--tfds-card-animated-icon-color': 'var(--color-orange-700)',
    '--tfds-card-animated-icon-hover-bg': 'var(--color-orange-500)',
  },
  grey: {
    '--tfds-card-animated-accent': 'var(--color-blueGrey-700)',
    '--tfds-card-animated-icon-bg': 'var(--color-fill)',
    '--tfds-card-animated-icon-border': 'var(--color-border-default)',
    '--tfds-card-animated-icon-color': 'var(--color-blueGrey-700)',
    '--tfds-card-animated-icon-hover-bg': 'var(--color-black)',
  },
};

/* ── 信息卡片3 ── */
const INFO3_CARD = [
  'box-border h-auto flex-col gap-2 text-left',
  '!rounded-lg !p-[16px] hover:!shadow-none',
].join(' ');
const INFO3_HEADER = 'flex items-start justify-between gap-2';
const INFO3_TITLE = [
  'm-0 min-w-0 flex-1 text-base [font-weight:var(--font-semibold)] leading-6 text-blueGrey-900',
  'line-clamp-2',
].join(' ');
const INFO3_DESCRIPTION = 'm-0 line-clamp-2 text-sm font-normal leading-[22px] text-blueGrey-600';
const INFO3_META = 'flex min-w-0 flex-wrap items-center gap-3 text-xs font-normal leading-4 text-blueGrey-500';
const INFO3_META_ITEM = 'inline-flex min-w-0 items-center gap-1';
const INFO3_META_AVATAR = [
  '[&>img]:!scale-100',
  '[&>img]:!translate-y-0',
  '[&>img]:!object-center',
].join(' ');

const INFO3_STATUS_VARIANT = {
  生效: 'green',
  已发布: 'green',
  草稿: 'grey',
  审核中: 'orange',
  已停用: 'red',
  已下架: 'red',
};

/* ── 底部 ── */
const FOOTER = 'flex w-full items-center justify-between gap-4';
const ACTION = [
  'card-action inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full',
  'border border-transparent text-foreground-muted',
  'transition-colors transition-transform tfds-motion-ui-normal',
  'hover:border-black hover:text-black',
  'active:scale-[0.96]',
  'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blueGrey-300',
  'disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none',
  'group-hover:border-black group-hover:text-black',
].join(' ');

function getInteractiveCardProps(onAction, actionAriaLabel) {
  if (typeof onAction !== 'function') return {};

  return {
    role: 'button',
    tabIndex: 0,
    'aria-label': actionAriaLabel,
    onClick: onAction,
    onKeyDown: (event) => {
      if (event.key !== 'Enter' && event.key !== ' ') return;
      event.preventDefault();
      onAction(event);
    },
  };
}

const CARD_LOADING = 'pointer-events-none hover:!shadow-none';

function getCardLoadingShellClass(type, infoLayout) {
  if (type === 'product') {
    return infoLayout === 'icon-right' ? PRODUCT_CARD_ICON_RIGHT : PRODUCT_CARD;
  }
  if (type === 'info') {
    return infoLayout === 'icon-right' ? INFO_CARD_ICON_RIGHT : INFO_CARD_ICON_LEFT;
  }
  if (type === 'info2') return ANIMATED_CARD;
  if (type === 'info3') return INFO3_CARD;
  return DATA_CARD;
}

function handleNestedActionClick(event, onAction) {
  event.stopPropagation();
  onAction?.(event);
}

/**
 * Card — 业务信息摘要卡片
 * @prop {'data'|'product'|'info'|'info2'|'info3'|'animated'} [type='data'] — 卡片类型：data 为数据卡片，product 为商品卡片，info 为信息卡片1，info2 为信息卡片2，info3 为信息卡片3；animated 为旧版兼容别名
 * @prop {string} [title] — 卡片标题，商品卡片中为商品标题
 * @prop {string} [description] — 卡片描述，商品卡片中为数量、价格等辅助信息
 * @prop {'white'|'grey'} [color='white'] — 卡片颜色：white 为白底样式，适用于灰/浅灰/非纯白容器；grey 为 Blue Grey 灰底样式，适用于纯白容器
 * @prop {Array<{iconName: string, value: string, tooltip?: string}>|null} [stats=null] — 数据卡片指标数组，最多展示 3 项；tooltip 用于 hover/focus 展示详细说明
 * @prop {string[]|null} [tags=null] — 数据卡片标签数组，建议 1-2 个短标签；商品卡片和信息卡片1不渲染通用 tags
 * @prop {string} [productStatus='已使用'] — 商品状态标签文案
 * @prop {string} [productImageSrc] — 商品卡片左侧商品图地址
 * @prop {string} [productImageAlt='商品图'] — 商品图无障碍文案
 * @prop {string} [infoIconName='magic-wand-01-stroked'] — 信息卡片1左侧图标名称
 * @prop {'pink'|'blue'|'green'|'orange'|'purple'|'brand'|'grey'} [infoIconTone='pink'] — 信息卡片1左侧图标色系
 * @prop {'tone'|'inverse'} [infoIconStyle='inverse'] — 信息卡片1图标容器样式：tone 为同色系浅底，inverse 为黑底白 icon
 * @prop {'default'|'icon-right'} [infoLayout='icon-right'] — 卡片主视觉布局：信息卡片1为 default 左侧图标 / icon-right 右侧图标；商品卡片为 default 左侧商品图 / icon-right 右侧商品图
 * @prop {'hidden'|'visible'} [dataIconVisible='hidden'] — 数据卡片是否展示右侧图标
 * @prop {string|null} [dataIconName=null] — 数据卡片右侧图标名称；dataIconVisible=visible 时生效
 * @prop {'pink'|'blue'|'green'|'orange'|'purple'|'brand'|'grey'} [dataIconTone='blue'] — 数据卡片右侧图标容器色系
 * @prop {'tone'|'inverse'} [dataIconStyle='inverse'] — 数据卡片右侧图标容器样式：tone 为彩色浅底，inverse 为黑底白 icon
 * @prop {'brand'|'blue'|'purple'|'green'|'orange'|'grey'} [animatedTone='grey'] — 信息卡片2图标色系
 * @prop {string|null} [animatedIconName='magic-wand-01-stroked'] — 信息卡片2左上角图标
 * @prop {string|null} [animatedBadge='AI 推荐'] — 信息卡片2左下角徽标
 * @prop {string|null} [animatedActionText='立即体验'] — 信息卡片2底部右侧操作文案
 * @prop {boolean} [selected=false] — 信息卡片3整体选中态，使用浅绿色背景与 brand 描边
 * @prop {string} [status='生效'] — 信息卡片3右上角状态标签文案
 * @prop {'brand'|'red'|'orange'|'yellow'|'green'|'cyan'|'blue'|'purple'|'pink'|'teal'|'grey'|'white'|'ai'|null} [statusVariant=null] — 信息卡片3右上角状态标签颜色；不传时按常见状态自动映射
 * @prop {Array<{iconName?: string, value: string, avatarSrc?: string, avatarAlt?: string}>|null} [metaItems=null] — 信息卡片3底部元信息，适合类型、更新时间、创建人等密集信息
 * @prop {string} [infoMetaLabel='段然'] — 信息卡片1底部人名昵称
 * @prop {string} [infoMetaBadge='官方能力'] — 信息卡片1右上角徽标文案
 * @prop {'brand'|'red'|'orange'|'yellow'|'green'|'cyan'|'blue'|'purple'|'pink'|'teal'|'grey'|'white'|'ai'|null} [infoMetaBadgeVariant=null] — 信息卡片1右上角徽标颜色；黑底白标时可覆盖，彩色浅底时固定 grey
 * @prop {string} [infoMetaAvatarSrc] — 信息卡片1底部人名昵称头像
 * @prop {string} [infoMetaAvatarAlt='用户头像'] — 信息卡片1底部人名昵称头像无障碍文案
 * @prop {Array<{iconName: string, value: string, tooltip?: string}>|null} [infoStats=null] — 信息卡片1底部右侧辅助项数组，最多展示 3 项；tooltip 用于 hover/focus 展示详细说明
 * @prop {function|null} [onAction=null] — 详情跳转 / 进入二级页回调；传入后整张卡片默认可点击
 * @prop {string} [actionAriaLabel='查看卡片详情'] — 整卡与右侧操作按钮共用的无障碍文案
 * @prop {boolean} [loading=false] — 首屏/刷新加载态：保留 Card 外壳，内容区用与 type 槽位 1:1 的 Skeleton 原位占位（见 skeleton-slots.js）
 * @prop {string} [className=''] — 附加类名
 * @prop {object} [style] — 内联样式
 *
 * 通用 tags 仅用于数据卡片左下角；商品和信息卡片1不渲染标题左侧通用标签。
 * 所有 Card 分类都遵循“背景反衬”规则：父容器是纯白色时必须使用灰底卡；父容器是灰色、浅灰色或其他非纯白底时必须使用白底卡。
 * 卡片容器默认半透明白底，hover 后补满白底并出现业务卡片专用投影；灰底卡保持灰底与灰描边，并保留相同投影反馈。
 * 所有 Card 分类只要传入 onAction，就默认整张卡片区域可点击进入；右下角箭头仅作为进入提示，不是唯一热区。
 */
export default function Card({
  type = 'data',
  title,
  description,
  color = 'white',
  stats = null,
  tags = null,
  productStatus = DEFAULT_PRODUCT_STATUS,
  productImageSrc,
  productImageAlt = '商品图',
  infoIconName = DEFAULT_INFO_ICON,
  infoIconTone = DEFAULT_INFO_ICON_TONE,
  infoIconStyle = DEFAULT_INFO_ICON_STYLE,
  infoLayout = DEFAULT_INFO_LAYOUT,
  infoMetaLabel = DEFAULT_INFO_META,
  infoMetaBadge = DEFAULT_INFO_BADGE,
  infoMetaBadgeVariant = null,
  infoMetaAvatarSrc = DEFAULT_INFO_META_AVATAR,
  infoMetaAvatarAlt = '用户头像',
  infoStats = null,
  dataIconVisible = DEFAULT_DATA_ICON_VISIBLE,
  dataIconName = null,
  dataIconTone = DEFAULT_DATA_ICON_TONE,
  dataIconStyle = DEFAULT_DATA_ICON_STYLE,
  animatedTone = 'grey',
  animatedIconName = DEFAULT_ANIMATED_ICON,
  animatedBadge = DEFAULT_ANIMATED_BADGE,
  animatedActionText = DEFAULT_ANIMATED_ACTION_TEXT,
  selected = false,
  status = DEFAULT_INFO3_STATUS,
  statusVariant = null,
  metaItems = null,
  children,
  onAction,
  actionAriaLabel = '查看卡片详情',
  loading = false,
  className = '',
  style,
}) {
  const resolvedType = type === 'product' || type === 'info' || type === 'info3'
    ? type
    : (type === 'info2' || type === 'animated' ? 'info2' : 'data');
  // Card 颜色依赖父级背景做反衬，不按卡片类型区分。
  const resolvedColor = color === 'grey' ? 'grey' : 'white';
  const resolvedTitle = title || (
    resolvedType === 'product'
      ? DEFAULT_PRODUCT_TITLE
      : (resolvedType === 'info' ? DEFAULT_INFO_TITLE : (resolvedType === 'info2' ? DEFAULT_ANIMATED_TITLE : (resolvedType === 'info3' ? DEFAULT_INFO3_TITLE : DEFAULT_DATA_TITLE)))
  );
  const resolvedDescription = description || (
    resolvedType === 'product'
      ? DEFAULT_PRODUCT_DESCRIPTION
      : (resolvedType === 'info' ? DEFAULT_INFO_DESCRIPTION : (resolvedType === 'info2' ? DEFAULT_ANIMATED_DESCRIPTION : (resolvedType === 'info3' ? DEFAULT_INFO3_DESCRIPTION : DEFAULT_DATA_DESCRIPTION)))
  );
  const resolvedStats = (Array.isArray(stats) && stats.length > 0 ? stats : DEFAULT_STATS).slice(0, 3);
  const resolvedTags = resolvedType === 'data'
    ? (Array.isArray(tags) && tags.length > 0 ? tags : DEFAULT_TAGS)
    : [];
  const resolvedInfoStats = (Array.isArray(infoStats) && infoStats.length > 0 ? infoStats : DEFAULT_INFO_STATS).slice(0, 3);
  const resolvedInfoIconTone = Object.prototype.hasOwnProperty.call(INFO_ICON_TONE_CLASS, infoIconTone)
    ? infoIconTone
    : DEFAULT_INFO_ICON_TONE;
  const resolvedInfoIconStyle = Object.prototype.hasOwnProperty.call(INFO_ICON_STYLE_CLASS, infoIconStyle)
    ? infoIconStyle
    : DEFAULT_INFO_ICON_STYLE;
  const resolvedInfoLayout = infoLayout === 'default' || infoLayout === 'icon-right'
    ? infoLayout
    : DEFAULT_INFO_LAYOUT;
  const resolvedInfoMetaBadgeVariant = resolvedInfoIconStyle === 'tone'
    ? 'grey'
    : (INFO_BADGE_VARIANTS.has(infoMetaBadgeVariant) ? infoMetaBadgeVariant : DEFAULT_INFO_BADGE_VARIANT);
  const resolvedDataIconTone = Object.prototype.hasOwnProperty.call(INFO_ICON_TONE_CLASS, dataIconTone)
    ? dataIconTone
    : DEFAULT_DATA_ICON_TONE;
  const resolvedDataIconStyle = Object.prototype.hasOwnProperty.call(INFO_ICON_STYLE_CLASS, dataIconStyle)
    ? dataIconStyle
    : DEFAULT_DATA_ICON_STYLE;
  const resolvedDataIconVisible = dataIconVisible === 'visible' ? 'visible' : DEFAULT_DATA_ICON_VISIBLE;
  const hasDataIcon = resolvedType === 'data' && resolvedDataIconVisible === 'visible' && !!dataIconName;
  const resolvedAnimatedTone = Object.prototype.hasOwnProperty.call(ANIMATED_TONE_STYLE, animatedTone)
    ? animatedTone
    : 'grey';
  const resolvedInfo3MetaItems = Array.isArray(metaItems) && metaItems.length > 0
    ? metaItems
    : DEFAULT_INFO3_META_ITEMS;
  const resolvedStatusVariant = INFO_BADGE_VARIANTS.has(statusVariant)
    ? statusVariant
    : (INFO3_STATUS_VARIANT[status] || 'grey');
  const isClickable = typeof onAction === 'function';
  const cardStyle = {
    ...(CARD_VARIANT_STYLE[resolvedColor] || {}),
    ...(resolvedType === 'info' && resolvedInfoIconStyle === 'tone' ? INFO_ICON_TONE_HOVER_STYLE[resolvedInfoIconTone] : {}),
    ...(resolvedType === 'info2' ? ANIMATED_TONE_STYLE[resolvedAnimatedTone] : {}),
    ...style,
  };
  const interactiveProps = loading ? {} : getInteractiveCardProps(onAction, actionAriaLabel);

  if (loading) {
    return (
      <article
        className={[
          CARD_SURFACE,
          CARD_LOADING,
          getCardLoadingShellClass(resolvedType, resolvedInfoLayout),
          CARD_VARIANT_CLASS[resolvedColor],
          className,
        ].filter(Boolean).join(' ')}
        style={cardStyle}
        data-tfds-component="Card"
        data-tfds-loading="true"
        aria-busy="true"
        aria-label="卡片加载中"
      >
        <CardLoadingSkeleton
          type={resolvedType}
          infoLayout={resolvedInfoLayout}
          hasDataIcon={hasDataIcon}
        />
      </article>
    );
  }

  if (resolvedType === 'product') {
    return (
      <article
        className={[
          CARD_SURFACE,
          isClickable ? CARD_INTERACTIVE : null,
          resolvedInfoLayout === 'icon-right' ? PRODUCT_CARD_ICON_RIGHT : PRODUCT_CARD,
          CARD_VARIANT_CLASS[resolvedColor],
          className,
        ].filter(Boolean).join(' ')}
        style={cardStyle}
        data-tfds-component="Card"
        {...interactiveProps}
      >
        <div className={PRODUCT_IMAGE_FRAME}>
          <img
            className={PRODUCT_IMAGE}
            src={productImageSrc || DEFAULT_PRODUCT_IMAGE_SRC}
            alt={productImageSrc ? productImageAlt : ''}
            aria-hidden={productImageSrc ? undefined : true}
          />
        </div>

        <div className={PRODUCT_BODY}>
          <div className={resolvedInfoLayout === 'icon-right' ? PRODUCT_HEADER_ICON_RIGHT : PRODUCT_HEADER}>
            <h3 className={PRODUCT_TITLE}>{resolvedTitle}</h3>
            <Tag variant="green" size="l" radius="md" className="shrink-0">
              {productStatus || DEFAULT_PRODUCT_STATUS}
            </Tag>
          </div>
          <p className={PRODUCT_DESCRIPTION}>{resolvedDescription}</p>
        </div>
      </article>
    );
  }

  if (resolvedType === 'info') {
    const iconNode = (
      <span
        className={[
          INFO_ICON_FRAME_BASE,
          resolvedInfoIconStyle === 'inverse'
            ? INFO_ICON_STYLE_CLASS.inverse
            : INFO_ICON_TONE_CLASS[resolvedInfoIconTone],
          resolvedInfoIconStyle === 'tone' ? INFO_ICON_TONE_HOVER_CLASS : null,
        ].join(' ')}
        aria-hidden="true"
      >
        <Icon name={infoIconName || DEFAULT_INFO_ICON} size={24} />
      </span>
    );

    const badgeNode = infoMetaBadge ? (
      <Tag
        variant={resolvedInfoMetaBadgeVariant}
        size="l"
        radius="md"
        fontWeight="bold"
        className="shrink-0 self-center"
      >
        {infoMetaBadge}
      </Tag>
    ) : null;

    const infoCardLayoutCls = resolvedInfoLayout === 'icon-right'
      ? INFO_CARD_ICON_RIGHT
      : INFO_CARD_ICON_LEFT;

    return (
      <article
        className={[CARD_SURFACE, isClickable ? CARD_INTERACTIVE : null, infoCardLayoutCls, CARD_VARIANT_CLASS[resolvedColor], className].filter(Boolean).join(' ')}
        style={cardStyle}
        data-tfds-component="Card"
        {...interactiveProps}
      >
        {resolvedInfoLayout === 'icon-right' ? null : iconNode}

        <div className={INFO_BODY}>
          {resolvedInfoLayout === 'icon-right' ? (
            <div className={INFO_HEADER_ICON_RIGHT_GRID}>
              <div className={INFO_HEADER_ICON_RIGHT_COPY}>
                <div className={INFO_HEADER_ICON_RIGHT_TITLE_ROW}>
                  <h3 className={INFO_TITLE}>{resolvedTitle}</h3>
                  {badgeNode}
                </div>
                <p className={INFO_DESCRIPTION}>{resolvedDescription}</p>
              </div>
              <div className={INFO_HEADER_ICON_RIGHT_ICON}>{iconNode}</div>
            </div>
          ) : (
            <div className={INFO_HEADER}>
              <div className={INFO_HEADER_ROW}>
                <h3 className={INFO_TITLE}>{resolvedTitle}</h3>
                {badgeNode}
              </div>
              <p className={INFO_DESCRIPTION}>{resolvedDescription}</p>
            </div>
          )}

          <div className={INFO_FOOTER}>
            <span className={INFO_META}>
              <Avatar
                type="image"
                shape="round"
                size="xxs"
                src={infoMetaAvatarSrc}
                alt={infoMetaAvatarSrc ? infoMetaAvatarAlt : `${infoMetaLabel || DEFAULT_INFO_META}头像`}
                className={INFO_META_AVATAR}
              />
              <span className="whitespace-nowrap">{infoMetaLabel || DEFAULT_INFO_META}</span>
            </span>

            <div className={INFO_STATS}>
              {resolvedInfoStats.map((stat, index) => renderMetricItem(stat, index, INFO_STAT))}
            </div>
          </div>
        </div>
      </article>
    );
  }

  if (resolvedType === 'info2') {
    return (
      <article
        className={[CARD_SURFACE, isClickable ? CARD_INTERACTIVE : null, ANIMATED_CARD, CARD_VARIANT_CLASS[resolvedColor], className].filter(Boolean).join(' ')}
        style={cardStyle}
        data-tfds-component="Card"
        {...interactiveProps}
      >
        <div className={ANIMATED_CONTENT}>
          <div className={ANIMATED_HEADER}>
            {animatedIconName ? (
              <span
                className={ANIMATED_ICON_FRAME}
                style={{
                  backgroundColor: 'var(--tfds-card-animated-icon-bg)',
                  borderColor: 'var(--tfds-card-animated-icon-border)',
                  color: 'var(--tfds-card-animated-icon-color)',
                }}
                aria-hidden="true"
              >
                <Icon name={animatedIconName} size={24} />
              </span>
            ) : null}
          </div>

          <div className={ANIMATED_COPY}>
            <h3 className={ANIMATED_TITLE}>{resolvedTitle}</h3>
            <p className={ANIMATED_DESCRIPTION}>{resolvedDescription}</p>
          </div>

          <div className={ANIMATED_FOOTER}>
            <div className={ANIMATED_SLOT}>
              {animatedBadge ? (
                <Tag variant="white" size="l" radius="md" fontWeight="regular">
                  {animatedBadge}
                </Tag>
              ) : children}
            </div>
            {animatedActionText ? (
              <button
                type="button"
                className={ACTION}
                aria-label={animatedActionText || actionAriaLabel}
                onClick={(event) => handleNestedActionClick(event, onAction)}
                disabled={!onAction}
              >
                <Icon name="arrow-narrow-right-stroked" size={16} />
              </button>
            ) : null}
          </div>
        </div>
      </article>
    );
  }

  if (resolvedType === 'info3') {
    return (
      <article
        className={[
          CARD_SURFACE,
          isClickable ? CARD_INTERACTIVE : null,
          INFO3_CARD,
          CARD_VARIANT_CLASS[resolvedColor],
          className,
        ].filter(Boolean).join(' ')}
        style={{
          ...cardStyle,
          ...(selected ? { borderColor: 'var(--color-brand-500, #00B384)' } : {}),
        }}
        data-tfds-component="Card"
        data-tfds-card-type="info3"
        aria-selected={selected || undefined}
        {...interactiveProps}
      >
        <div className={INFO3_HEADER}>
          <h3 className={INFO3_TITLE}>{resolvedTitle}</h3>
          {status ? (
            <Tag variant={resolvedStatusVariant} className="shrink-0">
              {status}
            </Tag>
          ) : null}
        </div>

        <p className={INFO3_DESCRIPTION}>{resolvedDescription}</p>

        <div className={INFO3_META}>
          {resolvedInfo3MetaItems.map((item, index) => (
            <span key={`${item.value}-${index}`} className={INFO3_META_ITEM}>
              {item.avatarSrc ? (
                <Avatar
                  size="xxs"
                  type="image"
                  src={item.avatarSrc}
                  alt={item.avatarAlt || `${item.value}头像`}
                  className={INFO3_META_AVATAR}
                />
              ) : item.iconName ? (
                <Icon name={item.iconName} size="xs" />
              ) : null}
              <span className="truncate">{item.value}</span>
            </span>
          ))}
        </div>
      </article>
    );
  }

  return (
    <article
      className={[CARD_SURFACE, isClickable ? CARD_INTERACTIVE : null, DATA_CARD, CARD_VARIANT_CLASS[resolvedColor], className].filter(Boolean).join(' ')}
      style={cardStyle}
      data-tfds-component="Card"
      {...interactiveProps}
    >
      {hasDataIcon ? (
        <div className={DATA_ICON_ROW}>
          <div className={DATA_CONTENT_INNER}>
            <div className={COPY}>
              <h3 className={TITLE}>{resolvedTitle}</h3>
              <p className={DESCRIPTION}>{resolvedDescription}</p>
            </div>
            <div className={STATS}>
              {resolvedStats.map((stat, index) => renderMetricItem(stat, index))}
            </div>
          </div>
          <span
            className={[
              DATA_ICON_FRAME_BASE,
              resolvedDataIconStyle === 'inverse'
                ? INFO_ICON_STYLE_CLASS.inverse
                : INFO_ICON_TONE_CLASS[resolvedDataIconTone],
            ].join(' ')}
            aria-hidden="true"
          >
            <Icon name={dataIconName} size={24} />
          </span>
        </div>
      ) : (
        <div className={CONTENT}>
          <div className={COPY}>
            <h3 className={TITLE}>{resolvedTitle}</h3>
            <p className={DESCRIPTION}>{resolvedDescription}</p>
          </div>

          <div className={STATS}>
            {resolvedStats.map((stat, index) => renderMetricItem(stat, index))}
          </div>
        </div>
      )}

      <div className={FOOTER}>
        <div className={DATA_TAGS}>
          {resolvedTags.slice(0, 2).map((tag, index) => (
            <Tag key={`${tag}-${index}`} variant="grey" size="l" radius="md" fontWeight="bold">
              {tag}
            </Tag>
          ))}
        </div>
        <button
          type="button"
          className={ACTION}
          aria-label={actionAriaLabel}
          onClick={(event) => handleNestedActionClick(event, onAction)}
          disabled={!onAction}
        >
          <Icon name="arrow-narrow-right-stroked" size={16} />
        </button>
      </div>
    </article>
  );
}
