/* ConsultX — field components. Exposed on window for app.jsx. */
const Check = () => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3.4" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12" /></svg>
);
const AlertCircle = () => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10" /><line x1="12" y1="8" x2="12" y2="12" /><line x1="12" y1="16" x2="12.01" y2="16" /></svg>
);

function FieldError({ msg }) {
  if (!msg) return null;
  return (
    <div className="cx-err" role="alert"><AlertCircle /><span>{msg}</span></div>
  );
}

/* normalize option to {value, desc} */
const opt = (o) => (typeof o === 'string' ? { value: o, desc: '' } : o);

const CX_MONTHS = ['January', 'February', 'March', 'April', 'May', 'June',
  'July', 'August', 'September', 'October', 'November', 'December'];

function SubHead({ label }) {
  return (
    <div className="cx-subhead"><span>{label}</span></div>
  );
}

function YearPicker({ value, onChange }) {
  const [open, setOpen] = React.useState(false);
  const pos = React.useRef({ top: 0, left: 0, width: 0 });
  const triggerRef = React.useRef(null);
  const listRef = React.useRef(null);

  const currentYear = new Date().getFullYear();
  const years = [];
  for (let y = currentYear; y >= 1970; y--) years.push(y);

  const toggle = () => {
    if (!open && triggerRef.current) {
      const r = triggerRef.current.getBoundingClientRect();
      const listH = Math.min(220, years.length * 41 + 8);
      const below = window.innerHeight - r.bottom;
      pos.current = {
        top: below < listH + 10 && r.top > below ? r.top - listH - 5 : r.bottom + 5,
        left: r.left,
        width: r.width,
      };
    }
    setOpen(function(o) { return !o; });
  };

  React.useEffect(() => {
    if (!open) return;
    const onClickOutside = (e) => {
      const inT = triggerRef.current && triggerRef.current.contains(e.target);
      const inL = listRef.current && listRef.current.contains(e.target);
      if (!inT && !inL) setOpen(false);
    };
    document.addEventListener('click', onClickOutside, true);
    return () => document.removeEventListener('click', onClickOutside, true);
  }, [open]);

  React.useEffect(() => {
    if (open && value && listRef.current) {
      const item = listRef.current.querySelector('[data-year="' + value + '"]');
      if (item) item.scrollIntoView({ block: 'nearest' });
    }
  }, [open]);

  return (
    <div className="cx-yearpicker" ref={triggerRef}>
      <button type="button" className={'cx-year-trigger' + (open ? ' is-open' : '')} onClick={toggle}>
        {value ? <span>{value}</span> : <span className="cy-ph">Select year</span>}
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
          <polyline points="6 9 12 15 18 9"/>
        </svg>
      </button>
      {open && ReactDOM.createPortal(
        <div className="cx-year-list" ref={listRef}
          style={{ position: 'fixed', top: pos.current.top + 'px', left: pos.current.left + 'px', width: pos.current.width + 'px', zIndex: 9999 }}>
          {years.map(function(y) {
            return (
              <button type="button" key={y} data-year={String(y)}
                className={'cx-year-opt' + (String(y) === value ? ' is-sel' : '')}
                onClick={() => { onChange(String(y)); setOpen(false); }}>
                {y}
              </button>
            );
          })}
        </div>,
        document.body
      )}
    </div>
  );
}

function DayMonth({ value, onChange }) {
  const notSure = value === 'Not sure';
  const dm = value && typeof value === 'object' ? value : {};
  return (
    <div className="cx-daymonth">
      <select className="cx-select day" disabled={notSure} value={dm.day || ''}
        onChange={(e) => onChange({ ...dm, day: e.target.value })}>
        <option value="" disabled hidden>Day</option>
        {Array.from({ length: 31 }, (_, i) => String(i + 1).padStart(2, '0')).map((d) => <option key={d} value={d}>{d}</option>)}
      </select>
      <select className="cx-select month" disabled={notSure} value={dm.month || ''}
        onChange={(e) => onChange({ ...dm, month: e.target.value })}>
        <option value="" disabled hidden>Month</option>
        {CX_MONTHS.map((m) => <option key={m} value={m}>{m}</option>)}
      </select>
      <button type="button" className={`cx-chip single ${notSure ? 'is-sel' : ''}`}
        onClick={() => onChange(notSure ? '' : 'Not sure')}>
        <span className="ind"><Check /></span>Not sure
      </button>
    </div>
  );
}

function CustomSelect({ value, onChange, opts, placeholder }) {
  const [open, setOpen] = React.useState(false);
  const pos = React.useRef({ top: 0, left: 0, width: 0 });
  const triggerRef = React.useRef(null);
  const listRef = React.useRef(null);

  const toggle = () => {
    if (!open && triggerRef.current) {
      const r = triggerRef.current.getBoundingClientRect();
      const listH = Math.min(220, ((opts || []).length * 41) + 8);
      const below = window.innerHeight - r.bottom;
      pos.current = {
        top: below < listH + 10 && r.top > below ? r.top - listH - 5 : r.bottom + 5,
        left: r.left,
        width: r.width,
      };
    }
    setOpen(function(o) { return !o; });
  };

  React.useEffect(() => {
    if (!open) return;
    const onClickOutside = (e) => {
      const inT = triggerRef.current && triggerRef.current.contains(e.target);
      const inL = listRef.current && listRef.current.contains(e.target);
      if (!inT && !inL) setOpen(false);
    };
    document.addEventListener('click', onClickOutside, true);
    return () => document.removeEventListener('click', onClickOutside, true);
  }, [open]);

  React.useEffect(() => {
    if (open && value && listRef.current) {
      const item = listRef.current.querySelector('[data-val="' + value + '"]');
      if (item) item.scrollIntoView({ block: 'nearest' });
    }
  }, [open]);

  return (
    <div className="cx-yearpicker" ref={triggerRef}>
      <button type="button" className={'cx-year-trigger' + (open ? ' is-open' : '')} onClick={toggle}>
        {value ? <span>{value}</span> : <span className="cy-ph">{placeholder || 'Select…'}</span>}
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
          <polyline points="6 9 12 15 18 9"/>
        </svg>
      </button>
      {open && ReactDOM.createPortal(
        <div className="cx-year-list" ref={listRef}
          style={{ position: 'fixed', top: pos.current.top + 'px', left: pos.current.left + 'px', width: pos.current.width + 'px', zIndex: 9999 }}>
          {(opts || []).map(function(o) {
            const v = typeof o === 'string' ? o : o.value;
            return (
              <button type="button" key={v} data-val={v}
                className={'cx-year-opt' + (v === value ? ' is-sel' : '')}
                onClick={() => { onChange(v); setOpen(false); }}>
                {v}
              </button>
            );
          })}
        </div>,
        document.body
      )}
    </div>
  );
}

/* opts is always a pre-resolved plain array — never a function */
function Chips({ field, value, onChange, opts }) {
  const multi = field.type === 'multichips';
  const arr = multi ? (value || []) : value;
  const toggle = (v) => {
    if (multi) {
      const set = new Set(value || []);
      set.has(v) ? set.delete(v) : set.add(v);
      onChange([...set]);
    } else {
      onChange(value === v ? '' : v);
    }
  };
  /* key derived from option set — causes container remount (and CSS fade-in) when options change */
  const optsKey = (opts || []).map(o => typeof o === 'string' ? o : o.value).join('|');
  return (
    <div key={optsKey} className="cx-chips cx-opts-anim" role={multi ? 'group' : 'radiogroup'}>
      {(opts || []).map((o) => {
        const { value: v } = opt(o);
        const sel = multi ? arr.includes(v) : arr === v;
        return (
          <button type="button" key={v} className={`cx-chip ${multi ? 'multi' : 'single'} ${sel ? 'is-sel' : ''}`}
            role={multi ? 'checkbox' : 'radio'} aria-checked={sel} onClick={() => toggle(v)}>
            <span className="ind"><Check /></span>{v}
          </button>
        );
      })}
    </div>
  );
}

function Segmented({ value, onChange, opts }) {
  const optsKey = (opts || []).map(o => typeof o === 'string' ? o : o.value).join('|');
  return (
    <div key={optsKey} className="cx-seg cx-opts-anim" role="radiogroup">
      {(opts || []).map((o) => {
        const { value: v } = opt(o);
        const sel = value === v;
        return (
          <button type="button" key={v} role="radio" aria-checked={sel}
            className={sel ? 'is-sel' : ''} onClick={() => onChange(value === v ? '' : v)}>{v}</button>
        );
      })}
    </div>
  );
}

function Cards({ field, value, onChange, opts }) {
  return (
    <div className={`cx-cards ${field.card === 'wide' ? 'wide' : ''}`} role="radiogroup">
      {(opts || []).map((o) => {
        const { value: v, desc } = opt(o);
        const sel = value === v;
        return (
          <button type="button" key={v} role="radio" aria-checked={sel}
            className={`cx-selcard ${sel ? 'is-sel' : ''}`} onClick={() => onChange(value === v ? '' : v)}>
            <span className="t">{v}</span>
            {desc ? <span className="d">{desc}</span> : null}
            <span className="check"><Check /></span>
          </button>
        );
      })}
    </div>
  );
}

function Consent({ field, value, onChange }) {
  return (
    <button type="button" className={`cx-consent ${value ? 'is-sel' : ''}`} aria-checked={!!value} role="checkbox"
      onClick={() => onChange(!value)}>
      <span className="box"><Check /></span>
      <span className="txt">{field.text}</span>
    </button>
  );
}

/* resolvedOpts — plain array computed by App before passing down; never a function */
function Field({ field, num, value, onChange, error, fieldRef, required, resolvedOpts }) {
  let control;
  switch (field.type) {
    case 'text':
    case 'email':
      control = (
        <input className="cx-input" type={field.type === 'email' ? 'email' : 'text'} value={value || ''}
          placeholder={field.placeholder || ''} onChange={(e) => onChange(e.target.value)}
          inputMode={field.type === 'email' ? 'email' : undefined} autoComplete="off" />
      );
      break;
    case 'textarea':
      control = (
        <textarea className="cx-textarea" value={value || ''} placeholder={field.placeholder || ''}
          rows={3} onChange={(e) => onChange(e.target.value)} />
      );
      break;
    case 'select':
      control = <CustomSelect value={value} onChange={onChange} opts={resolvedOpts} placeholder={field.placeholder} />;
      break;
    case 'chips':
    case 'multichips':
      control = <Chips field={field} value={value} onChange={onChange} opts={resolvedOpts} />;
      break;
    case 'segmented':
      control = <Segmented value={value} onChange={onChange} opts={resolvedOpts} />;
      break;
    case 'cards':
      control = <Cards field={field} value={value} onChange={onChange} opts={resolvedOpts} />;
      break;
    case 'year':
      control = <YearPicker value={value} onChange={onChange} />;
      break;
    case 'daymonth':
      control = <DayMonth value={value} onChange={onChange} />;
      break;
    case 'consent':
      control = <Consent field={field} value={value} onChange={onChange} />;
      break;
    default:
      control = null;
  }

  const widthClass = field.width === 'half' ? '' : 'col-2';

  if (field.type === 'consent') {
    return (
      <div className={`cx-q col-2 ${error ? 'has-error' : ''}`} ref={fieldRef}>
        {control}
        <FieldError msg={error} />
      </div>
    );
  }

  return (
    <div className={`cx-q ${widthClass} ${error ? 'has-error' : ''}`} ref={fieldRef}>
      <label className="cx-label">
        <span><span className="num">{num}.</span>&nbsp;{field.label}{required ? <span className="cx-req" title="Required"> *</span> : null}</span>
        {!required ? <span className="cx-opt">Optional</span> : null}
      </label>
      {field.help ? <p className="cx-help">{field.help}</p> : null}
      <div className="cx-controlwrap">{control}</div>
      <FieldError msg={error} />
    </div>
  );
}

Object.assign(window, { Field, SubHead, Check, AlertCircle });
