// Advanced form primitives: DatePicker, TimePicker, FileUpload, Combobox, RichText, ColorInput, Slider

// --- DATE PICKER ---
const DatePicker = ({ value, onChange, placeholder = 'Pick a date', min, max }) => {
  const anchor = React.useRef(null);
  const [open, setOpen] = React.useState(false);
  const [view, setView] = React.useState(() => value ? new Date(value) : new Date());

  const monthStart = new Date(view.getFullYear(), view.getMonth(), 1);
  const dayOffset = (monthStart.getDay() + 6) % 7; // Mon=0
  const daysInMonth = new Date(view.getFullYear(), view.getMonth() + 1, 0).getDate();
  const cells = [];
  for (let i = 0; i < dayOffset; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(view.getFullYear(), view.getMonth(), d));

  const isSame = (a, b) => a && b && a.toDateString() === b.toDateString();
  const today = new Date();
  const selected = value ? new Date(value) : null;
  const monthName = view.toLocaleDateString('en-US', { month: 'long', year: 'numeric' });
  const labelText = selected ? selected.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : placeholder;

  return (
    <>
      <button
        ref={anchor}
        onClick={() => setOpen(o => !o)}
        style={{
          display: 'flex', alignItems: 'center', gap: 10,
          border: '1px solid var(--line-2)', background: 'var(--bg-raised)',
          borderRadius: 8, padding: '0 12px', height: 38,
          fontFamily: 'inherit', fontSize: 14, color: selected ? 'var(--ink)' : 'var(--ink-3)',
          cursor: 'pointer', width: '100%', textAlign: 'left',
        }}>
        <Icon name="calendar" size={16} style={{ color: 'var(--ink-3)' }}/>
        <span style={{ flex: 1 }}>{labelText}</span>
      </button>
      <Popover open={open} anchor={anchor} onClose={() => setOpen(false)}>
        <div style={{ padding: 12, width: 280 }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
            <button onClick={() => setView(v => new Date(v.getFullYear(), v.getMonth()-1, 1))}
              style={{ border: 0, background: 'transparent', cursor: 'pointer', padding: 6, borderRadius: 6, color: 'var(--ink-2)' }}>
              <Icon name="chevronLeft" size={16}/>
            </button>
            <span style={{ fontWeight: 600, fontSize: 13.5 }}>{monthName}</span>
            <button onClick={() => setView(v => new Date(v.getFullYear(), v.getMonth()+1, 1))}
              style={{ border: 0, background: 'transparent', cursor: 'pointer', padding: 6, borderRadius: 6, color: 'var(--ink-2)' }}>
              <Icon name="chevronRight" size={16}/>
            </button>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 2, marginBottom: 4 }}>
            {['M','T','W','T','F','S','S'].map((d,i) => (
              <div key={i} style={{ textAlign: 'center', fontSize: 10.5, fontWeight: 600, color: 'var(--ink-4)', letterSpacing: '0.05em' }}>{d}</div>
            ))}
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 2 }}>
            {cells.map((c, i) => c ? (
              <button key={i}
                onClick={() => { onChange?.(c); setOpen(false); }}
                style={{
                  height: 34, border: 0, borderRadius: 6,
                  background: isSame(c, selected) ? 'var(--ink)' : (isSame(c, today) ? 'var(--bg-muted)' : 'transparent'),
                  color: isSame(c, selected) ? 'var(--bg)' : 'var(--ink)',
                  fontFamily: 'inherit', fontSize: 12.5, fontWeight: isSame(c, today) ? 600 : 500,
                  cursor: 'pointer', transition: 'background 120ms',
                }}>
                {c.getDate()}
              </button>
            ) : <div key={i}/>)}
          </div>
        </div>
      </Popover>
    </>
  );
};

// --- TIME PICKER ---
const TimePicker = ({ value = '09:00', onChange, step = 30 }) => {
  const anchor = React.useRef(null);
  const [open, setOpen] = React.useState(false);
  const times = [];
  for (let h = 0; h < 24; h++) for (let m = 0; m < 60; m += step)
    times.push(`${String(h).padStart(2,'0')}:${String(m).padStart(2,'0')}`);
  const display = v => {
    const [h, m] = v.split(':').map(Number);
    const ap = h >= 12 ? 'PM' : 'AM';
    const h12 = ((h + 11) % 12) + 1;
    return `${h12}:${String(m).padStart(2,'0')} ${ap}`;
  };
  return <>
    <button ref={anchor} onClick={() => setOpen(o => !o)} style={{
      display: 'flex', alignItems: 'center', gap: 10,
      border: '1px solid var(--line-2)', background: 'var(--bg-raised)',
      borderRadius: 8, padding: '0 12px', height: 38,
      fontFamily: 'inherit', fontSize: 14, color: 'var(--ink)',
      cursor: 'pointer', width: '100%', textAlign: 'left',
    }}>
      <Icon name="clock" size={16} style={{ color: 'var(--ink-3)' }}/>
      <span style={{ flex: 1 }}>{display(value)}</span>
    </button>
    <Popover open={open} anchor={anchor} onClose={() => setOpen(false)}>
      <div style={{ maxHeight: 260, overflow: 'auto', padding: 4, width: 160 }}>
        {times.map(t => (
          <button key={t} onClick={() => { onChange?.(t); setOpen(false); }}
            style={{
              display: 'block', width: '100%', textAlign: 'left',
              padding: '7px 10px', border: 0, borderRadius: 6,
              background: t === value ? 'var(--bg-muted)' : 'transparent',
              color: 'var(--ink)', fontFamily: 'var(--font-mono)', fontSize: 12.5, cursor: 'pointer',
            }}>{display(t)}</button>
        ))}
      </div>
    </Popover>
  </>;
};

// --- FILE UPLOAD ---
const FileUpload = ({ onFile, preview, height = 180, label = 'Drop image or click to upload', accept = 'image/*' }) => {
  const [drag, setDrag] = React.useState(false);
  const [img, setImg] = React.useState(preview);
  const input = React.useRef();
  const handle = f => {
    if (!f) return;
    const url = URL.createObjectURL(f);
    setImg(url);
    onFile?.(f);
  };
  return (
    <div
      onDragOver={e => { e.preventDefault(); setDrag(true); }}
      onDragLeave={() => setDrag(false)}
      onDrop={e => { e.preventDefault(); setDrag(false); handle(e.dataTransfer.files[0]); }}
      onClick={() => input.current?.click()}
      style={{
        height, borderRadius: 12,
        border: `2px dashed ${drag ? 'var(--accent)' : 'var(--line-2)'}`,
        background: drag ? 'var(--accent-soft)' : 'var(--bg-sunken)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        flexDirection: 'column', gap: 6,
        cursor: 'pointer', position: 'relative', overflow: 'hidden',
        transition: 'all 160ms',
      }}>
      {img ? (
        <>
          <img src={img} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }}/>
          <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(0,0,0,0.6), transparent 50%)' }}/>
          <div style={{ position: 'absolute', bottom: 10, left: 12, color: '#fff', fontSize: 12, fontWeight: 500 }}>
            Click or drop to replace
          </div>
        </>
      ) : (
        <>
          <div style={{
            width: 40, height: 40, borderRadius: 10,
            background: 'var(--bg-raised)', border: '1px solid var(--line-2)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: 'var(--ink-2)',
          }}><Icon name="upload" size={18}/></div>
          <div style={{ fontSize: 13, fontWeight: 550, color: 'var(--ink-2)' }}>{label}</div>
          <div style={{ fontSize: 11.5, color: 'var(--ink-4)' }}>PNG, JPG up to 5MB · 1200×600 recommended</div>
        </>
      )}
      <input ref={input} type="file" accept={accept} onChange={e => handle(e.target.files[0])} style={{ display: 'none' }}/>
    </div>
  );
};

// --- COMBOBOX (autocomplete) ---
const Combobox = ({ value, onChange, options, placeholder = 'Search...', icon = 'search' }) => {
  const [query, setQuery] = React.useState('');
  const [open, setOpen] = React.useState(false);
  const anchor = React.useRef(null);
  const filtered = options.filter(o => o.label.toLowerCase().includes(query.toLowerCase()));
  const selected = options.find(o => o.value === value);
  return <>
    <div ref={anchor} style={{
      display: 'flex', alignItems: 'center', gap: 8,
      border: '1px solid var(--line-2)', background: 'var(--bg-raised)',
      borderRadius: 8, padding: '0 12px', height: 38,
    }}>
      <Icon name={icon} size={15} style={{ color: 'var(--ink-3)' }}/>
      <input
        value={open ? query : (selected?.label || '')}
        onFocus={() => setOpen(true)}
        onChange={e => { setQuery(e.target.value); setOpen(true); }}
        placeholder={placeholder}
        style={{ flex: 1, border: 0, outline: 0, background: 'transparent', fontSize: 14, fontFamily: 'inherit', color: 'var(--ink)' }}
      />
    </div>
    <Popover open={open && filtered.length > 0} anchor={anchor} onClose={() => setOpen(false)}>
      <div style={{ maxHeight: 240, overflow: 'auto', padding: 4, width: anchor.current?.offsetWidth || 240 }}>
        {filtered.map(o => (
          <button key={o.value}
            onClick={() => { onChange?.(o.value); setOpen(false); setQuery(''); }}
            style={{
              display: 'flex', alignItems: 'center', gap: 10, width: '100%',
              padding: '8px 10px', border: 0, borderRadius: 6,
              background: o.value === value ? 'var(--bg-muted)' : 'transparent',
              fontFamily: 'inherit', fontSize: 13, textAlign: 'left', cursor: 'pointer',
              color: 'var(--ink)',
            }}
            onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-muted)'}
            onMouseLeave={e => e.currentTarget.style.background = o.value === value ? 'var(--bg-muted)' : 'transparent'}
          >
            {o.icon && <Icon name={o.icon} size={14} style={{ color: 'var(--ink-3)' }}/>}
            <span style={{ flex: 1 }}>{o.label}</span>
            {o.hint && <span style={{ fontSize: 11, color: 'var(--ink-4)' }}>{o.hint}</span>}
          </button>
        ))}
      </div>
    </Popover>
  </>;
};

// --- RICH TEXT (toolbar mock, real contenteditable) ---
const RichText = ({ placeholder = 'Tell attendees what to expect...', minHeight = 200, defaultValue = '' }) => {
  const ref = React.useRef(null);
  const exec = cmd => { document.execCommand(cmd); ref.current?.focus(); };
  const tools = [
    { cmd: 'bold', icon: 'bold', label: 'Bold', kbd: '⌘B' },
    { cmd: 'italic', icon: 'italic', label: 'Italic', kbd: '⌘I' },
    { cmd: 'underline', icon: 'underline', label: 'Underline' },
    '|',
    { cmd: 'insertUnorderedList', icon: 'listUl', label: 'Bullet list' },
    { cmd: 'insertOrderedList', icon: 'listOl', label: 'Numbered list' },
    '|',
    { cmd: 'createLink', icon: 'link', label: 'Link' },
  ];
  return (
    <div style={{ border: '1px solid var(--line-2)', borderRadius: 10, background: 'var(--bg-raised)', overflow: 'hidden' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 2, padding: 6, borderBottom: '1px solid var(--line)', background: 'var(--bg-sunken)' }}>
        {tools.map((t, i) => t === '|' ? (
          <div key={i} style={{ width: 1, height: 16, background: 'var(--line-2)', margin: '0 4px' }}/>
        ) : (
          <Tooltip key={i} label={`${t.label}${t.kbd ? ` · ${t.kbd}` : ''}`}>
            <button
              type="button"
              onMouseDown={e => e.preventDefault()}
              onClick={() => exec(t.cmd)}
              style={{
                width: 28, height: 28, border: 0, borderRadius: 6, cursor: 'pointer',
                background: 'transparent', color: 'var(--ink-2)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}
              onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-muted)'}
              onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
            ><Icon name={t.icon} size={14}/></button>
          </Tooltip>
        ))}
      </div>
      <div
        ref={ref}
        contentEditable
        suppressContentEditableWarning
        dangerouslySetInnerHTML={{ __html: defaultValue }}
        data-placeholder={placeholder}
        style={{
          minHeight, padding: '14px 16px', outline: 0,
          fontSize: 14, lineHeight: 1.6, color: 'var(--ink)',
        }}
      />
      <style>{`[contenteditable][data-placeholder]:empty:before { content: attr(data-placeholder); color: var(--ink-4); }`}</style>
    </div>
  );
};

// --- SLIDER ---
const Slider = ({ value, onChange, min = 0, max = 100, step = 1, format = v => v, style = {} }) => {
  const pct = ((value - min) / (max - min)) * 100;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 12, ...style }}>
      <div style={{ flex: 1, position: 'relative', height: 20 }}>
        <div style={{ position: 'absolute', top: 9, left: 0, right: 0, height: 4, borderRadius: 99, background: 'var(--bg-muted)' }}/>
        <div style={{ position: 'absolute', top: 9, left: 0, width: `${pct}%`, height: 4, borderRadius: 99, background: 'var(--accent)' }}/>
        <input type="range" min={min} max={max} step={step} value={value}
          onChange={e => onChange?.(Number(e.target.value))}
          style={{
            position: 'absolute', inset: 0, width: '100%', height: 20,
            appearance: 'none', background: 'transparent', margin: 0, cursor: 'pointer',
          }}/>
        <style>{`
          input[type="range"]::-webkit-slider-thumb { appearance: none; width: 18px; height: 18px; border-radius: 50%; background: #fff; border: 2px solid var(--accent); box-shadow: var(--shadow-sm); cursor: grab; }
          input[type="range"]::-webkit-slider-thumb:active { cursor: grabbing; transform: scale(1.12); }
        `}</style>
      </div>
      <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12.5, fontWeight: 600, minWidth: 40, textAlign: 'right', color: 'var(--ink-2)' }}>
        {format(value)}
      </div>
    </div>
  );
};

// --- COLOR INPUT ---
const ColorInput = ({ value, onChange, swatches }) => {
  const defaults = swatches || ['#D97757', '#E8B25E', '#5A8C76', '#4A6FB0', '#8B5CF6', '#EC4899', '#F59E0B', '#18181B'];
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
      {defaults.map(c => (
        <button key={c} onClick={() => onChange?.(c)}
          style={{
            width: 26, height: 26, borderRadius: 8, border: value === c ? '2px solid var(--ink)' : '2px solid transparent',
            background: c, cursor: 'pointer', padding: 0,
            boxShadow: 'inset 0 0 0 1px rgba(0,0,0,0.08)',
          }}/>
      ))}
      <label style={{
        width: 26, height: 26, borderRadius: 8, cursor: 'pointer',
        border: '1px dashed var(--line-2)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: 'var(--ink-3)',
      }}>
        <Icon name="plus" size={14}/>
        <input type="color" value={value} onChange={e => onChange?.(e.target.value)} style={{ display: 'none' }}/>
      </label>
    </div>
  );
};

// --- SEARCH INPUT (with clear + kbd hint) ---
const SearchInput = ({ value, onChange, placeholder = 'Search...', kbd = '⌘K', style = {}, ...rest }) => (
  <div style={{
    display: 'flex', alignItems: 'center', gap: 8,
    border: '1px solid var(--line-2)', background: 'var(--bg-raised)',
    borderRadius: 8, padding: '0 10px 0 12px', height: 36, ...style,
  }}>
    <Icon name="search" size={15} style={{ color: 'var(--ink-3)' }}/>
    <input value={value} onChange={e => onChange?.(e.target.value)} placeholder={placeholder}
      style={{ flex: 1, border: 0, outline: 0, background: 'transparent', fontSize: 13.5, fontFamily: 'inherit', color: 'var(--ink)', minWidth: 0 }}
      {...rest}/>
    {value ? (
      <button onClick={() => onChange?.('')} style={{ border: 0, background: 'transparent', color: 'var(--ink-3)', cursor: 'pointer', padding: 4 }}>
        <Icon name="x" size={13}/>
      </button>
    ) : kbd && <Kbd>{kbd}</Kbd>}
  </div>
);

Object.assign(window, { DatePicker, TimePicker, FileUpload, Combobox, RichText, Slider, ColorInput, SearchInput });
