import React, { useState, useRef, useCallback } from 'react';
import './CodeInput.css';

function buildCells(v, length) {
  const arr = (v || '').split('').slice(0, length);
  while (arr.length < length) arr.push('');
  return arr;
}

export default function CodeInput({
  value = '',
  length = 6,
  masked = false,
  tip = '',
  hasError = false,
  onChange
}) {
  const inputsRef = useRef([]);
  const [cells, setCells] = useState(() => buildCells(value, length));
  const [focusedIndex, setFocusedIndex] = useState(-1);

  const emit = useCallback(
    (next) => {
      const code = next.join('');
      if (onChange) onChange(code);
    },
    [onChange]
  );

  const focus = (i) => {
    const el = inputsRef.current[i];
    if (el) el.focus();
  };

  const onInput = (e, i) => {
    const ch = (e.target.value || '').slice(-1);
    const next = cells.slice();
    next[i] = ch;
    e.target.value = ch;
    setCells(next);
    if (ch && i < length - 1) focus(i + 1);
    emit(next);
  };

  const onKeydown = (e, i) => {
    if (e.key === 'Backspace') {
      e.preventDefault();
      const next = cells.slice();
      if (next[i]) {
        next[i] = '';
      } else if (i > 0) {
        next[i - 1] = '';
        focus(i - 1);
      }
      setCells(next);
      emit(next);
    } else if (e.key === 'ArrowLeft' && i > 0) {
      focus(i - 1);
    } else if (e.key === 'ArrowRight' && i < length - 1) {
      focus(i + 1);
    }
  };

  const onPaste = (e) => {
    e.preventDefault();
    const text = (e.clipboardData || window.clipboardData).getData('text') || '';
    const digits = text.replace(/\D/g, '').slice(0, length).split('');
    const next = cells.slice();
    for (let k = 0; k < length; k++) next[k] = digits[k] || '';
    setCells(next);
    focus(Math.min(digits.length, length - 1));
    emit(next);
  };

  return (
    <div>
      <div className="kole-code" onPaste={onPaste}>
        {cells.map((c, i) => (
          <div
            key={i}
            className={
              'kole-code-cell' +
              (focusedIndex === i ? ' is-focus' : '') +
              (c ? ' is-filled' : '') +
              (masked ? ' is-masked' : '')
            }
          >
            <input
              ref={(el) => (inputsRef.current[i] = el)}
              className="kole-code-input"
              value={c}
              maxLength={1}
              inputMode="numeric"
              aria-label={'验证码第 ' + (i + 1) + ' 位'}
              onFocus={() => setFocusedIndex(i)}
              onInput={(e) => onInput(e, i)}
              onKeyDown={(e) => onKeydown(e, i)}
            />
          </div>
        ))}
      </div>
      <div className={'kole-code-tip' + (hasError ? ' error' : '')}>{tip}</div>
    </div>
  );
}
