import React, { useRef, useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import {
  ChecklistEl,
  ExternalEl,
  MediaEl,
  SignatureEl,
  TimeEl,
  GpsEl,
  LovibondEl,
} from './FormEditor';
import InfoEl from './InfoEl';
import FormEl from './FormEl';
import ListEl from './ListEl';
import AddressEl from './AddressEl';

import { EditorPktEl, PktEl, pktTypes } from './PktEl';
import SpinnerEl from './SpinnerEl';
import TxtEl from './TxtEl';
import {
  FormEditorAction,
  deleteElement,
  toggleRequired,
  Path,
  renameElement,
  toggleEditing,
  toggleProperty,
  setElType,
  Toggle,
  getTogglesForElType,
  removeProperty,
  saveModalContent,
  setProperty,
} from './types';
import DoneIcon from '@mui/icons-material/CheckCircleOutline';
import EditIcon from '@mui/icons-material/EditOutlined';
import DeleteIcon from '@mui/icons-material/Delete';
import NumericEl from './NumericEl';
import DateEl from './DateEl';
import TextField from './TextField';
import { isEmptyStringOrNumber } from './common';
import { element } from 'prop-types';
import '../../css/frontendStyle.css';

/*ahmed */
import LockClockIcon from '@mui/icons-material/LockClock';
import TimeControlModal from './TimeControlModel';

type PktElWithActionsProps = ReturnType<typeof mapDispatchToProps> & {
  el: EditorPktEl;
  path: Path;
};

function renderEl(el: EditorPktEl, path: Path, children?: React.ReactNode) {
  // provide default range for date type
  if (el.typ === 'date' && el.range === undefined) {
    el.range = [0, 0];
  }
  const [elementState, setElementState] = useState(null);
  if (elementState !== null) {
    el = elementState;
    setElementState(null);
  }

  switch (el.typ) {
    case 'txt':
      return (
        <div>
          <TxtEl el={el} path={path} children={children} />
        </div>
      );
    case 'info':
      return (
        <div>
          <InfoEl el={el} path={path} children={children} />
        </div>
      );
    case 'form':
      return <FormEl el={el} path={path} children={children} />;
    case 'media':
      return <MediaEl el={el} path={path} children={children} />;
    case 'spin':
      return elementState !== null ? (
        <SpinnerEl
          el={elementState}
          path={path}
          children={children}
          setElementState={setElementState}
        />
      ) : (
        <SpinnerEl
          el={el}
          path={path}
          children={children}
          setElementState={setElementState}
        />
      );

    case 'num':
      return <NumericEl el={el} path={path} children={children} />;
    case 'date':
      return <DateEl el={el} path={path} children={children} />;
    case 'sign':
      return <SignatureEl el={el} path={path} children={children} />;
    case 'ext':
      return <ExternalEl el={el} path={path} children={children} />;
    case 'chk':
      return elementState !== null ? (
        <ChecklistEl
          el={elementState}
          path={path}
          children={children}
          setElementState={setElementState}
        />
      ) : (
        <ChecklistEl
          el={el}
          path={path}
          children={children}
          setElementState={setElementState}
        />
      );
    case 'list':
      return (
        <div>
          <ListEl el={el} path={path} children={children} />
        </div>
      );
    case 'time':
      return <TimeEl el={el} path={path} children={children} />;
    case 'gps':
      return <GpsEl el={el} path={path} children={children} />;
    case 'lovibond':
      return <LovibondEl el={el} path={path} children={children} />;
    case 'address':
      return <AddressEl el={el} path={path} children={children} />;

    default:
      return (
        <div className='pkt-el pkt-unsupported'>
          {children && <div className='children'>{children}</div>}
          (Unimplemented element type: {el.typ})
        </div>
      );
  }
}
// Definition von toggleDisplayValues
const toggleDisplayValues: { [key in Toggle]: string } = {
  required: 'Erforderlich',
  isdescription: 'Beschreibung',
  addToTag: 'Mit Tag markieren',
  en_timestamp: 'Zeitstempel',
  movedya: 'Verschieben',
  emailsend: 'Email versenden',
  unfolded: 'Ausgeklappt',
  isBarcode: 'Barcode',
};
function renderToggle(
  toggle: Toggle,
  path: Path,
  el: EditorPktEl,
  toggleProperty: (toggle: Toggle, path: Path) => void
) {
  const translatedToggle = toggleDisplayValues[toggle]; // Übersetzten Wert abrufen

  return (
    <label key={`toggle-${toggle}-${el.uuid}`}>
      {translatedToggle} {/* Verwenden Sie den übersetzten Wert */}
      <input
        type='checkbox'
        checked={el[toggle] ?? false}
        onChange={() => toggleProperty(toggle, path)}
      ></input>
    </label>
  );
}

const labels = document.querySelectorAll('.el-toggles label');
labels.forEach((label) => {
  const input = label.querySelector('input');
  const labelText = toggleDisplayValues[input.value]; // Übersetzten Wert abrufen
  label.firstChild.textContent = labelText;
});

const PktElWithActions: React.FC<PktElWithActionsProps> = (props) => {
  const {
    el,
    path,
    toggleRequired,
    deleteElement,
    renameElement,
    toggleEditing,
    toggleProperty,
    removeProperty,
    setProperty,
    setElType,
  } = props;

  const [editTime, setEditTime] = useState(false);

  function saveName(newName: string) {
    if (newName !== el.name) {
      if (newName === '') {
        removeProperty(path, 'name');
      } else {
        renameElement(path, newName);
      }
    }
  }

  function onClickName() {
    if (!isEditingName) {
      setEditingName(true);
    }
  }

  const toggles = getTogglesForElType(el.typ).map((tog) =>
    renderToggle(tog, path, el, toggleProperty)
  );

  const setDeleteInDays = (val: string) => {
    if (val === '') {
      removeProperty(path, 'delete_in_days');
    } else {
      setProperty(path, 'delete_in_days', parseInt(val));
    }
  };
  const deleteInDaysInput = (
    <TextField
      currentValue={el.delete_in_days?.toString()}
      validate={isEmptyStringOrNumber}
      setValue={setDeleteInDays}
      label='Wann löschen (in Tagen)'
    />
  );
  const setFunction = (val: string) => {
    if (val === '') {
      removeProperty(path, 'function');
    } else {
      setProperty(path, 'function', val);
    }
  };
  const functionInput = (
    <TextField
      label='Funktion'
      currentValue={el.function ?? ''}
      validate={(value) => true}
      setValue={setFunction}
    />
  );
  const close = () => {
    localStorage.removeItem('jsonForm');
    setEditTime(!editTime);
  };

  const changeTime = (timeControlConfig) => {
    Object.assign(el, timeControlConfig);
  };
  let backgroundColor = null;
  if (el.hasOwnProperty('timeControl')) {
    el.timeControl.required
      ? (backgroundColor = 'lightgreen')
      : (backgroundColor = null);
  }
  const children =
    el.editing && el.typ == 'form' ? (
      <>
        <div className='el-toggles' style={{ flexFlow: 'wrap' }}>
          {toggles}
          <>
            <label key={`toggle-${'timeControl'}-${el.uuid}`}>
              Zeit
              <button
                style={{ backgroundColor: backgroundColor }}
                onClick={() => {
                  setEditTime(!editTime);
                }}
                title='Zeit'
                id='zeitControl'
              >
                <LockClockIcon />
              </button>
            </label>
          </>
          {editTime ? (
            <TimeControlModal
              isOpen={editTime}
              close={close}
              jsonForm={JSON.stringify(el)}
              changeTime={changeTime}
            />
          ) : (
            <></>
          )}
        </div>

        {deleteInDaysInput}
        {functionInput}
      </>
    ) : el.editing && el.typ != 'form' ? (
      <>
        <div className='el-toggles'>{toggles}</div>
        {deleteInDaysInput}
        {functionInput}
      </>
    ) : (
      <></>
    );

  const innerEl = renderEl(el, path, children);
  const [isEditingName, setEditingName] = useState(false);

  const typeDisplayValues = {
    txt: 'Text',
    chk: 'Multicheck',
    num: 'Zahlen',
    spin: 'Dropdown',
    media: 'Medien',
    date: 'Datum',
    sign: 'Signatur',
    form: 'Formular',
    ext: 'Extern',
    gps: 'GPS',
    lovibond: 'Lovibond',
    list: 'Liste',
    time: 'Uhrzeit',
    info: 'Info',
    address: 'Adresse',
  };

  return (
    <div className='el-container'>
      <div className='el-top-bar'>
        <span
          onClick={onClickName}
          className={isEditingName ? 'el-name' : 'el-name click-to-edit'}
        >
          {el.required && <span className='required-asterisk' />}
          {isEditingName ? (
            <TextField
              currentValue={el.name}
              validate={(newName) => true}
              setValue={saveName}
              onBlur={() => setEditingName(false)}
              label=''
              autoFocus={true}
            />
          ) : (
            el.name ?? '(Kein Name vorhanden)'
          )}
        </span>
        {el.editing ? (
          <ElTypePicker path={path} el={el} setElType={setElType} />
        ) : (
          <span className='edit-element'>
            {typeDisplayValues[el.typ] ?? el.typ}
          </span>
        )}
        <div className='el-actions edit-element'>
          <button
            className='toggle-edit-button'
            onClick={() => {
              toggleEditing(path);
            }}
          >
            {el.editing ? <DoneIcon /> : <EditIcon />}
          </button>
          <button className='delete-button' onClick={() => deleteElement(path)}>
            <DeleteIcon />
          </button>
        </div>
      </div>
      {innerEl}
    </div>
  );
};

type ElTypePickerProps = {
  el: EditorPktEl;
  path: Path;
  setElType: (path: Path, typ: PktEl['typ']) => void;
};

const ElTypePicker: React.FC<ElTypePickerProps> = (props) => {
  const { setElType, el, path } = props;

  const typeDisplayValues = {
    txt: 'Text',
    chk: 'Multicheck',
    num: 'Zahlen',
    spin: 'Dropdown',
    media: 'Medien',
    date: 'Datum',
    sign: 'Signatur',
    form: 'Formular',
    ext: 'Extern',
    gps: 'GPS',
    lovibond: 'Lovibond',
    list: 'Liste',
    time: 'Uhrzeit',
    info: 'Info',
    address: 'Adresse',
  };

  return (
    <select
      onChange={(event) => setElType(path, event.target.value as PktEl['typ'])}
      defaultValue={el.typ}
    >
      {pktTypes.map((typ) => (
        <option value={typ} key={typ}>
          {typeDisplayValues[typ] ?? typ}
        </option>
      ))}
    </select>
  );
};

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

function mapDispatchToProps(dispatch: Dispatch<FormEditorAction>) {
  return bindActionCreators(
    {
      deleteElement,
      toggleRequired,
      renameElement,
      toggleEditing,
      toggleProperty,
      removeProperty,
      setProperty,
      setElType,
    },
    dispatch
  );
}

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