import React, { useEffect, useState } from 'react';
import { Alert, Button, Col, Glyphicon, Grid, Row } from 'react-bootstrap';
import { useDispatch, useSelector } from 'react-redux';
import { useFetcher, useResource } from 'rest-hooks';
import { setBreadCrumbs } from '../../actions/breadcrumbs';
import { isEditable } from '../../helpers/statusUtils';
import ParcelResource from '../../resources/parcel';
import ShipmentResource from '../../resources/shipment';
import ItemTable from '../Items/ItemTable';
import BasicPanel from './BasicPanel';
import ParcelFormModal from './ParcelFormModal';
import ParcelHeader from './ParcelHeader';
import ParcelStatusButtons from './ParcelStatusButtons';
import StatusDisplay from './StatusDisplay';
import StatusTable from './StatusTable';
import styles from './ParcelDetails.module.css';
import AddressPanel from '../Address/AddressPanel';

function ParcelDetails(props) {
  const { investigationId, parcelId } = props;

  const initParcel = useResource(ParcelResource.detailShape(), {
    investigationId,
    _id: parcelId,
  });
  const [parcel, setParcel] = useState(initParcel);

  const editParcel = useFetcher(ParcelResource.updateShape());
  const getParcel = useFetcher(ParcelResource.detailShape());
  const refetchParcel = () => getParcel({ investigationId, _id: parcelId });
  const editParcelWithRefetch = async (params, body) => {
    await editParcel(params, body);
    setParcel(await refetchParcel());
  };

  const {
    description,
    shippingAddress,
    returnAddress,
    comments,
    storageConditions,
  } = parcel;
  const [shipment] = useResource(ShipmentResource.listShape(), {
    investigationId: parcel.investigationId,
  });

  const [isEditingParcel, setEditingParcel] = useState(false);
  const [alert, setAlert] = useState();

  const dispatch = useDispatch();
  const userInvestigations = useSelector(
    (state) => state.myInvestigations.data
  );

  const investigation = userInvestigations.find(
    (investigation) => investigation.id === Number(investigationId)
  );

  useEffect(() => {
    if (investigation) {
      dispatch(
        setBreadCrumbs([
          {
            name: investigation.visitId.toUpperCase(),
            link: `/investigation/${investigation.id}/datasets`,
          },
          { badge: investigation.name, name: investigation.summary },
          {
            name: 'Shipping',
            link: `/investigation/${investigation.id}/shipping`,
          },
          { name: parcel ? parcel.name : 'Not found' },
        ])
      );
    }
  }, [dispatch, investigation, parcel]);

  if (!parcel) {
    return <p>Parcel not found !</p>;
  }

  function handleCloseModal() {
    setEditingParcel(false);
  }

  async function handleSubmit(values) {
    setAlert(undefined);
    try {
      const fetcherParams = {
        investigationId: parcel.investigationId,
        shipmentId: parcel.shipmentId,
      };

      await editParcelWithRefetch(fetcherParams, values);
      setAlert({ type: 'success', message: 'Parcel saved.' });
    } catch (error) {
      setAlert({ type: 'danger', message: 'An error occurred.' });
      console.error(error.response);
    }

    handleCloseModal();
  }

  return (
    <div className={styles.panelWrapper}>
      {alert && <Alert bsStyle={alert.type}>{alert.message}</Alert>}
      {isEditingParcel && (
        <ParcelFormModal
          shipment={shipment}
          parcel={parcel}
          onSubmitAsync={handleSubmit}
          onCloseModal={handleCloseModal}
        />
      )}
      <ParcelHeader parcel={parcel} setAlert={setAlert} />

      <div className={styles.statusRow}>
        <div className={styles.statusCol}>
          <span className={styles.label}>Status:</span>
          <div className={styles.currentStatus}>
            <StatusDisplay status={parcel.status} />
          </div>
        </div>
        <div className={styles.statusCol}>
          <ParcelStatusButtons
            parcel={parcel}
            updateStatus={(status, body) =>
              editParcelWithRefetch(
                {
                  investigationId: parcel.investigationId,
                  status,
                  parcelId: parcel._id,
                },
                { _id: parcel._id, ...body }
              )
            }
          />
        </div>
      </div>

      <BasicPanel
        title={
          <div className={styles.panelHeader}>
            <div>Parcel info</div>
            <Button
              bsStyle="primary"
              aria-label="Edit"
              onClick={() => setEditingParcel(true)}
              disabled={!isEditable(parcel)}
            >
              <Glyphicon glyph="pencil" />
              <span className={styles.actionLabel}> Edit</span>
            </Button>
          </div>
        }
      >
        <Grid fluid>
          <Row>
            <Col sm={12} md={2}>
              <span className={styles.label}>Description:</span>
            </Col>
            <Col sm={12} md={10}>
              {description || 'No description.'}
            </Col>
          </Row>
          <Row>
            <Col sm={12} md={2}>
              <span className={styles.label}>Storage conditions:</span>
            </Col>
            <Col sm={12} md={10}>
              {storageConditions}
            </Col>
          </Row>
          <Row>
            <Col sm={12} md={2}>
              <span className={styles.label}>Comments:</span>
            </Col>
            <Col sm={12} md={10}>
              {comments || 'No comments.'}
            </Col>
          </Row>

          <Row style={{ marginTop: '0.5rem' }}>
            <Col sm={12} md={6}>
              {parcel.containsDangerousGoods && (
                <Alert bsStyle="danger">
                  <Glyphicon glyph="warning-sign" /> This parcel contains
                  dangerous goods.
                </Alert>
              )}
            </Col>
          </Row>

          <Row style={{ marginTop: '0.5rem' }}>
            {shippingAddress && (
              <Col sm={12} md={6}>
                <AddressPanel
                  address={shippingAddress}
                  header={<b>Address of Sender:</b>}
                />
              </Col>
            )}
            <Col sm={12} md={6}>
              {returnAddress ? (
                <AddressPanel
                  address={returnAddress}
                  header={<b>Return Address:</b>}
                />
              ) : (
                <Alert bsStyle="danger">
                  <Glyphicon glyph="warning-sign" /> This parcel has no return
                  address and will be destroyed at the end of the investigation.
                </Alert>
              )}
            </Col>
          </Row>
        </Grid>
      </BasicPanel>

      <BasicPanel title="Content">
        <ItemTable
          setAlert={setAlert}
          onItemChange={async () => setParcel(await refetchParcel())}
          parcel={parcel}
        />
      </BasicPanel>

      <BasicPanel title="History">
        <Grid fluid>
          <Row>
            <StatusTable statuses={parcel.statuses} />
          </Row>
        </Grid>
      </BasicPanel>
    </div>
  );
}

export default ParcelDetails;
