import type { CSSProperties, ReactNode } from 'react';
import DashboardModuleTitle from './DashboardModuleTitle';

/**
 * FeatureCardGroup — Dashboard 业务卡：特征卡片组
 *
 * 设计目标：
 *   将"同一主题、不同维度"的多张 chart 子卡聚合在同一张大白卡内，作为
 *   "核心反馈特征 / 用户特征"等聚合分析模块的承载容器。复用 DashboardModuleTitle
 *   作为可选标题区，子卡 chart slot 由调用方传入（SmartPieChart / SmartComposedChart /
 *   SmartBarChart 等业务图表）。
 *
 * 与既有组件关系：
 *   - 复用 DashboardModuleTitle（h3 + 副文案）作为外层标题区
 *   - 仅承载布局与视觉壳，不在内部 hardcode 任何图表实现，避免与 SmartIndicator /
 *     SmartPieChart / SmartComposedChart / SmartBarChart 形成耦合或重复定义
 *
 * 视觉契约（Figma node 4067:68727）：
 *   外层白卡：rounded-xl bg-white，padding 16px，gap 16px
 *   子卡：bg #FCFCFD + 0.4px 边 rgba(45,66,107,0.12) + rounded-xl
 *         padding 16px（上下左右一致），title 行与 chart slot 间距 16px
 *   chart slot：bg-white + rounded-md (8px) + padding 16px；图表自身需自适应缩放
 *   chart 最小高度默认 240px，图表禁止顶格
 */

export interface FeatureCardProps {
  /** 子卡标题（必填） */
  title: string;
  /** 子卡副文案（口径说明 / 颗粒度说明） */
  subtitle?: string;
  /** 图表 slot（SmartPieChart / SmartBarChart / SmartComposedChart 等） */
  chart: ReactNode;
  /** 子卡附加 className */
  className?: string;
  /** chart slot 附加 className */
  chartClassName?: string;
  /**
   * chart slot 最小高度（px）。默认 280 — 保证图表与 legend 都能呼吸，
   * 子卡含底部占比条等额外结构时，图表区不会被压扁。
   * 图表组件需开启 fillContainer 自适应缩放；如需更高图表区，调高此值。
   */
  chartMinHeight?: number;
  /**
   * 子卡宽高比（CSS aspect-ratio）。默认 'auto' — 高度由内容 + grid items-stretch
   * 决定，图表/占比条/标题随容器自适应。如需强制比例，传 '486 / 444' 等。
   */
  aspectRatio?: string;
}

export interface FeatureCardGroupProps {
  /** 外层模块标题；bare=true 时不渲染 */
  title?: string;
  /** 外层模块副文案 */
  subtitle?: string;
  /** 标题语义标签（透传给 DashboardModuleTitle） */
  titleAs?: 'h2' | 'h3' | 'h4';
  /**
   * 期望展示数量/列控输入（自动 clamp 到 [1, 6]）。
   * 组件一行最多 3 张；当期望数量大于传入 cards 数时，会复制已有卡片补足，避免出现空位。
   */
  columns?: number;
  /** 卡间距（px），默认 16 */
  gap?: number;
  /** 数据驱动模式：传入 cards 列表，组件按 columns 渲染等高 grid */
  cards?: FeatureCardProps[];
  /** 自定义模式：直接传入子卡（需自行使用 <FeatureCard />） */
  children?: ReactNode;
  /** 外层白卡附加 className（mt-3 等节奏类由调用方提供） */
  className?: string;
  /**
   * bare 模式：不渲染外层白卡 / padding / 标题区，仅渲染 grid + 子卡。
   * 适用于"已有外层白卡 + 共享标题区"的页面（如 UserPersonaDashboardPattern 的"核心反馈特征"卡）。
   */
  bare?: boolean;
}

const SUBCARD_BG = '#FCFCFD';
const SUBCARD_BORDER_COLOR = 'rgba(45,66,107,0.12)';

function clampDisplayTarget(raw: number | undefined): number {
  const n = Number.isFinite(raw) ? Number(raw) : 3;
  if (n < 1) return 1;
  if (n > 6) return 6;
  return Math.floor(n);
}

function getGridColumns(cardCount: number, requestedColumns: number): number {
  if (cardCount === 4) return 2;
  if (cardCount >= 5) return 3;
  return Math.min(Math.max(1, requestedColumns), 3);
}

function getStableDuplicateIndex(cards: FeatureCardProps[], displayIndex: number): number {
  const seed = cards
    .map((card) => card.title || '')
    .join('|')
    .split('')
    .reduce((sum, char) => sum + char.charCodeAt(0), 0);
  return (seed + displayIndex) % cards.length;
}

function buildDisplayCards(cards: FeatureCardProps[] | undefined, displayTarget: number) {
  if (!cards || cards.length === 0) return [];
  const result = cards.map((card, index) => ({ card, renderKey: `${card.title || 'card'}-${index}` }));
  while (result.length < displayTarget) {
    const duplicateIndex = getStableDuplicateIndex(cards, result.length);
    const duplicate = cards[duplicateIndex];
    result.push({
      card: duplicate,
      renderKey: `${duplicate.title || 'card'}-duplicate-${result.length}`,
    });
  }
  return result;
}

/** 单张子卡：标题区 + chart slot */
export function FeatureCard({
  title,
  subtitle = '',
  chart,
  className = '',
  chartClassName = '',
  chartMinHeight,
  aspectRatio = 'auto',
}: FeatureCardProps) {
  const cardStyle: CSSProperties = {
    background: SUBCARD_BG,
    border: `0.4px solid ${SUBCARD_BORDER_COLOR}`,
    rowGap: 16,
    padding: 16,
  };
  if (aspectRatio && aspectRatio !== 'auto') {
    cardStyle.aspectRatio = aspectRatio;
  }
  return (
    <div
      className={[
        'flex h-full min-w-0 flex-col rounded-xl',
        className,
      ]
        .filter(Boolean)
        .join(' ')}
      style={cardStyle}
    >
      <DashboardModuleTitle as="h4" title={title} subtitle={subtitle} />
      <div
        className={[
          'flex min-w-0 items-stretch overflow-hidden bg-white',
          chartClassName,
        ]
          .filter(Boolean)
          .join(' ')}
        style={{
          padding: 16,
          borderRadius: 8,
          minHeight: chartMinHeight ?? 240,
        }}
      >
        <div className="min-w-0 flex-1">{chart}</div>
      </div>
    </div>
  );
}

export default function FeatureCardGroup({
  title = '',
  subtitle = '',
  titleAs = 'h3',
  columns = 3,
  gap = 16,
  cards,
  children,
  className = '',
  bare = false,
}: FeatureCardGroupProps) {
  const displayTarget = clampDisplayTarget(columns);
  const displayCards = buildDisplayCards(cards, displayTarget);
  const cardCount = cards ? displayCards.length : 0;
  const cols = cards ? getGridColumns(cardCount, displayTarget) : Math.min(displayTarget, 3);
  const gridStyle: CSSProperties = {
    gap,
    gridTemplateColumns: `repeat(${cols}, minmax(0, 1fr))`,
  };

  const grid = (
    <div className="grid min-w-0 items-stretch" style={gridStyle}>
      {cards
        ? displayCards.map(({ card, renderKey }) => (
            <FeatureCard
              key={renderKey}
              title={card.title}
              subtitle={card.subtitle}
              chart={card.chart}
              className={card.className}
              chartClassName={card.chartClassName}
              chartMinHeight={card.chartMinHeight}
              aspectRatio={card.aspectRatio}
            />
          ))
        : children}
    </div>
  );

  if (bare) {
    return (
      <div className={['min-w-0', className].filter(Boolean).join(' ')}>
        {grid}
      </div>
    );
  }

  return (
    <section
      className={['min-w-0 rounded-xl bg-white', className].filter(Boolean).join(' ')}
      style={{ padding: 16 }}
    >
      {title ? (
        <div style={{ marginBottom: 16 }}>
          <DashboardModuleTitle as={titleAs} title={title} subtitle={subtitle} />
        </div>
      ) : null}
      {grid}
    </section>
  );
}
