import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'clsx';
import { closestCenter, DndContext, KeyboardSensor, PointerSensor, useSensor, useSensors } from '@dnd-kit/core';
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { DeleteRounded, DragIndicatorRounded } from '@mui/icons-material';

import { getInputPropsByName } from '@/modules/@common/Form/helpers';

import SortableItem from '@/modules/@common/dnd/SortableItem/SortableItem';
import { FormGroup, FormRow, useFormSettings } from '@/modules/@common/Form';
import { IconButton, Stack, TextField } from '@/mui/components';

import styles from './PlaceholderList.module.scss';

function PlaceholderList({ ...props }) {
  const { size } = useFormSettings();
  const sensors = useSensors(
    useSensor(PointerSensor),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    }),
  );

  // fields handlers
  const handleDragEnd = ({ active, over }) => {
    const getIndex = (neededIndex) => props.fields.findIndex((o) => o.id === neededIndex);
    const oldIndex = getIndex(active.id);
    const newIndex = getIndex(over.id);
    const dynamicFields = arrayMove(props.fields, oldIndex, newIndex);

    props.onSetField(dynamicFields);
  };

  const handleRemove = (fieldId) => {
    const dynamicFields = props.fields.filter((field) => field.id !== fieldId);
    return props.onSetField(dynamicFields);
  };

  const handleFieldSetValue = (fieldId, keyOfValue, value) => {
    const dynamicFields = props.fields.map((field) => ({
      ...field,
      [keyOfValue]: field.id === fieldId ? value : field[keyOfValue],
    }));

    return props.onSetField(dynamicFields);
  };

  return (
    <FormGroup>
      <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
        <SortableContext items={props.fields?.map((field) => field.id)} strategy={verticalListSortingStrategy}>
          {props.fields?.map((field) => (
            <SortableItem key={field.id} value={field.id} isDragDisabled={props.fields?.length <= 1}>
              {(sortableItemProps) => (
                <FormRow fullWidth key={field.id} multiline>
                  <Stack
                    spacing={0}
                    direction="row"
                    alignItems="flex-start"
                    fullWidth
                    key={field.id}
                    ref={sortableItemProps.dndSetNodeRef}
                    style={sortableItemProps.dndStyle}
                    {...sortableItemProps.dndAttributes}
                    className={classNames(styles.Field, {
                      [styles.Field___selected]: field.isSelected,
                      [styles.Field___dragging]: sortableItemProps.dndIsDragging,
                    })}
                  >
                    <>
                      <IconButton size={size} component="span" {...sortableItemProps.dndListeners}>
                        <DragIndicatorRounded />
                      </IconButton>
                      <TextField
                        size={size}
                        value={field.selector}
                        placeholder={field.placeholder}
                        onChange={({ target }) => handleFieldSetValue(field.id, 'selector', target.value)}
                        // eslint-disable-next-line react/prop-types
                        {...getInputPropsByName(props.scheme, ['selectors', field.id, 'selector'])}
                        // eslint-disable-next-line react/prop-types
                        onFocus={() => props.removeErrorByPropAction(['selectors', field.id, 'selector'])}
                      />
                      <IconButton size={size} component="span" onClick={() => handleRemove(field.id)}>
                        <DeleteRounded />
                      </IconButton>
                    </>
                  </Stack>
                </FormRow>
              )}
            </SortableItem>
          ))}
        </SortableContext>
      </DndContext>
    </FormGroup>
  );
}

PlaceholderList.propTypes = {
  fields: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
  onSetField: PropTypes.func.isRequired,
};

export default PlaceholderList;
