// DSTextInput.jsx — Meridian text inputs
//
//   DSTextInput  — labelled input with rest / focused / filled / error /
//                  disabled states, optional multiline.
//   DSSearchField — sibling variant with leading magnifying-glass icon,
//                   clear-text button, optional inline filter-chip slot.
//
// MInput is kept as a back-compat alias for the existing onboarding
// screen import.

// ── DSTextInput ──────────────────────────────────────────────────
function DSTextInput({
  value,
  onChange,
  onSubmit,
  label,
  placeholder = '',
  helperText,
  errorText,
  isMultiline = false,
  disabled = false,
  autoFocus = false,
  // legacy MInput compatibility — accepts an onChange(event) like a raw input
  legacyOnChange,
  style,
}) {
  const [isFocused, setFocused] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (autoFocus && ref.current) ref.current.focus();
  }, [autoFocus]);

  const hasError = !!errorText;
  const isFilled = !isFocused && value && String(value).length > 0;
  const state = disabled ? 'disabled'
    : isFocused      ? 'focused'
    : hasError       ? 'error'
    : isFilled       ? 'filled'
    : 'rest';

  const borderColor = state === 'focused' ? M.axis
    : state === 'error'   ? M.crisis
    : M.rule;
  const borderWidth = state === 'focused' || state === 'error' ? 1.5 : 1;
  const background = state === 'focused' ? M.surface : M.surfaceAlt;

  const commonInputStyle = {
    width: '100%', boxSizing: 'border-box',
    border: 'none', outline: 'none', background: 'transparent',
    font: `400 15px/1.4 ${M.sans}`, color: M.ink,
    padding: 0, margin: 0, resize: isMultiline ? 'vertical' : 'none',
  };

  const handleChange = (e) => {
    // Support both modern (value-based) and legacy (event-based) onChange.
    if (legacyOnChange) legacyOnChange(e);
    if (onChange) onChange(e.target.value);
  };
  const handleKey = (e) => {
    if (!isMultiline && e.key === 'Enter' && onSubmit) {
      e.preventDefault();
      onSubmit(value || '');
    }
  };

  return (
    <div style={style}>
      {label && (
        <div style={{
          font: `500 12px/1 ${M.sans}`, color: M.inkMuted,
          letterSpacing: '0.08em', textTransform: 'uppercase',
          marginBottom: 6,
        }}>{label}</div>
      )}
      <div style={{
        padding: '12px 14px',
        background,
        border: `${borderWidth}px solid ${borderColor}`,
        borderRadius: 8,
        opacity: disabled ? 0.5 : 1,
        transition: 'border-color 120ms cubic-bezier(.2,.8,.2,1), background 120ms cubic-bezier(.2,.8,.2,1)',
      }}>
        {isMultiline
          ? <textarea
              ref={ref} rows={3}
              value={value || ''} onChange={handleChange}
              placeholder={placeholder}
              disabled={disabled}
              onFocus={() => setFocused(true)} onBlur={() => setFocused(false)}
              style={commonInputStyle} />
          : <input
              ref={ref}
              value={value || ''} onChange={handleChange} onKeyDown={handleKey}
              placeholder={placeholder}
              disabled={disabled}
              onFocus={() => setFocused(true)} onBlur={() => setFocused(false)}
              style={commonInputStyle} />}
      </div>
      {hasError ? (
        <div style={{ font: `400 12px/1.4 ${M.sans}`, color: M.crisis, marginTop: 6 }}>{errorText}</div>
      ) : helperText ? (
        <div style={{ font: `400 12px/1.4 ${M.sans}`, color: M.inkMuted, marginTop: 6 }}>{helperText}</div>
      ) : null}
    </div>
  );
}

// ── DSSearchField ────────────────────────────────────────────────
// Leading magnifying-glass + input + clear-text button.
// `filterSlot` renders to the right of the input (before the clear/icon
// region) for an inline filter chip or count badge.
function DSSearchField({
  value,
  onChange,
  onSubmit,
  placeholder = 'Search entries…',
  filterSlot,
  disabled = false,
  autoFocus = false,
  style,
}) {
  const [isFocused, setFocused] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (autoFocus && ref.current) ref.current.focus();
  }, [autoFocus]);

  const hasText = !!(value && String(value).length > 0);
  const borderColor = isFocused ? M.axis : M.rule;
  const borderWidth = isFocused ? 1.5 : 1;
  const background = isFocused ? M.surface : M.surfaceAlt;

  const clear = () => {
    onChange?.('');
    ref.current?.focus();
  };

  return (
    <div role="search" style={{
      display: 'flex', alignItems: 'center', gap: 8,
      padding: '8px 10px 8px 12px',
      background,
      border: `${borderWidth}px solid ${borderColor}`,
      borderRadius: 8,
      opacity: disabled ? 0.5 : 1,
      transition: 'border-color 120ms cubic-bezier(.2,.8,.2,1), background 120ms cubic-bezier(.2,.8,.2,1)',
      ...style,
    }}>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true" style={{ flexShrink: 0, color: isFocused ? M.axis : M.inkMuted }}>
        <circle cx="11" cy="11" r="7" stroke="currentColor" strokeWidth="2" />
        <path d="M21 21l-4.5-4.5" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
      </svg>

      <input
        ref={ref}
        value={value || ''}
        onChange={(e) => onChange?.(e.target.value)}
        onKeyDown={(e) => {
          if (e.key === 'Escape' && hasText) { e.preventDefault(); clear(); }
          if (e.key === 'Enter' && onSubmit) { e.preventDefault(); onSubmit(value || ''); }
        }}
        onFocus={() => setFocused(true)} onBlur={() => setFocused(false)}
        placeholder={placeholder}
        disabled={disabled}
        style={{
          flex: 1, minWidth: 0,
          border: 'none', outline: 'none', background: 'transparent',
          font: `400 14px/1 ${M.sans}`, color: M.ink,
          padding: '4px 2px',
        }}
      />

      {filterSlot && (
        <div style={{ display: 'flex', alignItems: 'center', flexShrink: 0 }}>
          {filterSlot}
        </div>
      )}

      {hasText && !disabled && (
        <button
          type="button"
          onClick={clear}
          aria-label="Clear search"
          style={{
            width: 22, height: 22, padding: 0, flexShrink: 0,
            borderRadius: 999,
            background: M.inkFaint, color: '#fff',
            border: 'none', cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            transition: 'background 120ms cubic-bezier(.2,.8,.2,1)',
          }}>
          <svg width="12" height="12" viewBox="0 0 24 24" fill="none">
            <path d="M6 6l12 12M6 18L18 6" stroke="#fff" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </button>
      )}
    </div>
  );
}

// Back-compat: existing onboarding screen calls MInput with the raw
// (event-based) onChange of a plain <input>. Adapt to DSTextInput's
// value-first signature via the `legacyOnChange` escape hatch.
function MInput(props) {
  return <DSTextInput
    value={props.value}
    legacyOnChange={props.onChange}
    placeholder={props.placeholder}
    autoFocus={props.autoFocus}
    onSubmit={props.onSubmit}
  />;
}

Object.assign(window, {
  DSTextInput, DSSearchField,
  MInput, // legacy alias — onboarding still uses it
});
