import { ArrowBigUp, Delete, Space, X } from 'lucide-react';
import { forwardRef, RefObject, useState } from 'react';
import { createPortal } from 'react-dom';

const defaultLayout = {
  default: [
    '1 2 3 4 5 6 7 8 9 0 {bksp}',
    'q w e r t y u i o p',
    'a s d f g h j k l',
    '{shift} z x c v b n m /',
    '{space} {close}',
  ],
  shift: [
    '1 2 3 4 5 6 7 8 9 0 {bksp}',
    'Q W E R T Y U I O P',
    'A S D F G H J K L',
    '{shift} Z X C V B N M /',
    '{space} {close}',
  ],
};

const Keyboard = forwardRef<
  HTMLDivElement,
  {
    value: string;
    blurRef: RefObject<boolean>;
    top?: boolean;
    onInput: (value: string) => void;
    onClose: () => void;
  }
>(({ value, top, blurRef, onInput, onClose }, ref) => {
  const [shift, setShift] = useState(false);

  const layout = shift ? defaultLayout.shift : defaultLayout.default;

  const handleKeyPress = (key: string) => {
    console.log('KEY PRESSED', key);

    if (key === '{close}') {
      onClose();
      return;
    }

    blurRef.current = true;

    if (key === '{shift}') {
      setShift(!shift);
      return;
    }

    let newValue = value;

    if (key === '{bksp}') {
      newValue = value.slice(0, -1);
    } else if (key === '{space}') {
      newValue = value + ' ';
    } else if (key.length === 1) {
      newValue = value + key;
    }

    onInput(newValue);
  };

  return createPortal(
    <div
      ref={ref}
      className={`absolute ${top ? 'top-0' : 'bottom-0'} left-0 z-50 box-border w-full touch-manipulation select-none overflow-hidden bg-zinc-800 p-2 text-white`}
    >
      {layout.map((row, rowIndex) => (
        <div key={`row-${rowIndex}`} className="mb-1 flex w-full justify-center gap-1">
          {row.split(' ').map((key, keyIndex) => {
            let keyIdent = <>{key}</>;
            switch (key) {
              case '{shift}':
                keyIdent = <ArrowBigUp />;
                break;
              case '{bksp}':
                keyIdent = <Delete />;
                break;
              case '{close}':
                keyIdent = <X />;
                break;
              case '{space}':
                keyIdent = <Space />;
                break;
            }

            return (
              <button
                key={`key-${rowIndex}-${keyIndex}`}
                className={`flex justify-center rounded-md p-4 ${
                  key === '{close}' ? 'bg-zinc-700 px-12 focus:bg-zinc-600' : 'flex-1 bg-zinc-600'
                }`}
                onMouseDown={() => handleKeyPress(key)}
              >
                {keyIdent}
              </button>
            );
          })}
        </div>
      ))}
    </div>,
    document.body
  );
});

export default Keyboard;
