import React from 'react';
import {
  Button,
  Checkbox,
  Col,
  ControlLabel,
  DropdownButton,
  Form,
  FormControl,
  FormGroup,
  Glyphicon,
  HelpBlock,
  MenuItem,
  Modal,
} from 'react-bootstrap';
import { useForm, FormProvider } from 'react-hook-form';
import { useSelector } from 'react-redux';
import { useCache, useResource } from 'rest-hooks';
import AddressResource from '../../resources/address';
import AddressTextFieldsForm from '../Address/AddressTextFields';
import { addressFormatter, useReturnAddress } from '../Address/utils';
import TextFieldGroup from '../Form/TextFieldGroup';
import styles from './ParcelFormModal.module.css';
import RequiredStar from '../RequiredStar';

const FORM_LAYOUT = { labelCol: { sm: 3 }, fieldCol: { sm: 9 } };

const STORAGE_CONDITIONS = {
  RoomTemp: 'At room temperature',
  Fridge: 'In fridge (-4°C)',
  Freezer: 'In freezer (-18°C)',
  UltraFreezer: 'In freezer (-80°C)',
  Other: 'Other',
};

function ParcelFormModal(props) {
  const {
    investigation,
    shipment,
    parcel,
    onSubmitAsync,
    onCloseModal,
  } = props;
  const [investigationId, investigationName] = parcel
    ? [parcel.investigationId, parcel.investigationName]
    : [investigation.id, investigation.name];
  const { _id: shipmentId } = shipment;
  const username = useSelector((state) => state.user.name);

  async function onSubmit(values) {
    const newValues = {
      ...values,
      returnAddress: values.noReturnAddress ? null : values.returnAddress,
    };
    await onSubmitAsync(newValues);
  }

  const addresses = useResource(AddressResource.listShape(), {});

  // Default addresses are returned in full with shipment so we get them straight from cache (as they may not be in the user's addresses)
  const shipmentShippingAddress = useCache(AddressResource.detailShape(), {
    _id: shipment.defaultShippingAddress,
  });
  const shipmentReturnAddress = useReturnAddress(shipment);

  const defaultValues = parcel
    ? { ...parcel, noReturnAddress: !parcel.returnAddress }
    : {
        shippingAddress: shipmentShippingAddress,
        returnAddress: shipmentReturnAddress,
        noReturnAddress: !shipmentReturnAddress,
        storageConditions: STORAGE_CONDITIONS.RoomTemp,
      };

  const methods = useForm({ defaultValues });
  const {
    handleSubmit,
    register,
    formState,
    watch,
    getValues,
    reset,
  } = methods;
  const { isSubmitting } = formState;

  const watchedNoReturnAddress = watch('noReturnAddress');
  const watchedStorageConditions = watch('storageConditions');

  return (
    <Modal
      show
      backdrop="static"
      bsSize="large"
      aria-labelledby="parcel-modal-title"
      onHide={onCloseModal}
    >
      <Modal.Header closeButton>
        <Modal.Title id="parcel-modal-title">
          {parcel ? 'Edit' : 'Create'} parcel
        </Modal.Title>
      </Modal.Header>

      <Modal.Body>
        <Form horizontal>
          <FormProvider {...methods}>
            {parcel && <input name="_id" type="hidden" ref={register} />}
            {
              <input
                name="investigationId"
                defaultValue={investigationId}
                type="hidden"
                ref={register}
              />
            }
            {
              <input
                name="investigationName"
                defaultValue={investigationName}
                type="hidden"
                ref={register}
              />
            }
            {
              <input
                name="shipmentId"
                defaultValue={shipmentId}
                type="hidden"
                ref={register}
              />
            }

            <TextFieldGroup
              name="name"
              label="Name of the parcel"
              type="text"
              registerOptions={{ required: true }}
              layout={FORM_LAYOUT}
            />
            <TextFieldGroup
              name="description"
              type="textarea"
              layout={FORM_LAYOUT}
            />
            <FormGroup controlId="storageConditions">
              <Col {...FORM_LAYOUT.labelCol}>
                <ControlLabel>
                  Storage conditions
                  <RequiredStar />
                </ControlLabel>
              </Col>
              <Col {...FORM_LAYOUT.fieldCol}>
                <FormControl
                  name="storageConditions"
                  componentClass="select"
                  inputRef={register}
                >
                  {Object.entries(STORAGE_CONDITIONS).map(([k, cond]) => (
                    <option key={k} value={cond}>
                      {cond}
                    </option>
                  ))}
                </FormControl>
                {watchedStorageConditions === STORAGE_CONDITIONS.Other && (
                  <HelpBlock>
                    <Glyphicon glyph="warning-sign" />
                    Please specify in the comments
                  </HelpBlock>
                )}
              </Col>
            </FormGroup>
            <TextFieldGroup
              name="comments"
              label="Comments"
              type="textarea"
              registerOptions={{
                required: watchedStorageConditions === STORAGE_CONDITIONS.Other,
              }}
              layout={FORM_LAYOUT}
            />

            <input
              name={'shippingAddress.createdBy'}
              defaultValue={username}
              type="hidden"
              ref={register}
            />
            <input
              name={'returnAddress.createdBy'}
              defaultValue={username}
              type="hidden"
              ref={register}
            />
            <input
              name={'shippingAddress.investigationName'}
              defaultValue={investigationName}
              type="hidden"
              ref={register}
            />
            <input
              name={'returnAddress.investigationName'}
              defaultValue={investigationName}
              type="hidden"
              ref={register}
            />

            <FormGroup controlId="shippingAddress">
              <Col {...FORM_LAYOUT.labelCol}>
                <ControlLabel>Address of sender</ControlLabel>
                <DropdownButton
                  title="Choose from my addresses"
                  id="shippingAddressAutoFill"
                  className={styles.dropdown}
                >
                  {addresses.map((a) => (
                    <MenuItem
                      key={a._id}
                      eventKey={a._id}
                      onSelect={() =>
                        reset({ ...getValues(), shippingAddress: a })
                      }
                    >
                      {addressFormatter(a)}
                    </MenuItem>
                  ))}
                </DropdownButton>
              </Col>
              <Col {...FORM_LAYOUT.fieldCol}>
                <AddressTextFieldsForm addressObjName={'shippingAddress'} />
                {getValues('shippingAddress._id') ===
                  shipmentShippingAddress._id && (
                  <HelpBlock>
                    This was filled according to your shipping configuration
                  </HelpBlock>
                )}
              </Col>
            </FormGroup>

            <FormGroup controlId="returnAddress">
              <Col {...FORM_LAYOUT.labelCol}>
                <ControlLabel>Return address</ControlLabel>
                <p className={styles.info}>
                  Where to return the parcel at the end of the investigation.
                </p>
                <DropdownButton
                  title="Choose from my addresses"
                  id="returnAddressAutoFill"
                  className={styles.dropdown}
                >
                  {addresses.map((a) => (
                    <MenuItem
                      key={a._id}
                      eventKey={a._id}
                      onSelect={() =>
                        reset({
                          ...getValues(),
                          returnAddress: a,
                          noReturnAddress: false,
                        })
                      }
                    >
                      {addressFormatter(a)}
                    </MenuItem>
                  ))}
                </DropdownButton>
              </Col>
              <Col {...FORM_LAYOUT.fieldCol}>
                <Checkbox
                  className={styles.returnCheckbox}
                  name="noReturnAddress"
                  inputRef={register}
                >
                  No return address (the parcel will be discarded)
                </Checkbox>
                {!watchedNoReturnAddress && (
                  <AddressTextFieldsForm addressObjName={'returnAddress'} />
                )}
                {((!shipmentReturnAddress && watchedNoReturnAddress) ||
                  (shipmentReturnAddress &&
                    !watchedNoReturnAddress &&
                    getValues('returnAddress._id') ===
                      shipmentReturnAddress._id)) && (
                  <HelpBlock>
                    This was filled according to your shipping configuration
                  </HelpBlock>
                )}
              </Col>
            </FormGroup>
          </FormProvider>
        </Form>
      </Modal.Body>

      <Modal.Footer>
        <Button bsStyle="link" onClick={onCloseModal}>
          Cancel
        </Button>
        <Button
          bsStyle="success"
          disabled={isSubmitting}
          onClick={handleSubmit(onSubmit)}
        >
          {`${parcel ? 'Sav' : 'Creat'}${isSubmitting ? 'ing...' : 'e'}`}
        </Button>
      </Modal.Footer>
    </Modal>
  );
}

export default ParcelFormModal;
