// Local-state input that doesn't lose focus even if parent rerenders mid-typing.
// Syncs to parent on every change, but reads its own value from local state.
function LocalInput({ value, onChange, style, ...rest }) {
  const [v, setV] = React.useState(value || '');
  const lastExternal = React.useRef(value);
  React.useEffect(() => {
    // Only sync from outside if external value actually changed (e.g. switching offer)
    if (value !== lastExternal.current) {
      setV(value || '');
      lastExternal.current = value;
    }
  }, [value]);
  return (
    <input
      value={v}
      onChange={e => {
        const nv = e.target.value;
        setV(nv);
        lastExternal.current = nv;
        onChange(nv);
      }}
      style={style}
      {...rest}
    />
  );
}
function LocalTextarea({ value, onChange, style, ...rest }) {
  const [v, setV] = React.useState(value || '');
  const lastExternal = React.useRef(value);
  React.useEffect(() => {
    if (value !== lastExternal.current) {
      setV(value || '');
      lastExternal.current = value;
    }
  }, [value]);
  return (
    <textarea
      value={v}
      onChange={e => {
        const nv = e.target.value;
        setV(nv);
        lastExternal.current = nv;
        onChange(nv);
      }}
      style={style}
      {...rest}
    />
  );
}
// Sifferfält för pris, antal, rabatt, avtalstid och restvärde.
//
// Tidigare låg talfälten helt i föräldrarnas tillstånd och tolkades om vid varje
// tangenttryck. Skrev man "0," blev strängen "0." → talet 0 → fältet ritades om
// som "0" och kommatecknet försvann i samma sekund: 0,5 gick helt enkelt inte
// att skriva. Redigerade man mitt i ett tal hoppade markören till slutet.
//
// Nu håller fältet sin egen råtext medan man skriver och rapporterar bara det
// tolkade talet uppåt. Utanför fokus visas det normaliserade värdet.
function LocalNumberInput({ value, onChange, min, max, style, ...rest }) {
  const visa = (v) => (v == null || v === '' ? '' : String(v).replace('.', ','));
  const [text, setText] = React.useState(visa(value));
  const [fokus, setFokus] = React.useState(false);
  const senast = React.useRef(value);

  React.useEffect(() => {
    // Ändras värdet utifrån (byte av offert, ångra) ska fältet följa med — men
    // inte medan man står och skriver i det.
    if (!fokus && value !== senast.current) {
      setText(visa(value));
      senast.current = value;
    }
  }, [value, fokus]);

  const tolka = (s) => {
    const rensad = String(s).replace(/\s/g, '').replace(',', '.');
    if (rensad === '' || rensad === '-') return null;
    const n = Number(rensad);
    if (!Number.isFinite(n)) return null;
    if (min != null && n < min) return min;
    if (max != null && n > max) return max;
    return n;
  };

  const utanforIntervall = (() => {
    const n = tolka(text);
    if (n == null) return false;
    const raa = Number(String(text).replace(/\s/g, '').replace(',', '.'));
    return Number.isFinite(raa) && raa !== n;
  })();

  return (
    <input
      value={text}
      inputMode="decimal"
      onFocus={() => setFokus(true)}
      onBlur={() => {
        setFokus(false);
        const n = tolka(text);
        // Rör INTE föräldern om värdet redan är rapporterat (vilket det är —
        // onChange nedan skickar det vid varje tangenttryck). En uppdatering här
        // ritar om hela sidan mitt i ett musklick: webbläsaren hinner då byta ut
        // knappen man klickar på mellan nedtryck och släpp, och klicket
        // försvinner. Det märktes som att första klicket på "Förhandsgranska"
        // efter att man skrivit ett pris inte gjorde någonting.
        const normaliserad = visa(n);
        if (normaliserad !== text) setText(normaliserad);
        if (n !== senast.current) {
          senast.current = n;
          onChange(n);
        }
      }}
      onChange={e => {
        const s = e.target.value;
        // Släpp bara igenom siffror, komma, punkt, minus och mellanslag — så en
        // felaktig bokstav aldrig hamnar i fältet och tolkas som NaN.
        if (!/^-?[\d\s.,]*$/.test(s)) return;
        setText(s);
        const n = tolka(s);
        senast.current = n;
        onChange(n);
      }}
      style={utanforIntervall ? { ...style, borderColor: 'var(--ulab-coral)' } : style}
      {...rest}
    />
  );
}

window.LocalInput = LocalInput;
window.LocalTextarea = LocalTextarea;
window.LocalNumberInput = LocalNumberInput;
