/* global React */

function Counter({ value, max }) {
  const len = (value || "").length;
  return <span className={"counter" + (len > max ? " over" : "")}>{len}/{max}</span>;
}

function Label({ label, required, max, value }) {
  return (
    <div className="field-label">
      <span className="lbl">{label}{required ? <span className="req">*</span> : <span className="opt"> (optional)</span>}</span>
      {max ? <Counter value={value} max={max} /> : null}
    </div>
  );
}

function TextField({ label, value, onChange, max, required, error, hint, placeholder, type = "text", inputMode }) {
  return (
    <div className="field">
      <Label label={label} required={required} max={max} value={value} />
      <input
        className={"input" + (error ? " invalid" : "")}
        type={type}
        inputMode={inputMode}
        value={value || ""}
        placeholder={placeholder}
        maxLength={max ? max + 10 : undefined}
        onChange={(e) => onChange(e.target.value)}
      />
      {error ? <div className="field-error">{error}</div> : hint ? <div className="field-hint">{hint}</div> : null}
    </div>
  );
}

function TextArea({ label, value, onChange, max, required, error, hint, placeholder, rows = 4 }) {
  return (
    <div className="field">
      <Label label={label} required={required} max={max} value={value} />
      <textarea
        className={"textarea" + (error ? " invalid" : "")}
        value={value || ""}
        rows={rows}
        placeholder={placeholder}
        onChange={(e) => onChange(e.target.value)}
      />
      {error ? <div className="field-error">{error}</div> : hint ? <div className="field-hint">{hint}</div> : null}
    </div>
  );
}

function SelectField({ label, value, onChange, options, required, error, hint, placeholder }) {
  return (
    <div className="field">
      <Label label={label} required={required} value={value} />
      <select
        className={"select" + (error ? " invalid" : "")}
        value={value || ""}
        onChange={(e) => onChange(e.target.value)}
      >
        <option value="">{placeholder || "Select…"}</option>
        {options.map((o) => <option key={o} value={o}>{o}</option>)}
      </select>
      {error ? <div className="field-error">{error}</div> : hint ? <div className="field-hint">{hint}</div> : null}
    </div>
  );
}

function RangeField({ label, value, onChange, min = 0, max = 100, step = 5, suffix = "%", valueLabel }) {
  return (
    <div className="field">
      <div className="field-label"><span className="lbl">{label}</span></div>
      <div className="slider-row">
        <input type="range" min={min} max={max} step={step}
          value={value || 0} onChange={(e) => onChange(Number(e.target.value))} />
        <span className="slider-val">{valueLabel != null ? valueLabel : `${value || 0}${suffix}`}</span>
      </div>
    </div>
  );
}

function MonthYearField({ label, value, onChange, required, error, hint, disabled }) {
  // value stored as "Mon YYYY" string; input is type=month -> convert
  const MONTHS = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
  // parse current to yyyy-mm for the input
  let inputVal = "";
  if (value) {
    const m = value.match(/(\w{3})\s+(\d{4})/);
    if (m) {
      const mi = MONTHS.indexOf(m[1]);
      if (mi >= 0) inputVal = `${m[2]}-${String(mi + 1).padStart(2, "0")}`;
    }
  }
  return (
    <div className="field">
      <Label label={label} required={required} />
      <input
        className={"input" + (error ? " invalid" : "")}
        type="month"
        value={inputVal}
        disabled={disabled}
        style={disabled ? { opacity: .5 } : undefined}
        onChange={(e) => {
          const v = e.target.value;
          if (!v) { onChange(""); return; }
          const [y, mm] = v.split("-");
          onChange(`${MONTHS[Number(mm) - 1]} ${y}`);
        }}
      />
      {error ? <div className="field-error">{error}</div> : hint ? <div className="field-hint">{hint}</div> : null}
    </div>
  );
}

Object.assign(window, { TextField, TextArea, SelectField, RangeField, MonthYearField, Counter });
