import React, { useState, useEffect, useRef } from 'react';
import qs from 'query-string';

import classNames from 'classnames/bind';
import { Form } from 'react-final-form';
import ParticipantForm from 'components/forms/ParticipantForm';
import arrayMutators from 'final-form-arrays';
import TextItem from 'components/items/TextItem';
import CustomIcon from 'components/items/CustomIcon';
import Tooltip from 'components/items/Tooltip';
import ModuleButton from 'components/items/ModuleButton';
import sortBy from 'lodash/sortBy';
import adminConfig from 'config/admin';
import { deepOmit } from 'store/utils/helper';
import styleIdentifiers from './participant.scss';

const styles = classNames.bind(styleIdentifiers);

export interface StateProps {}

export interface DispatchProps {}

export interface OwnProps {}

export type ParticipantProps = StateProps & DispatchProps & OwnProps;

const ParticipantIcon = props => {
  const { text, icon, action, noToolTip, className } = props;

  const item = (
    <div className={styles('info', className)} onClick={action}>
      <CustomIcon className={styles('icon')} icon={icon} />
    </div>
  );

  if (noToolTip) return item;

  return <Tooltip text={text} item={item} />;
};

const Participant = (props: ParticipantProps) => {
  const {
    load,
    match: { params },
    history,
    detail,
    addParticipant,
    deleteParticipant,
    dialogShow,
    exportAttestation,
    markAsParticipated,
    cancelParticipation,
    sendAttestation,
    participantFields = adminConfig?.adminEvent?.participantFields,
    match,
    options,
  } = props;

  const [showForm, setShowForm] = useState(false);
  const [showInfo, setShowInfo] = useState(false);
  const [selectedAll, setSelectedAll] = useState(false);
  const [selected, setSelected] = useState([]);
  const [filters, setFilters] = useState({});
  const [timer, setTimer] = useState(null);
  const searchInput = useRef(null);

  const data = detail?.data?.getParticipants;
  useEffect(() => {
    setFilters(qs.parse(location.search));
  }, [match]);

  function onSubmit(val) {
    addParticipant({
      input: val,
      id: params.id,
      callback: () => setShowForm(false),
    });
  }

  // to set params in url
  function loadSearch(res) {
    history.push({
      search: qs.stringify(res),
    });

    setFilters(location.search);
  }

  // search
  function handleSearch(res) {
    let req = filters;
    if (!req) req = {};

    if (res) req.search = res;
    else req = deepOmit(req, 'search');

    if (timer) clearTimeout(timer);
    const test = setTimeout(() => loadSearch(req), 500);
    setTimer(test);
  }

  function handleDelete(item) {
    dialogShow({
      id: 'confirm',
      title: 'Confirmation',
      messages: 'Are you sure you want to delete this participant?',
      action: {
        color: 'primary',
        value: () => {
          deleteParticipant({
            id: item._id,
            eventId: params.id,
          });
        },
      },
    });
  }

  function handleUploadAttestation(item) {
    exportAttestation({
      eventId: params.id,
      participantId: item._id,
      callback: res => {
        if (res.url) window.open(res.url, '_blank');
      },
    });
  }

  function handleMarkAsParticipated() {
    markAsParticipated({
      data: {
        participantIds: selected,
        eventId: params.id,
      },
    });
  }

  function handleSendAttestation() {
    sendAttestation({
      data: {
        participantIds: selected,
        eventId: params.id,
      },
      callback: () => setSelected([]),
    });
  }

  function handleMarkAsUnparticipated() {
    cancelParticipation({
      data: {
        participantIds: selected,
        eventId: params.id,
      },
    });
  }

  function handleSelect(item) {
    const res = [...selected];

    if (selected.includes(item)) {
      const index = res.indexOf(item);
      res.splice(index, 1);
    } else {
      res.push(item);
    }

    setSelected(res);
  }

  function handleAllSelect() {
    const res = [];
    if (!selectedAll) {
      for (let index = 0; index < data.length; index++) {
        const element = data[index];
        res.push(element._id);
      }
      setSelected(res);
      setSelectedAll(true);
    } else {
      setSelected(res);
      setSelectedAll(false);
    }
  }

  /*   useEffect(() => {
    load({ id: params.id });
  }, [params.id]); */

  useEffect(() => {
    load({ id: params.id, ...filters });
  }, [filters]);

  return (
    <div className={styles('Participant')}>
      <div className={styles('container')}>
        <div className={styles('title')}>
          <div className={styles('left')}>
            <div>Participants</div>
            <ModuleButton
              noMargin
              className={styles('button')}
              action={() => setShowForm(!showForm)}
              label={showForm ? 'Hide' : 'Add'}
              small
            />
          </div>
          <div className={styles('search-container')} onClick={() => searchInput.current.focus()}>
            <CustomIcon icon="search" className={styles('icon')} />
            <input
              onChange={e => handleSearch(e.target.value)}
              type="text"
              name="search"
              ref={searchInput}
              placeholder="Search"
            />
          </div>

          {selected && selected.length !== 0 && (
            <div className={styles('actions')}>
              <ModuleButton
                noMargin
                className={styles('button')}
                action={() => {
                  setSelected([]);
                  setSelectedAll(false);
                }}
                label="Clear selection"
                color="grey"
                small
              />
              <ModuleButton
                noMargin
                className={styles('button')}
                action={handleMarkAsParticipated}
                label="Mark as participate"
                small
              />
              <ModuleButton
                noMargin
                className={styles('button')}
                action={handleMarkAsUnparticipated}
                label="Cancel participation"
                small
              />
              <ModuleButton
                noMargin
                className={styles('button')}
                action={handleSendAttestation}
                label="Send Email"
                small
              />
            </div>
          )}
        </div>
        {showForm && (
          <div>
            <Form
              participantFields={participantFields}
              onSubmit={onSubmit}
              component={ParticipantForm}
              mutators={{ ...arrayMutators }}
              privateEvent={detail?.data?.private}
              tickets={detail?.data?.getTickets}
            />
          </div>
        )}
        <div className={styles('item-container-wrapper')}>
          <div className={styles('item-container')}>
            <div className={styles('item-main')}>
              <div
                className={styles('checkbox', selectedAll && 'active')}
                onClick={handleAllSelect}
              >
                <CustomIcon icon="check" className={styles('icon-check')} />
              </div>
            </div>
          </div>
          {sortBy(data, ['lastName']).map(
            (item, key) =>
              item && (
                <div className={styles('item-container')} key={key}>
                  <div className={styles('item-main')}>
                    <div
                      className={styles('checkbox', selected.includes(item._id) && 'active')}
                      onClick={() => handleSelect(item._id)}
                    >
                      <CustomIcon icon="check" className={styles('icon-check')} />
                    </div>
                    <div className={styles('name')}>
                      {`${item && item.title}. ${item.firstName} ${item.lastName} `}
                      <span className={styles('lg')}>{item.language}</span>
                      {item.participated && (
                        <ParticipantIcon icon="clipboard-check" text="Has participated" />
                      )}
                      {item.emailSent && (
                        <ParticipantIcon text="Attestation sent" icon="paper-plane" />
                      )}
                    </div>
                    <div className={styles('id')}>{`# ${item._id}`}</div>
                    <ParticipantIcon
                      noToolTip
                      icon={showInfo === item._id ? 'sort-up' : 'info'}
                      action={() => setShowInfo(showInfo === item._id ? false : item._id)}
                    />
                    <ParticipantIcon
                      action={() => handleUploadAttestation(item)}
                      icon="file-download"
                      text="Download attestation"
                    />
                    <ParticipantIcon
                      action={() => handleDelete(item)}
                      icon="trash-alt"
                      text="Delete"
                      className={styles('delete')}
                    />
                  </div>
                  {showInfo === item._id && (
                    <div className={styles('item-info')}>
                      <div>
                        <TextItem className={styles('name')} path="email : " />
                        <TextItem path={item.email} />
                      </div>
                      <div>
                        <TextItem className={styles('name')} path="phone : " />
                        <TextItem path={item.phone} />
                      </div>
                      <div>
                        <TextItem className={styles('name')} path="function : " />
                        <TextItem path={item.function} />
                      </div>
                      <div>
                        <TextItem className={styles('name')} path="company : " />
                        <TextItem path={item.company} />
                      </div>
                      {detail.data.getTickets.find(e => e._id === item.productId) && (
                        <div>
                          <TextItem className={styles('name')} path="ticket : " />
                          <TextItem
                            path={detail.data.getTickets.find(e => e._id === item.productId).title}
                          />
                        </div>
                      )}
                    </div>
                  )}
                </div>
              ),
          )}
        </div>
      </div>
    </div>
  );
};

export default Participant;
