import { capitalize } from 'lodash-es';
import React, { useState } from 'react';
import { Button, Glyphicon, Grid, Row } from 'react-bootstrap';
import { useFetcher, useResource } from 'rest-hooks';
import { isEditable } from '../../helpers/statusUtils';
import ItemResource from '../../resources/item';
import SampleResource from '../../resources/sample';
import ResponsiveTable from '../Table/ResponsiveTable';
import ItemCondensedView from './ItemCondensedView';
import ItemForm from './ItemForm';
import styles from './ItemTable.module.css';
import { getSamplePageURL } from '../../helpers';

function typeFormatter(type) {
  return capitalize(type);
}

function sampleFormatter(sampleId, samples) {
  const sample = sampleId && samples.find((s) => s.id === sampleId);
  if (!sample) {
    return '';
  }

  const sampleURL = getSamplePageURL(sample);
  if (!sampleURL) {
    return sample.name;
  }

  return (
    <a target="_blank" rel="noopener noreferrer" href={sampleURL}>
      {sample.name}
    </a>
  );
}

function ItemTable(props) {
  const { setAlert, parcel, onItemChange } = props;
  const { investigationId, _id: parcelId, items } = parcel;
  const isParcelEditable = isEditable(parcel);

  const createItem = useFetcher(ItemResource.createShape());
  const editItem = useFetcher(ItemResource.updateShape());
  const deleteItem = useFetcher(ItemResource.deleteShape());

  const [isCreatingItem, setCreatingItem] = useState(false);
  const [editedItem, setEditedItem] = useState();

  const onSubmitForm = isCreatingItem ? createItem : editItem;
  const onClosingForm = isCreatingItem
    ? () => setCreatingItem(false)
    : () => setEditedItem(undefined);

  const samples = useResource(SampleResource.listShape(), { investigationId });
  const columns = [
    { text: 'ID', dataField: '_id', hidden: true, searchable: false },
    {
      text: 'Item',
      formatter: (_, item, __, samples) => {
        const formattedItem = {
          ...item,
          sample: sampleFormatter(item, samples),
          type: typeFormatter(item.type),
        };
        return <ItemCondensedView {...formattedItem} />;
      },
      formatExtraData: samples,
      responsiveHeaderStyle: {
        xs: { width: '100%' },
        sm: { width: '100%' },
        md: { hidden: true },
        lg: { hidden: true },
      },
    },
    {
      text: 'Name',
      dataField: 'name',
      sort: true,
      responsiveHeaderStyle: {
        xs: { hidden: true },
        sm: { hidden: true },
        md: { width: 150 },
        lg: { width: 150 },
      },
    },
    {
      text: 'Type',
      dataField: 'type',
      sort: true,
      formatter: typeFormatter,
      responsiveHeaderStyle: {
        xs: { hidden: true },
        sm: { hidden: true },
        md: { width: 120 },
        lg: { width: 120 },
      },
    },
    {
      text: 'Sample',
      dataField: 'sampleId',
      sort: true,
      formatExtraData: samples,
      formatter: (sampleId, _, __, samples) =>
        sampleFormatter(sampleId, samples),
      responsiveHeaderStyle: {
        xs: { hidden: true },
        sm: { hidden: true },
        md: { width: 120 },
        lg: { width: 120 },
      },
    },
    {
      text: 'Description',
      dataField: 'description',
      responsiveHeaderStyle: {
        xs: { hidden: true },
        sm: { hidden: true },
      },
    },
    {
      text: 'Comments',
      dataField: 'comments',
      responsiveHeaderStyle: {
        xs: { hidden: true },
        sm: { hidden: true },
      },
    },
    {
      text: '',
      dataField: 'dummy-1',
      isDummyField: true,
      headerClasses: styles.actionHeader,
      formatter: (_, item) => (
        <div className={styles.actions}>
          <Button
            bsSize="xsmall"
            bsStyle="link"
            aria-label="Edit"
            onClick={() => setEditedItem(item)}
            disabled={!isParcelEditable}
          >
            <Glyphicon glyph="pencil" />
            <span className={styles.actionLabel}> Edit</span>
          </Button>
          <Button
            bsSize="xsmall"
            bsStyle="link"
            aria-label="Remove"
            onClick={async () => {
              try {
                setAlert(undefined);
                await deleteItem(
                  { investigationId, parcelId },
                  { _id: item._id }
                );
                onItemChange();
                setAlert({ type: 'success', message: 'Item removed.' });
              } catch (error) {
                setAlert({
                  type: 'danger',
                  message: `An error occurred while removing the item.`,
                });
                console.error(error.response);
              }
            }}
            disabled={!isParcelEditable}
          >
            <Glyphicon glyph="trash" />
            <span className={styles.actionLabel}> Remove</span>
          </Button>
        </div>
      ),
    },
  ];
  return (
    <Grid fluid>
      {isParcelEditable && (isCreatingItem || editedItem) && (
        <Row>
          <ItemForm
            item={editedItem}
            onSubmit={async (values) => {
              try {
                setAlert(undefined);
                await onSubmitForm({ investigationId, parcelId }, values);
                onItemChange();
                setAlert({ type: 'success', message: 'Item saved.' });
              } catch (error) {
                setAlert({
                  type: 'danger',
                  message: 'An error occurred while saving the item.',
                });
                console.error(error.response);
              }
              onClosingForm();
            }}
            onCancel={() => {
              setAlert(undefined);
              onClosingForm();
            }}
            samples={samples}
          />
        </Row>
      )}
      <Row>
        <ResponsiveTable
          keyField="_id"
          data={items}
          columns={columns}
          defaultSorted={[{ dataField: '_id', order: 'desc' }]}
          actions={[
            {
              label: 'Add an item',
              icon: 'plus',
              disabled: !isParcelEditable,
              bsStyle: 'primary',
              onClick: () => {
                setCreatingItem(true);
              },
            },
          ]}
        />
      </Row>
    </Grid>
  );
}

export default ItemTable;
