text: import React, { Component } from 'react';
  import { string, bool, arrayOf } from 'prop-types';
  import { compose } from 'redux';
  import { Form as FinalForm } from 'react-final-form';
  import { FormattedMessage, intlShape, injectIntl } from '../../util/reactIntl';
  import classNames from 'classnames';
  import moment from 'moment';
  import { required, bookingDatesRequired, composeValidators } from '../../util/validators';
  import { START_DATE, END_DATE } from '../../util/dates';
  import { propTypes } from '../../util/types';
  import config from '../../config';
  import { Form, PrimaryButton, FieldDateRangeInput, FieldTimeRangeInput } from '../../components';
  import EstimatedBreakdownMaybe from './EstimatedBreakdownMaybe';
  
  import css from './BookingDatesForm.css';
  
  const identity = v => v;
  
  export class BookingDatesFormComponent extends Component {
    constructor(props) {
      super(props);
      this.state = { focusedInput: null };
      this.handleFormSubmit = this.handleFormSubmit.bind(this);
      this.onFocusedInputChange = this.onFocusedInputChange.bind(this);
    }
  
    // Function that can be passed to nested components
    // so that they can notify this component when the
    // focused input changes.
    onFocusedInputChange(focusedInput) {
      this.setState({ focusedInput });
    }
  
    // In case start or end date for the booking is missing
    // focus on that input, otherwise continue with the
    // default handleSubmit function.
    handleFormSubmit(e) {
      const { startDate, endDate } = e.bookingDates || {};
      if (!startDate) {
        e.preventDefault();
        this.setState({ focusedInput: START_DATE });
      } else if (!endDate) {
        e.preventDefault();
        this.setState({ focusedInput: END_DATE });
      } else {
        this.props.onSubmit(e);
      }
    }
  
    render() {
      const { rootClassName, className, price: unitPrice, ...rest } = this.props;
      const classes = classNames(rootClassName || css.root, className);
  
      if (!unitPrice) {
        return (
          <div className={classes}>
            <p className={css.error}>
              <FormattedMessage id="BookingDatesForm.listingPriceMissing" />
            </p>
          </div>
        );
      }
      if (unitPrice.currency !== config.currency) {
        return (
          <div className={classes}>
            <p className={css.error}>
              <FormattedMessage id="BookingDatesForm.listingCurrencyInvalid" />
            </p>
          </div>
        );
      }
  
      return (
        <FinalForm
          {...rest}
          unitPrice={unitPrice}
          onSubmit={this.handleFormSubmit}
          render={fieldRenderProps => {
            const {
              endDatePlaceholder,
              startDatePlaceholder,
              formId,
              handleSubmit,
              intl,
              isOwnListing,
              form,
              submitButtonWrapperClassName,
              unitPrice,
              unitType,
              values,
              timeSlots,
              fetchTimeSlotsError,
              publicData,
            } = fieldRenderProps;
            const { startDate, endDate } = values && values.bookingDates ? values.bookingDates : {};
            const { startTime, endTime } = values && values.bookingTimes ? values.bookingTimes : {};
  
            const bookingStartLabel = intl.formatMessage({
              id: 'BookingDatesForm.bookingStartTitle',
            });
            const bookingEndLabel = intl.formatMessage({ id: 'BookingDatesForm.bookingEndTitle' });
            const requiredMessage = intl.formatMessage({ id: 'BookingDatesForm.requiredDate' });
            const startDateErrorMessage = intl.formatMessage({
              id: 'FieldDateRangeInput.invalidStartDate',
            });
            const endDateErrorMessage = intl.formatMessage({
              id: 'FieldDateRangeInput.invalidEndDate',
            });
            const timeSlotsError = fetchTimeSlotsError ? (
              <p className={css.timeSlotsError}>
                <FormattedMessage id="BookingDatesForm.timeSlotsError" />
              </p>
            ) : null;
  
            // This is the place to collect breakdown estimation data. See the
            // EstimatedBreakdownMaybe component to change the calculations
            // for customized payment processes.
            const bookingData =
              startDate && endDate && startTime && endTime
                ? {
                    unitType,
                    unitPrice,
                    startDate,
                    endDate,
                    startTime,
                    endTime,
  
                    // NOTE: If unitType is `line-item/units`, a new picker
                    // for the quantity should be added to the form.
                    quantity: 1,
                    saleOfOnMonday: publicData.saleOfOnMonday,
                  }
                : null;
            const bookingInfo = bookingData ? (
              <div className={css.priceBreakdownContainer}>
                <h3 className={css.priceBreakdownTitle}>
                  <FormattedMessage id="BookingDatesForm.priceBreakdownTitle" />
                </h3>
                <EstimatedBreakdownMaybe bookingData={bookingData}/>
              </div>
            ) : null;
  
            const dateFormatOptions = {
              weekday: 'short',
              month: 'short',
              day: 'numeric',
            };
  
            const now = moment();
            const today = now.startOf('day').toDate();
            const tomorrow = now
              .startOf('day')
              .add(1, 'days')
              .toDate();
            const startDatePlaceholderText =
              startDatePlaceholder || intl.formatDate(today, dateFormatOptions);
            const endDatePlaceholderText =
              endDatePlaceholder || intl.formatDate(tomorrow, dateFormatOptions);
            const submitButtonClasses = classNames(
              submitButtonWrapperClassName || css.submitButtonWrapper
            );
  
            return (
              <Form onSubmit={handleSubmit} className={classes}>
                {timeSlotsError}
                <FieldDateRangeInput
                  className={css.bookingDates}
                  name="bookingDates"
                  unitType={unitType}
                  startDateId={`${formId}.bookingStartDate`}
                  startDateLabel={bookingStartLabel}
                  startDatePlaceholderText={startDatePlaceholderText}
                  endDateId={`${formId}.bookingEndDate`}
                  endDateLabel={bookingEndLabel}
                  endDatePlaceholderText={endDatePlaceholderText}
                  focusedInput={this.state.focusedInput}
                  onFocusedInputChange={this.onFocusedInputChange}
                  format={identity}
                  timeSlots={timeSlots}
                  useMobileMargins
                  validate={composeValidators(
                    required(requiredMessage),
                    bookingDatesRequired(startDateErrorMessage, endDateErrorMessage)
                  )}
                />
                <FieldTimeRangeInput 
                  className={css.bookingTimes}
                  name="bookingTimes"
                  startTime={startTime}
                  endTime={endTime}
                  startDate={startDate}
                  endDate={endDate}
                  form={form}
                />
                {bookingInfo}
                <p className={css.smallPrint}>
                  <FormattedMessage
                    id={
                      isOwnListing
                        ? 'BookingDatesForm.ownListing'
                        : 'BookingDatesForm.youWontBeChargedInfo'
                    }
                  />
                </p>
                <div className={submitButtonClasses}>
                  <PrimaryButton type="submit">
                    <FormattedMessage id="BookingDatesForm.requestToBook" />
                  </PrimaryButton>
                </div>
              </Form>
            );
          }}
        />
      );
    }
  }
  
  BookingDatesFormComponent.defaultProps = {
    rootClassName: null,
    className: null,
    submitButtonWrapperClassName: null,
    price: null,
    isOwnListing: false,
    startDatePlaceholder: null,
    endDatePlaceholder: null,
    timeSlots: null,
  };
  
  BookingDatesFormComponent.propTypes = {
    rootClassName: string,
    className: string,
    submitButtonWrapperClassName: string,
  
    unitType: propTypes.bookingUnitType.isRequired,
    price: propTypes.money,
    isOwnListing: bool,
    timeSlots: arrayOf(propTypes.timeSlot),
  
    // from injectIntl
    intl: intlShape.isRequired,
  
    // for tests
    startDatePlaceholder: string,
    endDatePlaceholder: string,
  };
  
  const BookingDatesForm = compose(injectIntl)(BookingDatesFormComponent);
  BookingDatesForm.displayName = 'BookingDatesForm';
  
  export default BookingDatesForm;
  