/* ============================================================
   F2 UI — Forms stories
   ============================================================ */
(function () {
  const F2 = window.F2;
  const { Icon, Select, Checkbox, RadioGroup, Textarea, Slider, DatePicker, FileUpload, Button } = F2;
  const G = 'Forms';

  const WF = [
    { value: 'invoice', label: 'Invoice OCR → ERP' },
    { value: 'leads', label: 'Lead routing agent' },
    { value: 'support', label: 'Support triage' },
    { value: 'recon', label: 'Bank reconciliation' },
  ];

  /* ---------------- Select ---------------- */
  function SelectDemo(v) {
    const [val, setVal] = React.useState('invoice');
    return <Select label={v.label ? 'Workflow' : undefined} disabled={v.disabled} error={v.error}
      value={val} onChange={setVal} options={WF} placeholder="Select a workflow" style={{ width: 300 }} />;
  }
  window.story({
    id: 'select', group: G, name: 'Select', status: 'new',
    tagline: 'A fully custom listbox — keyboard-navigable, click-outside to close, amber focus ring and check on the selected option.',
    importLine: "const { Select } = F2;",
    keywords: ['dropdown', 'listbox', 'combobox', 'form'],
    props: [
      { name: 'value', type: 'string', description: 'Selected option value (controlled).' },
      { name: 'onChange', type: '(value) => void', description: 'Fired with the chosen value.' },
      { name: 'options', type: 'Array<{value,label}> | string[]', description: 'Options to render.' },
      { name: 'placeholder', type: 'string', default: 'Select…', description: 'Shown when nothing is selected.' },
      { name: 'label', type: 'string', default: true, control: 'boolean', description: 'Optional mono label above the field.' },
      { name: 'disabled', type: 'boolean', default: false, control: 'boolean', description: 'Disables the trigger.' },
      { name: 'error', type: 'boolean', default: false, control: 'boolean', description: 'Red border error state.' },
    ],
    render: (v) => <SelectDemo {...v} />,
    code: (v) => `const [value, setValue] = useState();\n<Select\n  ${v.label ? 'label="Workflow"\n  ' : ''}value={value}\n  onChange={setValue}\n  options={workflows}\n  placeholder="Select a workflow"${v.error ? '\n  error' : ''}${v.disabled ? '\n  disabled' : ''}\n/>`,
    examples: [
      { name: 'default', render: () => <SelectDemo label /> },
      { name: 'error', render: () => <SelectDemo label error /> },
      { name: 'disabled', render: () => <SelectDemo label disabled /> },
    ],
    a11y: [
      'Trigger uses <code>role="combobox"</code> with <code>aria-expanded</code>/<code>aria-haspopup</code>; the list is <code>role="listbox"</code> and options are <code>role="option"</code> with <code>aria-selected</code>.',
      'Keyboard: <kbd>↑</kbd>/<kbd>↓</kbd> move the active option, <kbd>Enter</kbd>/<kbd>Space</kbd> select, <kbd>Esc</kbd> closes.',
      'The selected option is marked with both a check icon and <code>aria-selected</code>, never color alone.',
    ],
  });

  /* ---------------- Checkbox ---------------- */
  function CheckDemo(v) {
    const [on, setOn] = React.useState(true);
    return <Checkbox checked={on} onChange={setOn} disabled={v.disabled} error={v.error} indeterminate={v.indeterminate} label={v.label ? 'Email me deploy alerts' : undefined} />;
  }
  window.story({
    id: 'checkbox', group: G, name: 'Checkbox', status: 'new',
    tagline: 'Boolean input with an amber checked state and an indeterminate mode for "some selected" parent rows.',
    importLine: "const { Checkbox } = F2;",
    keywords: ['check', 'boolean', 'form', 'multi-select'],
    props: [
      { name: 'checked', type: 'boolean', default: true, control: 'boolean', description: 'Checked state (controlled).' },
      { name: 'onChange', type: '(checked) => void', description: 'Fired with the next boolean.' },
      { name: 'label', type: 'ReactNode', default: true, control: 'boolean', description: 'Inline label (click toggles).' },
      { name: 'indeterminate', type: 'boolean', default: false, control: 'boolean', description: 'Mixed state — overrides the visual until checked changes.' },
      { name: 'disabled', type: 'boolean', default: false, control: 'boolean', description: 'Disables the input.' },
      { name: 'error', type: 'boolean', default: false, control: 'boolean', description: 'Red border (e.g. required-but-unchecked).' },
    ],
    render: (v) => <CheckDemo {...v} />,
    code: (v) => `const [checked, setChecked] = useState(true);\n<Checkbox\n  checked={checked}\n  onChange={setChecked}${v.indeterminate ? '\n  indeterminate' : ''}${v.error ? '\n  error' : ''}\n  label="Email me deploy alerts"\n/>`,
    examples: [
      { name: 'checked', render: () => <Checkbox checked onChange={() => {}} label="Checked" /> },
      { name: 'unchecked', render: () => <Checkbox checked={false} onChange={() => {}} label="Unchecked" /> },
      { name: 'indeterminate', render: () => <Checkbox indeterminate onChange={() => {}} label="Select all" /> },
      { name: 'disabled', render: () => <Checkbox checked disabled label="Locked" /> },
    ],
    a11y: [
      'Wraps a native <code>&lt;input type="checkbox"&gt;</code> — the visible box is decorative and the real control carries focus and state.',
      'Clicking the label toggles the box because the input and text share one <code>&lt;label&gt;</code>.',
      'Indeterminate is set on the DOM node via the <code>indeterminate</code> property (not an attribute) for correct AT announcement.',
    ],
  });

  /* ---------------- RadioGroup ---------------- */
  function RadioDemo(v) {
    const [val, setVal] = React.useState('monthly');
    return <RadioGroup label={v.label ? 'Billing period' : undefined} orientation={v.orientation} disabled={v.disabled} value={val} onChange={setVal}
      options={[{ value: 'monthly', label: 'Monthly', hint: 'R$ 4.900 / mo' }, { value: 'annual', label: 'Annual', hint: '2 months free' }, { value: 'usage', label: 'Usage-based', hint: 'Pay per run' }]} />;
  }
  window.story({
    id: 'radio-group', group: G, name: 'RadioGroup', status: 'new',
    tagline: 'Single-choice group with optional per-option hints; vertical or horizontal.',
    importLine: "const { RadioGroup } = F2;",
    keywords: ['radio', 'choice', 'form', 'options'],
    props: [
      { name: 'value', type: 'string', description: 'Selected value (controlled).' },
      { name: 'onChange', type: '(value) => void', description: 'Fired with the selected value.' },
      { name: 'options', type: 'Array<{value,label,hint?,disabled?}>', description: 'Radio options.' },
      { name: 'label', type: 'string', default: true, control: 'boolean', description: 'Group label (renders the group as a labelled radiogroup).' },
      { name: 'orientation', type: "'vertical' | 'horizontal'", default: 'vertical', control: 'select', options: ['vertical', 'horizontal'], description: 'Layout direction.' },
      { name: 'disabled', type: 'boolean', default: false, control: 'boolean', description: 'Disables the whole group.' },
    ],
    render: (v) => <RadioDemo {...v} />,
    code: (v) => `const [value, setValue] = useState('monthly');\n<RadioGroup\n  label="Billing period"\n  orientation="${v.orientation}"\n  value={value}\n  onChange={setValue}\n  options={periods}\n/>`,
    examples: [
      { name: 'vertical + hints', render: () => <RadioDemo label /> },
      { name: 'horizontal', render: () => <RadioDemo orientation="horizontal" /> },
    ],
    a11y: [
      'Renders <code>role="radiogroup"</code> with native <code>&lt;input type="radio"&gt;</code> controls sharing a name — arrow keys move within the group per platform convention.',
      'Each option label is clickable; hints are associated visually within the same label.',
    ],
  });

  /* ---------------- Textarea ---------------- */
  function TextareaDemo(v) {
    const [val, setVal] = React.useState('Cut invoice processing from 3 days to 20 minutes.');
    return <Textarea label={v.label ? 'System prompt' : undefined} rows={v.rows} error={v.error} disabled={v.disabled} maxLength={v.maxLength ? 180 : undefined} value={val} onChange={setVal} placeholder="Describe the agent…" style={{ width: 360 }} />;
  }
  window.story({
    id: 'textarea', group: G, name: 'Textarea', status: 'new',
    tagline: 'Multi-line field matching Input — hairline border, amber focus ring, optional character counter.',
    importLine: "const { Textarea } = F2;",
    keywords: ['textarea', 'multiline', 'form', 'input'],
    props: [
      { name: 'value', type: 'string', description: 'Field value (controlled).' },
      { name: 'onChange', type: '(value) => void', description: 'Fired with the next string.' },
      { name: 'label', type: 'string', default: true, control: 'boolean', description: 'Optional mono label.' },
      { name: 'rows', type: 'number', default: 4, control: 'number', min: 2, max: 10, step: 1, description: 'Initial visible rows.' },
      { name: 'maxLength', type: 'number', default: true, control: 'boolean', description: 'When set, shows a live character counter (here 180).' },
      { name: 'error', type: 'boolean', default: false, control: 'boolean', description: 'Red border error state.' },
      { name: 'disabled', type: 'boolean', default: false, control: 'boolean', description: 'Disables the field.' },
    ],
    render: (v) => <TextareaDemo {...v} />,
    code: (v) => `const [value, setValue] = useState('');\n<Textarea\n  label="System prompt"\n  rows={${v.rows}}${v.maxLength ? '\n  maxLength={180}' : ''}${v.error ? '\n  error' : ''}\n  value={value}\n  onChange={setValue}\n/>`,
    examples: [
      { name: 'with counter', render: () => <TextareaDemo label maxLength /> },
      { name: 'error', render: () => <TextareaDemo label error /> },
    ],
    a11y: [
      'The mono label is tied to the field via <code>htmlFor</code>/<code>id</code>.',
      'When <code>maxLength</code> is set the counter is visible; for screen readers, mirror remaining characters in an <code>aria-live</code> region near submit.',
      'Vertical resize stays enabled so users can expand long content.',
    ],
  });

  /* ---------------- Slider ---------------- */
  function SliderDemo(v) {
    const [val, setVal] = React.useState(v.start != null ? v.start : 40);
    return <Slider label={v.label ? 'Confidence threshold' : undefined} min={0} max={100} step={v.step} unit={v.unit || '%'} disabled={v.disabled} showValue={v.showValue} value={val} onChange={setVal} style={{ width: 320 }} />;
  }
  window.story({
    id: 'slider', group: G, name: 'Slider', status: 'new',
    tagline: 'Native range styled with an amber fill and a ringed thumb — accessible by keyboard, polished cross-browser.',
    importLine: "const { Slider } = F2;",
    keywords: ['range', 'slider', 'threshold', 'form'],
    props: [
      { name: 'value', type: 'number', description: 'Current value (controlled).' },
      { name: 'onChange', type: '(value) => void', description: 'Fired with the next number.' },
      { name: 'min', type: 'number', default: 0, description: 'Minimum value.' },
      { name: 'max', type: 'number', default: 100, description: 'Maximum value.' },
      { name: 'step', type: 'number', default: 1, control: 'number', min: 1, max: 25, step: 1, description: 'Increment.' },
      { name: 'showValue', type: 'boolean', default: true, control: 'boolean', description: 'Show the numeric readout.' },
      { name: 'label', type: 'string', default: true, control: 'boolean', description: 'Optional mono label.' },
      { name: 'disabled', type: 'boolean', default: false, control: 'boolean', description: 'Disables the slider.' },
    ],
    render: (v) => <SliderDemo {...v} />,
    code: (v) => `const [value, setValue] = useState(40);\n<Slider\n  label="Confidence threshold"\n  min={0} max={100} step={${v.step}}\n  unit="%"\n  value={value}\n  onChange={setValue}\n/>`,
    examples: [
      { name: 'low', render: () => <SliderDemo label start={15} /> },
      { name: 'high', render: () => <SliderDemo label start={85} /> },
      { name: 'no readout', render: () => <SliderDemo showValue={false} start={50} /> },
    ],
    a11y: [
      'Built on a native <code>&lt;input type="range"&gt;</code>, so it is operable with <kbd>←</kbd>/<kbd>→</kbd>/<kbd>Home</kbd>/<kbd>End</kbd> and exposes the value to AT.',
      'Pass a <code>label</code> (or <code>aria-label</code>) so the purpose of the slider is announced.',
      'The thumb shows a visible focus ring under keyboard focus.',
    ],
  });

  /* ---------------- DatePicker ---------------- */
  function DateDemo(v) {
    const [val, setVal] = React.useState('');
    return <DatePicker label={v.label ? 'Go-live date' : undefined} disabled={v.disabled} value={val} onChange={setVal} style={{ width: 260 }} />;
  }
  window.story({
    id: 'date-picker', group: G, name: 'DatePicker', status: 'new',
    tagline: 'A compact month calendar in a popover — today marked with a hairline, the selected day filled amber.',
    importLine: "const { DatePicker } = F2;",
    keywords: ['calendar', 'date', 'form', 'popover'],
    props: [
      { name: 'value', type: "string  // 'YYYY-MM-DD'", description: 'Selected date (controlled).' },
      { name: 'onChange', type: '(iso) => void', description: 'Fired with the ISO date string.' },
      { name: 'label', type: 'string', default: true, control: 'boolean', description: 'Optional mono label.' },
      { name: 'placeholder', type: 'string', default: 'Pick a date', description: 'Trigger text when empty.' },
      { name: 'disabled', type: 'boolean', default: false, control: 'boolean', description: 'Disables the trigger.' },
    ],
    render: (v) => <DateDemo {...v} />,
    code: (v) => `const [date, setDate] = useState('');\n<DatePicker\n  label="Go-live date"\n  value={date}\n  onChange={setDate}${v.disabled ? '\n  disabled' : ''}\n/>`,
    examples: [
      { name: 'empty', render: () => <DateDemo label /> },
      { name: 'preset', render: () => { const C = () => { const [d, setD] = React.useState('2026-07-15'); return <DatePicker label="Go-live" value={d} onChange={setD} style={{ width: 240 }} />; }; return <C />; } },
    ],
    a11y: [
      'The popover opens in a <code>role="dialog"</code>; month navigation buttons carry explicit labels ("Previous month").',
      'Day cells are real buttons — tab-reachable and Enter-activatable; today is distinguished by a hairline, not only color.',
      'Closes on outside click and <kbd>Esc</kbd>.',
    ],
    notes: 'Stores and emits an ISO <code>YYYY-MM-DD</code> string so it round-trips cleanly through APIs and the F2 token-driven inputs.',
  });

  /* ---------------- FileUpload ---------------- */
  window.story({
    id: 'file-upload', group: G, name: 'FileUpload', status: 'new',
    tagline: 'A drag-and-drop dropzone with a click-to-browse fallback, amber drag-over state and a removable file list.',
    importLine: "const { FileUpload } = F2;",
    keywords: ['file', 'upload', 'dropzone', 'drag'],
    props: [
      { name: 'onFiles', type: '(files: File[]) => void', description: 'Fired with the selected/dropped files.' },
      { name: 'multiple', type: 'boolean', default: true, control: 'boolean', description: 'Allow more than one file.' },
      { name: 'accept', type: 'string', description: 'Native accept filter, e.g. ".csv,.pdf".' },
      { name: 'label', type: 'string', default: true, control: 'boolean', description: 'Optional mono label above the zone.' },
      { name: 'hint', type: 'string', default: 'PNG, PDF or CSV up to 10MB', description: 'Secondary hint text.' },
      { name: 'disabled', type: 'boolean', default: false, control: 'boolean', description: 'Disables the zone.' },
    ],
    render: (v) => <FileUpload label={v.label ? 'Training documents' : undefined} multiple={v.multiple} disabled={v.disabled} onFiles={() => {}} style={{ width: 420 }} />,
    code: (v) => `<FileUpload\n  label="Training documents"\n  multiple={${v.multiple}}\n  accept=".pdf,.csv"\n  onFiles={(files) => upload(files)}\n/>`,
    examples: [
      { name: 'idle', render: () => <FileUpload label="Documents" onFiles={() => {}} style={{ width: 300 }} /> },
      { name: 'single file', render: () => <FileUpload multiple={false} hint="One CSV file" onFiles={() => {}} style={{ width: 300 }} /> },
    ],
    a11y: [
      'The zone is a <code>role="button"</code> with <code>tabIndex={0}</code> and Enter/Space support — not drag-only.',
      'Each listed file has a labelled remove button ("Remove {name}").',
      'Drag-over feedback uses an amber border <em>and</em> a surface change, so it is perceivable without color.',
    ],
  });
})();
