import React, { useRef, useState } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import {
  ChecklistEditor,
  ChecklistItemEditor,
  SpinnerEditor,
  SpinnerItem,
  SpinnerItemEditor
} from './PktEl';
import { ArrowDropUp, ArrowDropDown } from '@mui/icons-material';
import {
  FormEditorAction,
  toggleEditing,
  setSpinnerOptionName,
  setSpinnerOptionValue,
  setSpinnerOptionRequired,
  addSpinnerOption,
  deleteSpinnerOption,
  toggleProperty
} from './types';
import AddIcon from '@mui/icons-material/Add';
import DeleteIcon from '@mui/icons-material/Delete';

type SpinnerElProps = ReturnType<typeof mapDispatchToProps> & {
  setElementState: (el: SpinnerEditor | ChecklistEditor) => void;
  el: SpinnerEditor | ChecklistEditor;
  path: Array<string | number>;
  children: React.ReactNode;
  previewElement?: React.ReactNode; // The 'select' can be replaced with another element if provided
};

const SpinnerEl: React.FC<SpinnerElProps> = (props) => {
  const {
    el,
    children,
    path,
    setSpinnerOptionName,
    setSpinnerOptionValue,
    setSpinnerOptionRequired,
    addSpinnerOption,
    deleteSpinnerOption,
    setElementState
  } = props;
  const optionListEl = useRef(null);
  return (
    <div className='pkt-spinner-container'>
      <div
        className={
          el.editing ? 'pkt-el pkt-spinner editing' : 'pkt-el pkt-spinner'
        }
      >
        {children && <div className='children'>{children}</div>}
        {el.editing ? (
          <table className='pkt-spinner-list-editing' ref={optionListEl}>
            <thead>
              <tr>
                <th colSpan={1}>Bezeichnung App</th>
                <th colSpan={1}>Wert im Cloud</th>
                {el.typ === 'chk' && (
                  <th className='pkt-spinner-required-column' colSpan={1}>
                    Erforderlich
                  </th>
                )}
                <th colSpan={1} className='pkt-spinner-delete-column'></th>
              </tr>
            </thead>
            <tbody>
              {el.items.map((item, index) => {
                const setOptionName = (newName) =>
                  setSpinnerOptionName(newName, path, index);
                const setOptionValue = (newValue) =>
                  setSpinnerOptionValue(newValue, path, index);
                const deleteOption = () => deleteSpinnerOption(path, index);
                const setOptionRequired =
                  el.typ === 'spin'
                    ? undefined
                    : (newVal) => {
                        setSpinnerOptionRequired(newVal, path, index);
                      };
                return (
                  <EditableOption
                    setElementState={setElementState}
                    array={el}
                    item={item}
                    setOptionName={setOptionName}
                    setOptionValue={setOptionValue}
                    deleteOption={deleteOption}
                    setOptionRequired={setOptionRequired}
                    key={item.uuid}
                  />
                );
              })}
              <tr>
                <td style={{ textAlign: 'center', padding: '4px' }}>
                  <button
                    className='add-spinner-option-button'
                    onClick={() => addSpinnerOption(path, el.items.length)}
                  >
                    <AddIcon />
                  </button>
                </td>
                <td></td>
                {el.typ === 'chk' && <td></td> /*Extra column for 'required'*/}
                <td></td>
              </tr>
            </tbody>
          </table>
        ) : (
          props.previewElement || <select></select>
        )}
      </div>
    </div>
  );
};

type EditableOptionProps = {
  array: SpinnerEditor | ChecklistEditor;
  item: SpinnerItemEditor | ChecklistItemEditor;
  setOptionName: (newName: string) => void;
  setOptionValue: (newValue: string) => void;
  deleteOption: () => void;
  // If this prop is set, then item is ChecklistItemEditor
  setOptionRequired?: (newValue: boolean) => void;
  setElementState: (el: SpinnerEditor | ChecklistEditor) => void;
};
const EditableOption: React.FC<EditableOptionProps> = ({
  array,
  item,
  setOptionName,
  setOptionValue,
  setOptionRequired,
  deleteOption,
  setElementState,
}) => {
  const nameInput = useRef<HTMLInputElement>(null);
  const valueInput = useRef<HTMLInputElement>(null);

  const currentItemName = typeof item === 'string' ? item : item.text;
  const currentItemValue = typeof item === 'string' ? item : item.value;
  const chkItem = setOptionRequired ? (item as ChecklistItemEditor) : undefined;

  const processNameChange = () => {
    const newName = nameInput.current?.value.trim() ?? '';
    if (newName && newName !== currentItemName) {
      setOptionName(newName);

      // Spiegeln ins Value-Feld, falls dort nichts steht
      if (valueInput.current && !valueInput.current.value.trim()) {
        valueInput.current.value = newName;
        setOptionValue(newName);
      }
    }
  };

  const processValueChange = () => {
    let newValue = valueInput.current?.value.trim() ?? '';
    if (!newValue) {
      // Value leer → mit Name befüllen
      newValue = nameInput.current?.value.trim() ?? '';
      if (valueInput.current) {
        valueInput.current.value = newValue;
      }
    }
    if (newValue !== currentItemValue) {
      setOptionValue(newValue);
    }
  };

  const transformUp = () => {
    const idx = array.items.findIndex((i) => i.uuid === item.uuid);
    if (idx > 0) {
      [array.items[idx - 1], array.items[idx]] = [array.items[idx], array.items[idx - 1]];
      setElementState(array);
    }
  };

  const transformDown = () => {
    const idx = array.items.findIndex((i) => i.uuid === item.uuid);
    if (idx >= 0 && idx < array.items.length - 1) {
      [array.items[idx + 1], array.items[idx]] = [array.items[idx], array.items[idx + 1]];
      setElementState(array);
    }
  };

  return (
    <tr>
      <td className="spinner-option-input-td">
        <div className="pkt-container">
          <div>
            <ArrowDropUp onClick={transformUp} className="Arrow" />
            <ArrowDropDown onClick={transformDown} className="Arrow" />
          </div>
          <input
            ref={nameInput}
            className="spinner-option-input-name"
            type="text"
            onBlur={processNameChange}
            defaultValue={currentItemName}
          />
        </div>
      </td>
      <td className="spinner-option-input-td">
        <input
          ref={valueInput}
          className="spinner-option-input"
          type="text"
          onBlur={processValueChange}
          defaultValue={currentItemValue}
        />
      </td>
      {chkItem && (
        <td className="pkt-spinner-required-column">
          <input
            type="checkbox"
            checked={chkItem.required ?? false}
            onChange={() => setOptionRequired(!chkItem.required)}
            className="spinner-option-required-input"
          />
        </td>
      )}
      <td className="pkt-spinner-delete-column">
        <button onClick={deleteOption} className="delete-spinner-option-button">
          <DeleteIcon />
        </button>
      </td>
    </tr>
  );
};
const mapStateToProps = () => ({});

function mapDispatchToProps(dispatch: Dispatch<FormEditorAction>) {
  return bindActionCreators(
    {
      toggleEditing,
      setSpinnerOptionName,
      setSpinnerOptionValue,
      setSpinnerOptionRequired,
      addSpinnerOption,
      deleteSpinnerOption
    },
    dispatch
  );
}

export default connect(mapStateToProps, mapDispatchToProps)(SpinnerEl);
