/* ============================================================
   F2 UI — Core component stories (the 11 existing DS primitives)
   ============================================================ */
(function () {
  const F2 = window.F2;
  const { Icon, Button, IconButton, Badge, Tag, Card, Input, Switch, MonoLabel, StatusDot, WorkflowNode, FlowEdge } = F2;
  const G = 'Core';

  /* ---------------- Button ---------------- */
  window.story({
    id: 'button', group: G, name: 'Button',
    tagline: 'The primary action primitive — flat fills, hairline borders, a keycap-press feel. One amber primary per view.',
    importLine: "const { Button } = F2;",
    keywords: ['action', 'cta', 'submit'],
    props: [
      { name: 'variant', type: "'primary' | 'secondary' | 'ghost'", default: 'primary', control: 'select', options: ['primary', 'secondary', 'ghost'], description: 'Visual emphasis. Use primary (amber) for the single main action per view.' },
      { name: 'size', type: "'sm' | 'md' | 'lg'", default: 'md', control: 'select', options: ['sm', 'md', 'lg'], description: 'Control height — 32 / 40 / 48px.' },
      { name: 'children', type: 'ReactNode', default: 'Deploy agent', control: 'text', description: 'Button label.' },
      { name: 'disabled', type: 'boolean', default: false, control: 'boolean', description: 'Disables interaction; drops opacity to 0.45.' },
      { name: 'iconRight', type: 'ReactNode', default: true, control: 'boolean', description: 'Icon node after the label (here: an arrow).' },
      { name: 'iconLeft', type: 'ReactNode', description: 'Icon node before the label.' },
      { name: 'onClick', type: '(e) => void', description: 'Click handler.' },
    ],
    render: (v) => <Button variant={v.variant} size={v.size} disabled={v.disabled} iconRight={v.iconRight ? <Icon name="ArrowRight" size={v.size === 'lg' ? 18 : 16} /> : null}>{v.children}</Button>,
    code: (v) => `<Button variant="${v.variant}" size="${v.size}"${v.disabled ? ' disabled' : ''}${v.iconRight ? '\n  iconRight={<Icon name="ArrowRight" />}' : ''}>\n  ${v.children}\n</Button>`,
    examples: [
      { name: 'primary', render: () => <Button>Deploy agent</Button> },
      { name: 'secondary', render: () => <Button variant="secondary">Cancel</Button> },
      { name: 'ghost', render: () => <Button variant="ghost">Skip</Button> },
      { name: 'icon left', render: () => <Button variant="secondary" iconLeft={<Icon name="Plus" size={16} />}>New workflow</Button> },
      { name: 'icon right', render: () => <Button iconRight={<Icon name="ArrowRight" size={16} />}>Continue</Button> },
      { name: 'sm / md / lg', render: () => <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}><Button size="sm">sm</Button><Button size="md">md</Button><Button size="lg">lg</Button></div> },
      { name: 'disabled', render: () => <Button disabled>Disabled</Button> },
    ],
    a11y: [
      'Renders a native <code>&lt;button&gt;</code> — keyboard focusable and Enter/Space activatable out of the box.',
      'Disabled buttons set the <code>disabled</code> attribute (removed from the tab order). For a still-focusable disabled state, gate <code>onClick</code> instead.',
      'Icon-only actions should use <strong>IconButton</strong> with an <code>aria-label</code>, not a Button with an icon and no text.',
    ],
  });

  /* ---------------- IconButton ---------------- */
  window.story({
    id: 'icon-button', group: G, name: 'IconButton',
    tagline: 'Square, icon-only action. Always pass an aria-label — there is no visible text to name it.',
    importLine: "const { IconButton } = F2;",
    keywords: ['icon', 'action', 'toolbar'],
    props: [
      { name: 'variant', type: "'ghost' | 'solid' | 'accent'", default: 'ghost', control: 'select', options: ['ghost', 'solid', 'accent'], description: 'Ghost for toolbars, solid for surfaced actions, accent for the live/primary one.' },
      { name: 'size', type: "'sm' | 'md' | 'lg'", default: 'md', control: 'select', options: ['sm', 'md', 'lg'], description: 'Square control size.' },
      { name: 'aria-label', type: 'string', required: true, default: 'Settings', control: 'text', description: 'Required accessible name.' },
      { name: 'disabled', type: 'boolean', default: false, control: 'boolean', description: 'Disables interaction.' },
      { name: 'children', type: 'ReactNode', description: 'A single Lucide line icon.' },
    ],
    render: (v) => <IconButton variant={v.variant} size={v.size} disabled={v.disabled} aria-label={v['aria-label']}><Icon name="Settings2" size={v.size === 'sm' ? 16 : 18} /></IconButton>,
    code: (v) => `<IconButton variant="${v.variant}" size="${v.size}" aria-label="${v['aria-label']}">\n  <Icon name="Settings2" />\n</IconButton>`,
    examples: [
      { name: 'ghost', render: () => <IconButton variant="ghost" aria-label="More"><Icon name="MoreHorizontal" size={18} /></IconButton> },
      { name: 'solid', render: () => <IconButton variant="solid" aria-label="Copy"><Icon name="Copy" size={18} /></IconButton> },
      { name: 'accent', render: () => <IconButton variant="accent" aria-label="Run"><Icon name="Play" size={18} /></IconButton> },
      { name: 'sizes', render: () => <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}><IconButton size="sm" aria-label="a"><Icon name="Search" size={15} /></IconButton><IconButton size="md" aria-label="b"><Icon name="Search" size={18} /></IconButton><IconButton size="lg" aria-label="c"><Icon name="Search" size={20} /></IconButton></div> },
      { name: 'disabled', render: () => <IconButton disabled aria-label="Locked"><Icon name="Lock" size={18} /></IconButton> },
    ],
    a11y: [
      '<code>aria-label</code> is required and typed as such — an icon-only control with no name is invisible to screen readers.',
      'Use a verb for the label ("Delete row"), matching the action, not the icon shape.',
      'Reserve the <code>accent</code> variant for the single live/primary action so amber keeps its meaning.',
    ],
  });

  /* ---------------- Badge ---------------- */
  window.story({
    id: 'badge', group: G, name: 'Badge',
    tagline: 'A small mono status pill. The active tone (amber) marks a live or running node — use it sparingly.',
    importLine: "const { Badge } = F2;",
    keywords: ['status', 'pill', 'label', 'tag'],
    props: [
      { name: 'tone', type: "'neutral' | 'active' | 'success' | 'warning' | 'error'", default: 'neutral', control: 'select', options: ['neutral', 'active', 'success', 'warning', 'error'], description: 'Semantic color. Active = amber, the live node.' },
      { name: 'children', type: 'ReactNode', default: 'Running', control: 'text', description: 'Pill content. Kept short and uppercase by the mono type.' },
    ],
    render: (v) => <Badge tone={v.tone}>{v.tone === 'active' ? <StatusDot tone="active" live size={6} /> : null}{v.children}</Badge>,
    code: (v) => v.tone === 'active'
      ? `<Badge tone="active"><StatusDot tone="active" live size={6} /> ${v.children}</Badge>`
      : `<Badge tone="${v.tone}">${v.children}</Badge>`,
    examples: [
      { name: 'neutral', render: () => <Badge>Draft</Badge> },
      { name: 'active', render: () => <Badge tone="active"><StatusDot tone="active" live size={6} /> Live</Badge> },
      { name: 'success', render: () => <Badge tone="success">Deployed</Badge> },
      { name: 'warning', render: () => <Badge tone="warning">Degraded</Badge> },
      { name: 'error', render: () => <Badge tone="error">Failed</Badge> },
    ],
    a11y: [
      'Color is paired with a text label in every tone — never rely on hue alone to convey state.',
      'Warning is intentionally distinct from amber so the brand accent never reads as an alert.',
      'For status that updates live, wrap the surrounding region in <code>aria-live="polite"</code>.',
    ],
  });

  /* ---------------- Tag ---------------- */
  window.story({
    id: 'tag', group: G, name: 'Tag',
    tagline: 'A quiet, optionally removable label for filters and metadata.',
    importLine: "const { Tag } = F2;",
    keywords: ['filter', 'chip', 'metadata', 'remove'],
    props: [
      { name: 'children', type: 'ReactNode', default: 'invoice-ocr', control: 'text', description: 'Tag content.' },
      { name: 'removable', type: 'boolean', default: true, control: 'boolean', description: 'When onRemove is set, renders a × control.' },
      { name: 'onRemove', type: '() => void', description: 'Called when the remove control is clicked.' },
    ],
    render: (v) => <Tag onRemove={v.removable ? () => {} : undefined}>{v.children}</Tag>,
    code: (v) => v.removable ? `<Tag onRemove={() => removeTag(id)}>${v.children}</Tag>` : `<Tag>${v.children}</Tag>`,
    examples: [
      { name: 'plain', render: () => <Tag>read-only</Tag> },
      { name: 'removable', render: () => <Tag onRemove={() => {}}>invoice-ocr</Tag> },
      { name: 'filter row', render: () => <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}><Tag onRemove={() => {}}>PT-BR</Tag><Tag onRemove={() => {}}>agent</Tag><Tag onRemove={() => {}}>deploy</Tag></div> },
    ],
    a11y: [
      'The remove control is a real button with an accessible label ("Remove {tag}").',
      'When tags act as a filter set, manage focus after removal so keyboard users are not stranded.',
    ],
  });

  /* ---------------- Card ---------------- */
  window.story({
    id: 'card', group: G, name: 'Card',
    tagline: 'The base surface container. Elevation = raised surface + hairline border, never a shadow. Active lights the amber edge.',
    importLine: "const { Card } = F2;",
    keywords: ['surface', 'container', 'panel'],
    props: [
      { name: 'active', type: 'boolean', default: false, control: 'boolean', description: 'Lights the amber border + node dot to mark a live item.' },
      { name: 'interactive', type: 'boolean', default: false, control: 'boolean', description: 'Adds hover feedback for clickable cards.' },
      { name: 'children', type: 'ReactNode', description: 'Card content.' },
      { name: 'onClick', type: '(e) => void', description: 'Click handler for interactive cards.' },
    ],
    render: (v) => (
      <Card active={v.active} interactive={v.interactive} style={{ width: 280 }}>
        <MonoLabel node={v.active}>Invoice agent</MonoLabel>
        <div style={{ fontFamily: 'var(--f2-font-display)', fontSize: 18, fontWeight: 600, color: 'var(--f2-text)', marginTop: 10 }}>3 days → 20 minutes</div>
        <div style={{ color: 'var(--f2-text-muted)', fontSize: 14, marginTop: 6, lineHeight: 1.5 }}>Processing time after deploy.</div>
      </Card>
    ),
    code: (v) => `<Card${v.active ? ' active' : ''}${v.interactive ? ' interactive' : ''}>\n  <MonoLabel${v.active ? ' node' : ''}>Invoice agent</MonoLabel>\n  ...\n</Card>`,
    examples: [
      { name: 'default', render: () => <Card style={{ width: 200 }}><MonoLabel>Default</MonoLabel><div style={{ color: 'var(--f2-text-secondary)', marginTop: 8, fontSize: 14 }}>Resting surface.</div></Card> },
      { name: 'active', render: () => <Card active style={{ width: 200 }}><MonoLabel node>Live</MonoLabel><div style={{ color: 'var(--f2-text-secondary)', marginTop: 8, fontSize: 14 }}>Amber edge + node.</div></Card> },
      { name: 'interactive', render: () => <Card interactive style={{ width: 200 }}><MonoLabel>Hover me</MonoLabel><div style={{ color: 'var(--f2-text-secondary)', marginTop: 8, fontSize: 14 }}>Border brightens.</div></Card> },
    ],
    a11y: [
      'A clickable card should be reachable by keyboard — add <code>role="button"</code> + <code>tabIndex={0}</code> and an Enter/Space handler, or wrap the heading in a real link.',
      'Do not bury the only copy of an action inside a card with no focusable child.',
    ],
  });

  /* ---------------- Input ---------------- */
  window.story({
    id: 'input', group: G, name: 'Input',
    tagline: 'Single-line field with optional mono label, prefix glyph, amber focus ring, and an error state.',
    importLine: "const { Input } = F2;",
    keywords: ['field', 'text', 'form'],
    props: [
      { name: 'label', type: 'string', default: 'Work email', control: 'text', description: 'Label shown above the field.' },
      { name: 'placeholder', type: 'string', default: 'you@company.com', control: 'text', description: 'Placeholder text.' },
      { name: 'mono', type: 'boolean', default: true, control: 'boolean', description: 'Render the label as an uppercase mono label.' },
      { name: 'prefix', type: 'ReactNode', default: false, control: 'boolean', description: 'Static prefix glyph inside the field (here: @).' },
      { name: 'error', type: 'boolean', default: false, control: 'boolean', description: 'Error state — red border.' },
      { name: 'disabled', type: 'boolean', default: false, control: 'boolean', description: 'Disables the field.' },
    ],
    render: (v) => <Input label={v.label} placeholder={v.placeholder} mono={v.mono} error={v.error} disabled={v.disabled} prefix={v.prefix ? '@' : null} style={{ width: 320 }} />,
    code: (v) => `<Input\n  label="${v.label}"\n  placeholder="${v.placeholder}"${v.mono ? '' : '\n  mono={false}'}${v.prefix ? '\n  prefix="@"' : ''}${v.error ? '\n  error' : ''}\n/>`,
    examples: [
      { name: 'default', render: () => <Input label="Name" placeholder="Ada Lovelace" style={{ width: 220 }} /> },
      { name: 'prefix', render: () => <Input label="Handle" prefix="@" placeholder="f2tech" style={{ width: 220 }} /> },
      { name: 'error', render: () => <Input label="Email" error defaultValue="not-an-email" style={{ width: 220 }} /> },
      { name: 'non-mono label', render: () => <Input label="Company" mono={false} placeholder="Acme" style={{ width: 220 }} /> },
      { name: 'disabled', render: () => <Input label="Locked" disabled placeholder="—" style={{ width: 220 }} /> },
    ],
    a11y: [
      'The label is associated with the field via <code>htmlFor</code>/<code>id</code> — clicking it focuses the input.',
      'In the error state, also set <code>aria-invalid</code> and reference an error message with <code>aria-describedby</code>.',
      'The focus ring uses the accent-text role (amber on dark, amber-deep on light) so it passes contrast on both themes.',
    ],
  });

  /* ---------------- Switch ---------------- */
  window.story({
    id: 'switch', group: G, name: 'Switch',
    tagline: 'Binary toggle. On = amber track. Quick, settled motion; no bounce.',
    importLine: "const { Switch } = F2;",
    keywords: ['toggle', 'boolean', 'setting'],
    props: [
      { name: 'checked', type: 'boolean', default: true, control: 'boolean', description: 'Controlled on/off state.' },
      { name: 'disabled', type: 'boolean', default: false, control: 'boolean', description: 'Disables the toggle.' },
      { name: 'onChange', type: '(next: boolean) => void', description: 'Called with the next state.' },
      { name: 'aria-label', type: 'string', description: 'Accessible name when there is no visible label.' },
    ],
    render: function SwitchDemo(v) {
      const [on, setOn] = React.useState(v.checked);
      React.useEffect(() => setOn(v.checked), [v.checked]);
      return <Switch checked={on} disabled={v.disabled} onChange={setOn} aria-label="Demo toggle" />;
    },
    code: (v) => `const [on, setOn] = useState(${v.checked});\n<Switch checked={on} onChange={setOn} aria-label="Notifications"${v.disabled ? ' disabled' : ''} />`,
    examples: [
      { name: 'on', render: () => <Switch checked onChange={() => {}} aria-label="on" /> },
      { name: 'off', render: () => <Switch checked={false} onChange={() => {}} aria-label="off" /> },
      { name: 'disabled', render: () => <Switch checked disabled aria-label="disabled" /> },
      { name: 'with label', render: () => <label style={{ display: 'flex', alignItems: 'center', gap: 10, color: 'var(--f2-text)', fontSize: 14 }}><Switch checked onChange={() => {}} aria-label="x" /> Email alerts</label> },
    ],
    a11y: [
      'Renders a button with <code>role="switch"</code> and <code>aria-checked</code> — announced as a toggle, not a checkbox.',
      'Pair with a visible <code>&lt;label&gt;</code> or pass <code>aria-label</code>; do not leave it unnamed.',
    ],
  });

  /* ---------------- MonoLabel ---------------- */
  window.story({
    id: 'mono-label', group: G, name: 'MonoLabel',
    tagline: 'The technical-signal label — uppercase JetBrains Mono with wide tracking and an optional amber node.',
    importLine: "const { MonoLabel } = F2;",
    keywords: ['label', 'mono', 'caption', 'metadata'],
    props: [
      { name: 'children', type: 'ReactNode', default: 'SYSTEM STATUS', control: 'text', description: 'Label text — uppercased by the type.' },
      { name: 'node', type: 'boolean', default: true, control: 'boolean', description: 'Show a leading amber node dot.' },
      { name: 'accent', type: 'boolean', default: false, control: 'boolean', description: 'Color the whole label amber (use sparingly).' },
    ],
    render: (v) => <MonoLabel node={v.node} accent={v.accent}>{v.children}</MonoLabel>,
    code: (v) => `<MonoLabel${v.node ? ' node' : ''}${v.accent ? ' accent' : ''}>${v.children}</MonoLabel>`,
    examples: [
      { name: 'plain', render: () => <MonoLabel>METADATA</MonoLabel> },
      { name: 'with node', render: () => <MonoLabel node>ACTIVE NODE</MonoLabel> },
      { name: 'accent', render: () => <MonoLabel accent node>LIVE</MonoLabel> },
    ],
    a11y: [
      'Wide letter-spacing on uppercase text can hurt readability — keep labels short (1–3 words).',
      'This is a styling primitive, not a heading; use real heading elements for document structure.',
    ],
  });

  /* ---------------- StatusDot ---------------- */
  window.story({
    id: 'status-dot', group: G, name: 'StatusDot',
    tagline: 'A small state indicator; live pulses amber in a square-wave heartbeat for a running system.',
    importLine: "const { StatusDot } = F2;",
    keywords: ['status', 'indicator', 'dot', 'live'],
    props: [
      { name: 'tone', type: "'neutral' | 'active' | 'success' | 'warning' | 'error'", default: 'active', control: 'select', options: ['neutral', 'active', 'success', 'warning', 'error'], description: 'Indicator color.' },
      { name: 'live', type: 'boolean', default: true, control: 'boolean', description: 'Pulse to signal an active/running state. Respects reduced motion.' },
      { name: 'size', type: 'number', default: 10, control: 'number', min: 6, max: 20, step: 1, description: 'Diameter in px.' },
    ],
    render: (v) => <StatusDot tone={v.tone} live={v.live} size={v.size} />,
    code: (v) => `<StatusDot tone="${v.tone}"${v.live ? ' live' : ''} size={${v.size}} />`,
    examples: [
      { name: 'live (active)', render: () => <StatusDot tone="active" live size={12} /> },
      { name: 'success', render: () => <StatusDot tone="success" size={12} /> },
      { name: 'warning', render: () => <StatusDot tone="warning" size={12} /> },
      { name: 'error', render: () => <StatusDot tone="error" size={12} /> },
      { name: 'neutral', render: () => <StatusDot tone="neutral" size={12} /> },
    ],
    a11y: [
      'A dot alone is not accessible — pair it with text (as in Badge) or add an <code>aria-label</code> / visually-hidden status.',
      'The pulse animation is disabled under <code>prefers-reduced-motion: reduce</code>.',
    ],
  });

  /* ---------------- WorkflowNode ---------------- */
  window.story({
    id: 'workflow-node', group: G, name: 'WorkflowNode',
    tagline: 'One node in the house-style agent diagram — rounded square, card fill, hairline border; active lights amber.',
    importLine: "const { WorkflowNode } = F2;",
    keywords: ['diagram', 'agent', 'flow', 'node'],
    props: [
      { name: 'label', type: 'string', required: true, default: 'AGENT', control: 'text', description: 'Short uppercase label (TRIGGER, AGENT, TOOL CALL, OUTPUT).' },
      { name: 'active', type: 'boolean', default: true, control: 'boolean', description: 'Lights the amber border + node dot.' },
      { name: 'icon', type: 'ReactNode', default: true, control: 'boolean', description: 'Optional leading line icon.' },
    ],
    render: (v) => <WorkflowNode label={v.label} active={v.active} icon={v.icon ? <Icon name="Bot" size={16} /> : null} />,
    code: (v) => `<WorkflowNode label="${v.label}"${v.active ? ' active' : ''}${v.icon ? '\n  icon={<Icon name="Bot" />}' : ''} />`,
    examples: [
      { name: 'trigger', render: () => <WorkflowNode label="TRIGGER" icon={<Icon name="Webhook" size={16} />} /> },
      { name: 'agent (active)', render: () => <WorkflowNode label="AGENT" active icon={<Icon name="Bot" size={16} />} /> },
      { name: 'tool call', render: () => <WorkflowNode label="TOOL CALL" icon={<Icon name="Wrench" size={16} />} /> },
      { name: 'output', render: () => <WorkflowNode label="OUTPUT" icon={<Icon name="CheckCircle2" size={16} />} /> },
    ],
    a11y: [
      'Diagrams should carry a text alternative — label the container with <code>role="img"</code> + <code>aria-label</code>, or provide a caption describing the flow.',
      'Keep labels terse; the wide mono tracking is for scanning, not prose.',
    ],
  });

  /* ---------------- FlowEdge ---------------- */
  window.story({
    id: 'flow-edge', group: G, name: 'FlowEdge',
    tagline: 'A 1.5px connector with a soft arrowhead between workflow nodes; final colors the edge into OUTPUT amber.',
    importLine: "const { FlowEdge } = F2;",
    keywords: ['diagram', 'connector', 'edge', 'arrow'],
    props: [
      { name: 'final', type: 'boolean', default: false, control: 'boolean', description: 'The terminal edge into OUTPUT — renders amber.' },
      { name: 'length', type: 'number', default: 64, control: 'number', min: 24, max: 160, step: 4, description: 'Connector length in px.' },
      { name: 'vertical', type: 'boolean', default: false, control: 'boolean', description: 'Vertical orientation (default horizontal).' },
    ],
    render: (v) => (
      <div style={{ display: 'flex', alignItems: 'center', flexDirection: v.vertical ? 'column' : 'row', gap: 4 }}>
        <WorkflowNode label="A" />
        <FlowEdge final={v.final} length={v.length} vertical={v.vertical} />
        <WorkflowNode label="B" active={v.final} />
      </div>
    ),
    code: (v) => `<FlowEdge${v.final ? ' final' : ''} length={${v.length}}${v.vertical ? ' vertical' : ''} />`,
    examples: [
      { name: 'horizontal', render: () => <div style={{ display: 'flex', alignItems: 'center' }}><WorkflowNode label="A" /><FlowEdge length={56} /><WorkflowNode label="B" /></div> },
      { name: 'final (amber)', render: () => <div style={{ display: 'flex', alignItems: 'center' }}><WorkflowNode label="AGENT" /><FlowEdge final length={56} /><WorkflowNode label="OUT" active /></div> },
      { name: 'vertical', render: () => <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}><WorkflowNode label="A" /><FlowEdge vertical length={40} /><WorkflowNode label="B" /></div> },
    ],
    a11y: [
      'Edges are decorative connectors — they are marked <code>aria-hidden</code>; the meaning lives in the nodes and the diagram caption.',
      'The final/amber edge is reinforced by the active OUTPUT node, not color alone.',
    ],
  });
})();
