// Component Anatomy v2 — builds per-kind anatomy trees, variant × state matrices,
// and typed prop surfaces that downstream generators can turn into stubs.

const KNOWN_VARIANTS = ['primary', 'secondary', 'tertiary', 'ghost', 'outline', 'solid', 'destructive', 'danger', 'success', 'warning', 'link', 'subtle'];
const KNOWN_SIZES = ['xs', 'sm', 'md', 'lg', 'xl', 'small', 'medium', 'large'];

function slotFingerprint(slots = []) {
  return slots.map(s => s.role).join('>');
}

function inferSlots(slots = [], kind) {
  const roles = new Set(slots.map(s => s.role));
  if (kind === 'button') {
    return {
      label: true,
      icon: roles.has('icon'),
      badge: roles.has('badge'),
    };
  }
  if (kind === 'card') {
    return {
      heading: roles.has('heading'),
      description: roles.has('text'),
      media: roles.has('icon'),
      footer: slots.length > 3,
    };
  }
  if (kind === 'input') {
    return { leading: roles.has('icon'), trailing: false };
  }
  return {};
}

function dominant(arr) {
  const counts = {};
  for (const v of arr) counts[v] = (counts[v] || 0) + 1;
  return Object.entries(counts).sort((a, b) => b[1] - a[1])[0]?.[0] || '';
}

export function extractComponentAnatomy(candidates = []) {
  const byKind = {};
  for (const c of candidates) {
    const k = c.kind || 'other';
    (byKind[k] ||= []).push(c);
  }

  const anatomies = [];
  for (const [kind, items] of Object.entries(byKind)) {
    if (items.length < 2) continue;

    // Group variants by explicit class hint, fall back to style vector.
    const variantGroups = {};
    for (const it of items) {
      const v = it.variantHint || 'default';
      (variantGroups[v] ||= []).push(it);
    }

    const variants = Object.entries(variantGroups).map(([name, vs]) => {
      const sizes = {};
      for (const it of vs) {
        const sz = it.sizeHint || 'default';
        (sizes[sz] ||= []).push(it);
      }
      return {
        name,
        count: vs.length,
        states: {
          default: { count: vs.filter(v => !v.disabled).length, css: vs.find(v => !v.disabled)?.css || null },
          disabled: { count: vs.filter(v => v.disabled).length, css: vs.find(v => v.disabled)?.css || null },
        },
        sizes: Object.entries(sizes).map(([sName, sItems]) => ({ name: sName, count: sItems.length, css: sItems[0].css })),
        sampleText: vs.slice(0, 5).map(v => v.text).filter(Boolean),
      };
    }).sort((a, b) => b.count - a.count);

    const slotSignatures = items.map(i => slotFingerprint(i.slots));
    const anatomy = {
      kind,
      totalInstances: items.length,
      slots: inferSlots(items[0].slots, kind),
      dominantSlotShape: dominant(slotSignatures),
      variants,
      props: {
        variant: Object.keys(variantGroups).filter(v => v !== 'default'),
        size: [...new Set(items.map(i => i.sizeHint).filter(Boolean))],
        disabled: items.some(i => i.disabled),
      },
    };
    anatomies.push(anatomy);
  }

  return anatomies.sort((a, b) => b.totalInstances - a.totalInstances);
}

// Emit TypeScript-flavored React stub for the anatomy — includes variant/size props + slot children.
export function formatAnatomyStubs(anatomies = []) {
  const lines = [
    "// Auto-generated by designlang — component anatomy v2.",
    "// Scaffolds. Wire into your token system; not a runtime library.",
    "",
    "import * as React from 'react';",
    "",
  ];
  for (const a of anatomies) {
    const Name = a.kind.charAt(0).toUpperCase() + a.kind.slice(1);
    const variantUnion = (a.props.variant.length ? a.props.variant : ['default']).map(v => `'${v}'`).join(' | ');
    const sizeUnion = (a.props.size.length ? a.props.size : ['md']).map(v => `'${v}'`).join(' | ');
    lines.push(`export interface ${Name}Props {`);
    lines.push(`  variant?: ${variantUnion};`);
    lines.push(`  size?: ${sizeUnion};`);
    if (a.props.disabled) lines.push(`  disabled?: boolean;`);
    if (a.slots.icon) lines.push(`  leadingIcon?: React.ReactNode;`);
    if (a.slots.badge) lines.push(`  badge?: React.ReactNode;`);
    lines.push(`  children?: React.ReactNode;`);
    lines.push(`}`);
    lines.push(``);
    lines.push(`export function ${Name}({ variant = '${a.props.variant[0] || 'default'}', size = 'md', ...rest }: ${Name}Props) {`);
    lines.push(`  return React.createElement('${a.kind === 'input' ? 'input' : a.kind === 'link' ? 'a' : a.kind === 'card' ? 'div' : 'button'}', { 'data-variant': variant, 'data-size': size, ...rest });`);
    lines.push(`}`);
    lines.push(``);
  }
  return lines.join('\n');
}
