import React, { useState, Suspense } from 'react';
import {
  Modal,
  Alert,
  Button,
  Glyphicon,
  HelpBlock,
  Grid,
} from 'react-bootstrap';
import { LinkContainer } from 'react-router-bootstrap';
import { useHistory } from 'react-router-dom';
import { useFetcher, useResource } from 'rest-hooks';
import { STATUS_DEFS } from '../../constants/parcelStatuses';
import { useQuery } from '../../helpers/hooks';
import ParcelResource from '../../resources/parcel';
import { beamlineFormatter, dateFormatter } from '../Investigation/utils';
import ParcelFormModal from '../Parcels/ParcelFormModal';
import ParcelTable from '../Parcels/ParcelTable';
import styles from './ParcelSection.module.css';
import { itemsFormatter } from '../../helpers';
import ParcelCondensedView from '../Parcels/ParcelCondensedView';
import Loader from '../Loader';

function getColumns(investigation) {
  return [
    { text: '', dataField: '_id', hidden: true, searchable: false },
    {
      dataField: 'condensedView',
      text: 'Parcel',
      isDummyField: true,
      formatter: (_, parcel, __, investigation) => (
        <ParcelCondensedView parcel={parcel} investigation={investigation} />
      ),
      formatExtraData: investigation,
      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 },
      },
    },
    {
      text: 'Proposal',
      dataField: 'investigationName',
      sort: true,
      responsiveHeaderStyle: {
        xs: { hidden: true },
        sm: { hidden: true },
      },
    },
    {
      text: 'Beamline',
      dataField: 'beamline',
      formatter: (_, __, ___, investigation) => (
        <span style={{ fontWeight: 'bold' }}>
          {beamlineFormatter(investigation)}
        </span>
      ),
      formatExtraData: investigation,
      sort: true,
      responsiveHeaderStyle: {
        xs: { hidden: true },
        sm: { hidden: true },
        md: { width: 100 },
        lg: { width: 100 },
      },
    },
    {
      text: 'Start Date',
      dataField: 'startDate',
      formatter: (_, __, ___, investigation) => {
        return investigation ? dateFormatter(investigation.startDate) : '';
      },
      formatExtraData: investigation,
      sort: true,
      responsiveHeaderStyle: {
        xs: { hidden: true },
        sm: { hidden: true },
        md: { width: 110 },
        lg: { width: 110 },
      },
    },
    {
      text: 'Number of items',
      dataField: 'items',
      formatter: itemsFormatter,
      responsiveHeaderStyle: {
        xs: { hidden: true },
        sm: { hidden: true },
        md: { width: 180 },
        lg: { width: 180 },
      },
    },
    {
      text: 'Status',
      dataField: 'status',
      formatter: (status) => STATUS_DEFS[status].label,
      sort: true,
      responsiveHeaderStyle: {
        xs: { hidden: true },
        sm: { hidden: true },
      },
    },
    {
      text: 'Dangerous goods',
      dataField: 'containsDangerousGoods',
      sort: true,
      formatter: (containsDangerousGoods) =>
        containsDangerousGoods ? (
          <span className={styles.dangerous}>YES</span>
        ) : (
          'NO'
        ),
      responsiveHeaderStyle: {
        xs: { hidden: true },
        sm: { hidden: true },
        md: { width: 150 },
        lg: { width: 150 },
      },
    },
    {
      text: 'After experiment',
      dataField: 'returnAddress',
      formatter: (returnAddress) =>
        returnAddress ? (
          'Ship back'
        ) : (
          <span className={styles.dangerous}>Destroy</span>
        ),
      sort: true,
      responsiveHeaderStyle: {
        xs: { hidden: true },
        sm: { hidden: true },
        md: { width: 150 },
        lg: { width: 150 },
      },
    },
  ];
}

function ParcelsSection(props) {
  const {
    investigation,
    shipment,
    defaultShippingAddress,
    defaultReturnAddress,
  } = props;

  const history = useHistory();
  const investigationUrl = `/investigation/${investigation.id}`;

  const query = useQuery();
  const isCreating = query.has('new-parcel');
  const editingId = query.get('edit-parcel');

  const apiParams = { investigationId: investigation.id };

  const parcels = useResource(ParcelResource.listShape(), {
    investigationId: investigation.id,
    shipmentId: shipment._id,
  });
  const parcel = useResource(
    ParcelResource.detailShape(),
    editingId ? { _id: editingId, ...apiParams } : null
  );

  const [alert, setAlert] = useState();

  const createParcel = useFetcher(ParcelResource.createShape());
  const editParcel = useFetcher(ParcelResource.updateShape());
  const refetchParcels = useFetcher(ParcelResource.listShape());

  function handleCloseModal() {
    history.push(`${investigationUrl}/shipping`);
  }

  async function handleSubmit(values) {
    setAlert(undefined);
    try {
      const fetcherParams = { ...apiParams, shipmentId: shipment._id };

      if (!parcel) {
        await createParcel(fetcherParams, values);
      } else {
        await editParcel(fetcherParams, values);
      }

      await refetchParcels(fetcherParams);
      setAlert({
        type: 'success',
        message: `Parcel ${isCreating ? 'created' : 'saved'}.`,
      });
    } catch (error) {
      setAlert({ type: 'danger', message: `An error occurred.` });
      console.error(error.response);
    }

    handleCloseModal();
  }

  return (
    <Grid style={{ marginLeft: 0 }} fluid>
      {(isCreating || editingId) && (
        <Suspense
          fallback={
            <Modal show>
              <Loader message="Loading form..." spacedOut />
            </Modal>
          }
        >
          <ParcelFormModal
            investigation={investigation}
            shipment={shipment}
            parcel={parcel}
            investigationUrl={investigationUrl}
            onSubmitAsync={handleSubmit}
            onCloseModal={handleCloseModal}
          />
        </Suspense>
      )}
      <div className="actions-heading">
        <div className={styles.heading}>
          <h3>Parcels</h3>
          {investigation &&
            (defaultShippingAddress !== undefined &&
            defaultReturnAddress !== undefined ? (
              <LinkContainer
                className={styles.newButton}
                to={`/investigation/${investigation.id}/shipping?new-parcel`}
              >
                <Button bsStyle="primary">
                  <Glyphicon glyph="plus" /> New parcel
                </Button>
              </LinkContainer>
            ) : (
              <div className={styles.heading}>
                <HelpBlock>
                  <Glyphicon glyph="warning-sign" /> Your default shipping
                  addresses are not valid ! Please correct them before adding
                  parcels.
                </HelpBlock>
                <Button className={styles.newButton} bsStyle="primary" disabled>
                  <Glyphicon glyph="plus" /> New parcel
                </Button>
              </div>
            ))}
        </div>
      </div>

      {alert && (
        <Alert bsStyle={alert.type} onDismiss={() => setAlert(undefined)}>
          {alert.message}
        </Alert>
      )}

      <ParcelTable columns={getColumns(investigation)} parcels={parcels} />
    </Grid>
  );
}

export default ParcelsSection;
