import React, { useState } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import { FormEditor, PktEl } from './PktEl';
import PktElWithActions from './PktElWithActions';
import {
  FormEditorAction,
  insertElement,
  removeProperty,
  setProperty,
} from './types';
import TextIcon from '@mui/icons-material/TextFields';
import NumericIcon from '@mui/icons-material/LooksOne';
import DateIcon from '@mui/icons-material/Today';
import ExternalIcon from '@mui/icons-material/ExitToApp';
import MediaIcon from '@mui/icons-material/Image';
import ChecklistIcon from '@mui/icons-material/CheckBox';
import SpinnerIcon from '@mui/icons-material/RadioButtonChecked';
import FormIcon from '@mui/icons-material/ListAlt';
import SignatureIcon from '@mui/icons-material/Spellcheck';
import TimeIcon from '@mui/icons-material/AccessTime';
import InfoIcon from '@mui/icons-material/Info';
import HomeIcon from '@mui/icons-material/Home';
import TextField from './TextField';
import { isEmptyStringOrNumber } from './common';
import TimeControlModal from './TimeControlModel';

type FormElProps = ReturnType<typeof mapDispatchToProps> & {
  el: FormEditor;
  path: Array<string | number>;
  children: React.ReactNode;
};

const FormEl: React.FC<FormElProps> = (props) => {
  const { el, path, children, insertElement, setProperty, removeProperty } =
    props;

  const [displayMode, setDisplayMode] = useState(
    el.tmp && el.tmp.length > 0 ? 'tmp' : 'items'
  );

  const setMax = (val: string) => {
    if (val === '') {
      removeProperty(path, 'max');
    } else {
      setProperty(path, 'max', parseInt(val));
    }
  };

  const handleDisplayModeChange = (mode) => {
    if (mode === 'items' && displayMode === 'tmp') {
      const newItems = el.tmp.concat(el.items || []);
      setDisplayMode(mode);
      setProperty(path, 'items', newItems);
      setProperty(path, 'tmp', []);
    } else if (mode === 'tmp' && displayMode === 'items') {
      const newTmp = el.items.concat(el.tmp || []);
      setDisplayMode(mode);
      setProperty(path, 'tmp', newTmp);
      setProperty(path, 'items', []);
    } else {
      setDisplayMode(mode);
    }
  };

  return (
    <div
      className={
        el.editing ? 'pkt-el pkt-form pkt-form-editing' : 'pkt-el pkt-form'
      }
    >
      {children && <div className='children'>{children}</div>}

      <div style={{ margin: '1rem' }}></div>
      {el.editing && (
        <TextField
          label='Max'
          currentValue={el.max?.toString() ?? ''}
          validate={isEmptyStringOrNumber}
          setValue={setMax}
        />
      )}

      <div className='pkt-form-switch'>
        <label>
          <input
            type='radio'
            value='items'
            checked={displayMode === 'items'}
            onChange={() => handleDisplayModeChange('items')}
          />
          Einfach
        </label>
        <label>
          <input
            type='radio'
            value='tmp'
            checked={displayMode === 'tmp'}
            onChange={() => handleDisplayModeChange('tmp')}
          />
          Mehrfach
        </label>
      </div>

      <div className='pkt-form-items'>
        {el.editing && (
          <>
            <span className='pkt-form-section-header edit-element'>
              {displayMode === 'items' ? 'Einfach' : 'Mehrfach'}
            </span>
            <InsertElActions
              newItemIndex={0}
              path={path}
              insertElement={insertElement}
              itemType={displayMode === 'items' ? 'items' : 'tmp'}
            />
          </>
        )}
        {(el[displayMode] ?? []).map((item, itemIndex) => [
          <PktElWithActions
            el={item}
            path={[...path, displayMode, itemIndex]}
            key={item.uuid}
          />,
          el.editing && (
            <InsertElActions
              newItemIndex={itemIndex + 1}
              path={path}
              insertElement={insertElement}
              itemType={displayMode === 'items' ? 'items' : 'tmp'}
              key={'insertElActionsAfter' + item.uuid}
            />
          ),
        ])}
      </div>
    </div>
  );
};

const InsertElActions: React.FC<{
  path: Array<string | number>;
  newItemIndex: number;
  itemType: 'items' | 'tmp';
  insertElement: ReturnType<typeof mapDispatchToProps>['insertElement'];
}> = (props) => {
  const { path, insertElement, newItemIndex, itemType } = props;
  const createElement = (elTyp: PktEl['typ']) =>
    insertElement(elTyp, path, newItemIndex, itemType);
  return (
    <div className='insert-el-actions-wrapper edit-element'>
      <div className='insert-el-actions edit-element'>
        <button onClick={() => createElement('txt')} title='Text'>
          <TextIcon />
        </button>
        <button onClick={() => createElement('num')} title='Numerisch'>
          <NumericIcon />
        </button>
        <button onClick={() => createElement('date')} title='Datum'>
          <DateIcon />
        </button>
        <button onClick={() => createElement('media')} title='Medien'>
          <MediaIcon />
        </button>
        <button onClick={() => createElement('spin')} title='Spinner'>
          <SpinnerIcon />
        </button>
        <button onClick={() => createElement('chk')} title='Checkliste'>
          <ChecklistIcon />
        </button>
        <button onClick={() => createElement('form')} title='Formular'>
          <FormIcon />
        </button>
        <button onClick={() => createElement('sign')} title='Unterschrift'>
          <SignatureIcon />
        </button>
        <button onClick={() => createElement('ext')} title='Extern'>
          <ExternalIcon />
        </button>
        <button onClick={() => createElement('time')} title='Zeit'>
          <TimeIcon />
        </button>
        <button onClick={() => createElement('info')} title='Info'>
          <InfoIcon />
        </button>
        <button onClick={() => createElement('address')} title='Adresse'>
          <HomeIcon />
        </button>
      </div>
    </div>
  );
};

const mapStateToProps = (state) => ({});

function mapDispatchToProps(dispatch: Dispatch<FormEditorAction>) {
  return bindActionCreators(
    { insertElement, setProperty, removeProperty },
    dispatch
  );
}

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