// MultiSelect dropdown — used for branches, categories, products
const MultiSelect = ({ label, options, selected, onChange, placeholder = "All", disabled = false }) => {
  const [open, setOpen] = React.useState(false);
  const [search, setSearch] = React.useState('');
  const ref = React.useRef(null);

  React.useEffect(() => {
    const handler = (e) => {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, []);

  const toggle = (opt) => {
    if (selected.includes(opt)) onChange(selected.filter((x) => x !== opt));else
    onChange([...selected, opt]);
  };

  const filtered = options.filter((o) => o.toLowerCase().includes(search.toLowerCase()));
  const allSelected = selected.length === options.length;
  const noneSelected = selected.length === 0;

  let summary;
  if (noneSelected) summary = placeholder;else
  if (allSelected) summary = `All ${label.toLowerCase()}`;else
  if (selected.length === 1) summary = selected[0];else
  summary = `${selected.length} selected`;

  return (
    <div ref={ref} className="relative">
      <label className="block text-[11px] font-medium text-slate-500 uppercase tracking-wide mb-1">{label}</label>
      <button
        type="button"
        disabled={disabled}
        onClick={() => setOpen((o) => !o)}
        className={`w-full min-w-[140px] flex items-center justify-between gap-2 px-3 py-2 text-sm bg-white border border-slate-200 rounded-md hover:border-slate-300 focus:outline-none focus:ring-2 focus:ring-red-500/20 focus:border-red-500 transition ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}>
        
        <span className={`truncate ${noneSelected ? 'text-slate-400' : 'text-slate-900'}`}>{summary}</span>
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none" className={`text-slate-400 transition ${open ? 'rotate-180' : ''}`}>
          <path d="M3 5l4 4 4-4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </button>
      {open &&
      <div className="absolute z-30 mt-1 w-full min-w-[220px] bg-white border border-slate-200 rounded-lg shadow-lg overflow-hidden">
          {options.length > 6 &&
        <div className="p-2 border-b border-slate-100">
              <input
            type="text"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder={`Search ${label.toLowerCase()}…`}
            className="w-full px-2.5 py-1.5 text-sm border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500/20 focus:border-red-500" />
          
            </div>
        }
          <div className="flex items-center justify-between px-3 py-1.5 text-xs text-slate-500 border-b border-slate-100">
            <button onClick={() => onChange([...options])} className="hover:text-red-600 font-medium">Select all</button>
            <button onClick={() => onChange([])} className="hover:text-red-600 font-medium">Clear</button>
          </div>
          <div className="max-h-56 overflow-auto py-1">
            {filtered.length === 0 &&
          <div className="px-3 py-4 text-xs text-slate-400 text-center">No matches</div>
          }
            {filtered.map((opt) =>
          <label key={opt} className="flex items-center gap-2 px-3 py-1.5 text-sm hover:bg-slate-50 cursor-pointer">
                <input
              type="checkbox"
              checked={selected.includes(opt)}
              onChange={() => toggle(opt)}
              className="rounded border-slate-300 text-red-600 focus:ring-red-500/30" />
            
                <span className="text-slate-700 truncate">{opt}</span>
              </label>
          )}
          </div>
        </div>
      }
    </div>);

};

// DatePopover — custom calendar so we can enforce strict "commit only when a
// real date is clicked." Native <input type="date"> fires `change` on month/
// year nudges and wheel-spins, which the rep complained about. Here, month/
// year navigation only mutates the popover's internal `view` state; the only
// path that calls onChange is the day-cell click.
const DatePopover = ({ value, onChange, ariaLabel }) => {
  const [open, setOpen] = React.useState(false);
  const [view, setView] = React.useState(() => {
    const d = value ? new Date(value) : new Date();
    return { y: d.getFullYear(), m: d.getMonth() };
  });
  const ref = React.useRef(null);

  React.useEffect(() => {
    if (!open) return;
    const onDocDown = (e) => {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    };
    const onEsc = (e) => { if (e.key === 'Escape') setOpen(false); };
    document.addEventListener('mousedown', onDocDown);
    document.addEventListener('keydown', onEsc);
    return () => {
      document.removeEventListener('mousedown', onDocDown);
      document.removeEventListener('keydown', onEsc);
    };
  }, [open]);

  const openPopover = () => {
    // Reset the visible month to whatever the committed value points at, so
    // re-opening after browsing months doesn't strand the user on a stale view.
    const d = value ? new Date(value) : new Date();
    setView({ y: d.getFullYear(), m: d.getMonth() });
    setOpen(true);
  };

  const pad = (n) => String(n).padStart(2, '0');
  const fmtIso = (y, m, d) => `${y}-${pad(m + 1)}-${pad(d)}`;
  const display = value
    ? new Date(value).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' })
    : 'Pick date';

  const firstDow = new Date(view.y, view.m, 1).getDay();
  const daysInMonth = new Date(view.y, view.m + 1, 0).getDate();
  const cells = [];
  for (let i = 0; i < firstDow; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(d);
  while (cells.length % 7 !== 0) cells.push(null);

  const prev = () => setView(v => v.m === 0 ? { y: v.y - 1, m: 11 } : { y: v.y, m: v.m - 1 });
  const next = () => setView(v => v.m === 11 ? { y: v.y + 1, m: 0 } : { y: v.y, m: v.m + 1 });

  // The ONLY path that commits upward.
  const selectDay = (d) => {
    onChange(fmtIso(view.y, view.m, d));
    setOpen(false);
  };

  const baseYear = new Date().getFullYear();
  const yearOptions = [];
  for (let y = baseYear - 10; y <= baseYear + 5; y++) yearOptions.push(y);
  if (!yearOptions.includes(view.y)) {
    yearOptions.push(view.y);
    yearOptions.sort((a, b) => a - b);
  }

  const monthNames = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
  const dowNames = ['S','M','T','W','T','F','S'];

  const selectedDay = value && (() => {
    const d = new Date(value);
    return (d.getFullYear() === view.y && d.getMonth() === view.m) ? d.getDate() : null;
  })();

  return (
    <div ref={ref} className="relative shrink-0">
      <button
        type="button"
        aria-label={ariaLabel}
        onClick={() => open ? setOpen(false) : openPopover()}
        className="text-left text-sm text-slate-900 bg-transparent border-0 focus:outline-none whitespace-nowrap cursor-pointer hover:text-red-600 transition"
      >
        {display}
      </button>
      {open && (
        <div className="absolute z-30 mt-2 left-0 bg-white border border-slate-200 rounded-lg shadow-lg p-3 w-[260px]">
          <div className="flex items-center justify-between gap-2 mb-2">
            <button type="button" onClick={prev}
              className="p-1 rounded hover:bg-slate-100 text-slate-500"
              aria-label="Previous month">
              <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
                <path d="M9 3L5 7l4 4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </button>
            <div className="flex items-center gap-1">
              <select
                value={view.m}
                onChange={(e) => setView(v => ({ ...v, m: Number(e.target.value) }))}
                className="text-sm bg-transparent border-0 focus:outline-none font-medium text-slate-700 cursor-pointer"
              >
                {monthNames.map((mn, i) => <option key={mn} value={i}>{mn}</option>)}
              </select>
              <select
                value={view.y}
                onChange={(e) => setView(v => ({ ...v, y: Number(e.target.value) }))}
                className="text-sm bg-transparent border-0 focus:outline-none font-medium text-slate-700 cursor-pointer"
              >
                {yearOptions.map(y => <option key={y} value={y}>{y}</option>)}
              </select>
            </div>
            <button type="button" onClick={next}
              className="p-1 rounded hover:bg-slate-100 text-slate-500"
              aria-label="Next month">
              <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
                <path d="M5 3l4 4-4 4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </button>
          </div>
          <div className="grid grid-cols-7 gap-0.5 mb-1">
            {dowNames.map((n, i) => (
              <div key={i} className="text-[10px] text-slate-400 font-medium text-center py-1">{n}</div>
            ))}
          </div>
          <div className="grid grid-cols-7 gap-0.5">
            {cells.map((d, i) => {
              if (d == null) return <div key={i} />;
              const isSelected = d === selectedDay;
              return (
                <button
                  key={i}
                  type="button"
                  onClick={() => selectDay(d)}
                  className={`text-xs py-1.5 rounded text-center tabular-nums transition ${
                    isSelected
                      ? 'bg-red-600 text-white font-semibold'
                      : 'text-slate-700 hover:bg-slate-100'
                  }`}
                >
                  {d}
                </button>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
};

// Date range — two custom popovers, one per bound. The popover commits only
// when a day cell is clicked; outside-click / Esc / month-year nav never fire.
const DateRange = ({ start, end, onChange }) => {
  return (
    <div>
      <label className="block text-[11px] font-medium text-slate-500 uppercase tracking-wide mb-1">Date Range</label>
      <div className="inline-flex w-fit items-center gap-1.5 bg-white border border-slate-200 rounded-md px-3 py-2 hover:border-slate-300 focus-within:ring-2 focus-within:ring-red-500/20 focus-within:border-red-500 transition">
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none" className="text-slate-400 shrink-0" aria-hidden="true">
          <rect x="1.5" y="2.5" width="11" height="10" rx="1.5" stroke="currentColor" strokeWidth="1.2"/>
          <path d="M1.5 5.5h11" stroke="currentColor" strokeWidth="1.2"/>
          <path d="M4 1.5v2M10 1.5v2" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/>
        </svg>
        <DatePopover
          value={start}
          ariaLabel="Start date"
          onChange={(v) => onChange({ start: v, end })}
        />
        <span className="text-slate-400 text-xs shrink-0">→</span>
        <DatePopover
          value={end}
          ariaLabel="End date"
          onChange={(v) => onChange({ start, end: v })}
        />
      </div>
    </div>);

};

// Series toggles — checkboxes
const SeriesToggles = ({ series, onChange }) => {
  const items = [
  { key: 'forecast', label: 'Forecast', color: '#3b82f6' },
  { key: 'actual', label: 'Actual Sales', color: '#16a34a' },
  { key: 'inventory', label: 'Inventory', color: '#f59e0b' },
  { key: 'requisitions', label: 'Requisitions', color: '#7c3aed' }];

  return (
    <div>
      <label className="block text-[11px] font-medium text-slate-500 uppercase tracking-wide mb-1">Series</label>
      <div className="grid grid-cols-2 gap-1 bg-white border border-slate-200 rounded-md p-1">
        {items.map((it) =>
        <button
          key={it.key}
          onClick={() => onChange({ ...series, [it.key]: !series[it.key] })}
          className={`inline-flex items-center justify-start gap-1.5 px-2 py-1 rounded text-xs font-medium transition ${
          series[it.key] ?
          'bg-slate-100 text-slate-900' :
          'text-slate-400 hover:bg-slate-50'}`
          }>

            <span
            className={`inline-block w-2.5 h-2.5 rounded-sm shrink-0 transition ${series[it.key] ? '' : 'opacity-30'}`}
            style={{ background: it.color }} />

            <span className="truncate">{it.label}</span>
          </button>
        )}
      </div>
    </div>);

};

// Confidence-band controls. Schema-driven: receives the list of upper/lower
// levels actually present in the `results` table (discovered server-side via
// INFORMATION_SCHEMA) and renders one checkbox per level on each side.
//
// `selection` is an array of keys like ["upper_80", "lower_60"]. The chart
// pairs same-level upper+lower into a single band with one color; otherwise
// each selection gets its own color (see chart.jsx).
const ConfidenceControls = ({ bandLevels, selection, onChange, disabled }) => {
  const upperLevels = (bandLevels && bandLevels.upper) || [];
  const lowerLevels = (bandLevels && bandLevels.lower) || [];
  const empty = upperLevels.length === 0 && lowerLevels.length === 0;
  const sel = new Set(selection || []);

  const toggle = (key, on) => {
    const next = new Set(sel);
    if (on) next.add(key); else next.delete(key);
    onChange([...next]);
  };

  return (
    <div>
      <label className="block text-[11px] font-medium text-slate-500 uppercase tracking-wide mb-1">
        Confidence Band
      </label>
      <div className={`bg-white border border-slate-200 rounded-md px-3 py-1.5 ${disabled ? 'opacity-50' : ''}`}>
        {empty ? (
          <span className="text-xs text-slate-400">No band columns in results table</span>
        ) : (
          <div className="flex flex-wrap gap-x-4 gap-y-1 text-sm">
            {upperLevels.length > 0 && (
              <div className="inline-flex items-center gap-2">
                <span className="text-[10px] font-semibold uppercase tracking-wide text-slate-400">Upper</span>
                {upperLevels.map((lvl) => {
                  const key = `upper_${lvl}`;
                  return (
                    <label key={key} className="inline-flex items-center gap-1 text-slate-700 cursor-pointer">
                      <input
                        type="checkbox"
                        disabled={disabled}
                        checked={sel.has(key)}
                        onChange={(e) => toggle(key, e.target.checked)}
                        className="rounded border-slate-300 text-red-600 focus:ring-red-500/30" />
                      <span className="tabular-nums">{lvl}%</span>
                    </label>);

                })}
              </div>)}

            {lowerLevels.length > 0 && (
              <div className="inline-flex items-center gap-2">
                <span className="text-[10px] font-semibold uppercase tracking-wide text-slate-400">Lower</span>
                {lowerLevels.map((lvl) => {
                  const key = `lower_${lvl}`;
                  return (
                    <label key={key} className="inline-flex items-center gap-1 text-slate-700 cursor-pointer">
                      <input
                        type="checkbox"
                        disabled={disabled}
                        checked={sel.has(key)}
                        onChange={(e) => toggle(key, e.target.checked)}
                        className="rounded border-slate-300 text-red-600 focus:ring-red-500/30" />
                      <span className="tabular-nums">{lvl}%</span>
                    </label>);

                })}
              </div>)}

          </div>)}

      </div>
    </div>);

};

window.MultiSelect = MultiSelect;
window.DateRange = DateRange;
window.SeriesToggles = SeriesToggles;
window.ConfidenceControls = ConfidenceControls;