/**
 * Contents item component.
 * @module components/manage/Contents/ContentsItem
 */

import React from 'react';
import { Button, Table, Menu, Divider } from 'semantic-ui-react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import map from 'lodash/map';
import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
import Circle from '@plone/volto/components/manage/Contents/circle';
import FormattedDate from '@plone/volto/components/theme/FormattedDate/FormattedDate';
import Icon from '@plone/volto/components/theme/Icon/Icon';
import Popup from '@plone/volto/components/theme/Popup/Popup';
import { getContentIcon } from '@plone/volto/helpers/Content/Content';
import moreSVG from '@plone/volto/icons/more.svg';
import checkboxUncheckedSVG from '@plone/volto/icons/checkbox-unchecked.svg';
import checkboxCheckedSVG from '@plone/volto/icons/checkbox-checked.svg';
import cutSVG from '@plone/volto/icons/cut.svg';
import deleteSVG from '@plone/volto/icons/delete.svg';
import copySVG from '@plone/volto/icons/copy.svg';
import showSVG from '@plone/volto/icons/show.svg';
import moveUpSVG from '@plone/volto/icons/move-up.svg';
import moveDownSVG from '@plone/volto/icons/move-down.svg';
import editingSVG from '@plone/volto/icons/editing.svg';
import dragSVG from '@plone/volto/icons/drag.svg';
import cx from 'classnames';

import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';

const messages = defineMessages({
  private: {
    id: 'private',
    defaultMessage: 'Private',
  },
  pending: {
    id: 'pending',
    defaultMessage: 'Pending',
  },
  published: {
    id: 'published',
    defaultMessage: 'Published',
  },
  intranet: {
    id: 'intranet',
    defaultMessage: 'Intranet',
  },
  draft: {
    id: 'draft',
    defaultMessage: 'Draft',
  },
  no_workflow_state: {
    id: 'no workflow state',
    defaultMessage: 'No workflow state',
  },
  none: {
    id: 'Not available',
    defaultMessage: 'None',
  },
});

function getColor(string) {
  switch (string) {
    case 'private':
      return '#ed4033';
    case 'published':
      return '#007bc1';
    case 'intranet':
      return '#51aa55';
    case 'draft':
      return '#f6a808';
    default:
      return 'grey';
  }
}

/**
 * Contents item component class.
 * @function ContentsItemComponent
 * @returns {string} Markup of the component.
 */
export const ContentsItemComponent = ({
  item,
  selected,
  onClick,
  indexes,
  onCut,
  onCopy,
  onDelete,
  onMoveToTop,
  onMoveToBottom,
  order,
  dndKitSortable,
  dndKitUtilities,
}) => {
  const intl = useIntl();
  const { useSortable } = dndKitSortable;
  const { CSS } = dndKitUtilities;
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({
    id: item['@id'],
    data: {
      type: 'item',
      id: item['@id'],
    },
  });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
  };

  return (
    <tr
      key={item['@id']}
      ref={setNodeRef}
      style={style}
      className={cx('', { 'dragging-row': isDragging })}
      aria-label={item['@id']}
    >
      <Table.Cell className={cx('', { 'dragging-cell': isDragging })}>
        <div style={{ display: 'inline-block' }}>
          <Button icon basic {...attributes} {...listeners}>
            <Icon
              name={dragSVG}
              size="20px"
              color="#878f93"
              className="content drag handle"
            />
          </Button>
        </div>
      </Table.Cell>
      <Table.Cell className={cx('', { 'dragging-cell': isDragging })}>
        {selected ? (
          <Button
            icon
            basic
            aria-label="Unchecked"
            onClick={(e) => onClick(e, item['@id'])}
          >
            <Icon
              name={checkboxCheckedSVG}
              color="#007eb1"
              size="24px"
              className="checked"
            />
          </Button>
        ) : (
          <Button
            icon
            basic
            aria-label="Checked"
            onClick={(e) => onClick(e, item['@id'])}
          >
            <Icon
              name={checkboxUncheckedSVG}
              color="#826a6a"
              size="24px"
              className="unchecked"
            />
          </Button>
        )}
      </Table.Cell>
      <Table.Cell className={cx('', { 'dragging-cell': isDragging })}>
        <Link
          className="icon-align-name"
          to={`${item['@id']}${item.is_folderish ? '/contents' : ''}`}
        >
          <div className="expire-align">
            <Icon
              name={getContentIcon(item['@type'], item.is_folderish)}
              size="20px"
              className="icon-margin"
              color="#878f93"
              title={item['Type'] || item['@type']}
            />{' '}
            <span title={item.title}> {item.title}</span>
          </div>
          {item.ExpirationDate !== 'None' &&
            new Date(item.ExpirationDate).getTime() < new Date().getTime() && (
              <Button className="button-margin expired-past" size="mini">
                <FormattedMessage id="Expired" defaultMessage="Expired" />
              </Button>
            )}
          {item.EffectiveDate !== 'None' &&
            new Date(item.EffectiveDate).getTime() > new Date().getTime() && (
              <Button className="button-margin effective-future" size="mini">
                <FormattedMessage id="Scheduled" defaultMessage="Scheduled" />
              </Button>
            )}
          {item.is_working_copy && (
            <Button className="button-margin working-copy" size="mini">
              <FormattedMessage
                id="Working copy"
                defaultMessage="Working copy"
              />
            </Button>
          )}
        </Link>
      </Table.Cell>
      {map(indexes, (index) => (
        <Table.Cell
          className={cx('', { 'dragging-cell': isDragging })}
          key={index.id}
        >
          {index.type === 'boolean' &&
            (item[index.id] ? (
              <FormattedMessage id="Yes" defaultMessage="Yes" />
            ) : (
              <FormattedMessage id="No" defaultMessage="No" />
            ))}
          {index.type === 'string' &&
            index.id !== 'review_state' &&
            item[index.id]}
          {index.id === 'review_state' && (
            <div>
              <span>
                <Circle color={getColor(item[index.id])} size="15px" />
              </span>
              {messages[item[index.id]]
                ? intl.formatMessage(messages[item[index.id]])
                : item['review_title'] ||
                  item['review_state'] ||
                  intl.formatMessage(messages.no_workflow_state)}
            </div>
          )}
          {index.type === 'date' && (
            <>
              {item[index?.id] && item[index.id] !== 'None' ? (
                <FormattedDate date={item[index.id]} />
              ) : (
                intl.formatMessage(messages.none)
              )}
            </>
          )}
          {index.type === 'array' && <span>{item[index.id]?.join(', ')}</span>}
        </Table.Cell>
      ))}
      <Table.Cell
        className={cx('', { 'dragging-cell': isDragging })}
        textAlign="right"
      >
        <Popup
          menu={true}
          position="bottom right"
          flowing={true}
          basic={true}
          on="click"
          popper={{
            className: 'dropdown-popup',
          }}
          trigger={
            <Icon
              name={moreSVG}
              className="dropdown-popup-trigger"
              size="24px"
              color="#007eb1"
            />
          }
        >
          <Menu vertical borderless fluid>
            <Link className="item icon-align" to={`${item['@id']}/edit`}>
              <Icon name={editingSVG} color="#007eb1" size="24px" />{' '}
              <FormattedMessage id="Edit" defaultMessage="Edit" />
            </Link>
            <Link className="item right-dropdown icon-align" to={item['@id']}>
              <Icon name={showSVG} color="#007eb1" size="24px" />{' '}
              <FormattedMessage id="View" defaultMessage="View" />
            </Link>
            <Divider />
            <Menu.Item
              onClick={onCut}
              value={item['@id']}
              className="right-dropdown icon-align"
            >
              <Icon name={cutSVG} color="#007eb1" size="24px" />{' '}
              <FormattedMessage id="Cut" defaultMessage="Cut" />
            </Menu.Item>
            <Menu.Item
              onClick={onCopy}
              value={item['@id']}
              className="right-dropdown icon-align"
            >
              <Icon name={copySVG} color="#007eb1" size="24px" />{' '}
              <FormattedMessage id="Copy" defaultMessage="Copy" />
            </Menu.Item>
            <Menu.Item
              onClick={onDelete}
              value={item['@id']}
              className="right-dropdown icon-align"
            >
              <Icon name={deleteSVG} color="#e40166" size="24px" />{' '}
              <FormattedMessage id="Delete" defaultMessage="Delete" />
            </Menu.Item>
            <Divider />
            <Menu.Item
              onClick={onMoveToTop}
              value={order}
              className="right-dropdown icon-align"
            >
              <Icon name={moveUpSVG} color="#007eb1" size="24px" />{' '}
              <FormattedMessage
                id="Move to top of folder"
                defaultMessage="Move to top of folder"
              />
            </Menu.Item>
            <Menu.Item
              onClick={onMoveToBottom}
              value={order}
              className="right-dropdown icon-align"
            >
              <Icon name={moveDownSVG} color="#007eb1" size="24px" />{' '}
              <FormattedMessage
                id="Move to bottom of folder"
                defaultMessage="Move to bottom of folder"
              />
            </Menu.Item>
          </Menu>
        </Popup>
      </Table.Cell>
    </tr>
  );
};

/**
 * Property types.
 * @property {Object} propTypes Property types.
 * @static
 */
ContentsItemComponent.propTypes = {
  item: PropTypes.shape({
    '@id': PropTypes.string,
    title: PropTypes.string,
    is_folderish: PropTypes.bool,
    '@type': PropTypes.string,
  }).isRequired,
  selected: PropTypes.bool.isRequired,
  onClick: PropTypes.func.isRequired,
  indexes: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.string,
      type: PropTypes.string,
    }),
  ).isRequired,
  onCut: PropTypes.func.isRequired,
  onCopy: PropTypes.func.isRequired,
  onDelete: PropTypes.func.isRequired,
  onMoveToTop: PropTypes.func.isRequired,
  onMoveToBottom: PropTypes.func.isRequired,
  order: PropTypes.number.isRequired,
};

export default injectLazyLibs(['dndKitSortable', 'dndKitUtilities'])(
  ContentsItemComponent,
);
