text: import React from 'react';
  import PropTypes from 'prop-types';
  import { compose } from 'redux';
  import { withRouter } from 'react-router-dom';
  import { FormattedMessage, intlShape, injectIntl } from '../../util/reactIntl';
  import classNames from 'classnames';
  import routeConfiguration from '../../routeConfiguration';
  import {
    LINE_ITEM_NIGHT,
    LINE_ITEM_DAY,
    LISTING_STATE_PENDING_APPROVAL,
    LISTING_STATE_CLOSED,
    LISTING_STATE_DRAFT,
    propTypes,
  } from '../../util/types';
  import { formatMoney } from '../../util/currency';
  import { ensureOwnListing } from '../../util/data';
  import {
    LISTING_PAGE_PENDING_APPROVAL_VARIANT,
    LISTING_PAGE_DRAFT_VARIANT,
    LISTING_PAGE_PARAM_TYPE_DRAFT,
    LISTING_PAGE_PARAM_TYPE_EDIT,
    createSlug,
  } from '../../util/urlHelpers';
  import { createResourceLocatorString } from '../../util/routes';
  import config from '../../config';
  import {
    InlineTextButton,
    Menu,
    MenuLabel,
    MenuContent,
    MenuItem,
    NamedLink,
    IconSpinner,
    ResponsiveImage,
  } from '../../components';
  
  import MenuIcon from './MenuIcon';
  import Overlay from './Overlay';
  import css from './ManageListingCard.css';
  
  // Menu content needs the same padding
  const MENU_CONTENT_OFFSET = -12;
  const MAX_LENGTH_FOR_WORDS_IN_TITLE = 7;
  
  const priceData = (price, intl) => {
    if (price && price.currency === config.currency) {
      const formattedPrice = formatMoney(intl, price);
      return { formattedPrice, priceTitle: formattedPrice };
    } else if (price) {
      return {
        formattedPrice: intl.formatMessage(
          { id: 'ManageListingCard.unsupportedPrice' },
          { currency: price.currency }
        ),
        priceTitle: intl.formatMessage(
          { id: 'ManageListingCard.unsupportedPriceTitle' },
          { currency: price.currency }
        ),
      };
    }
    return {};
  };
  
  const createListingURL = (routes, listing) => {
    const id = listing.id.uuid;
    const slug = createSlug(listing.attributes.title);
    const isPendingApproval = listing.attributes.state === LISTING_STATE_PENDING_APPROVAL;
    const isDraft = listing.attributes.state === LISTING_STATE_DRAFT;
    const variant = isDraft
      ? LISTING_PAGE_DRAFT_VARIANT
      : isPendingApproval
      ? LISTING_PAGE_PENDING_APPROVAL_VARIANT
      : null;
  
    const linkProps =
      isPendingApproval || isDraft
        ? {
            name: 'ListingPageVariant',
            params: {
              id,
              slug,
              variant,
            },
          }
        : {
            name: 'ListingPage',
            params: { id, slug },
          };
  
    return createResourceLocatorString(linkProps.name, routes, linkProps.params, {});
  };
  
  // Cards are not fixed sizes - So, long words in title make flexboxed items to grow too big.
  // 1. We split title to an array of words and spaces.
  //    "foo bar".split(/([^\s]+)/gi) => ["", "foo", " ", "bar", ""]
  // 2. Then we break long words by adding a '<span>' with word-break: 'break-all';
  const formatTitle = (title, maxLength) => {
    const nonWhiteSpaceSequence = /([^\s]+)/gi;
    return title.split(nonWhiteSpaceSequence).map((word, index) => {
      return word.length > maxLength ? (
        <span key={index} style={{ wordBreak: 'break-all' }}>
          {word}
        </span>
      ) : (
        word
      );
    });
  };
  
  export const ManageListingCardComponent = props => {
    const {
      className,
      rootClassName,
      hasClosingError,
      hasOpeningError,
      history,
      intl,
      isMenuOpen,
      actionsInProgressListingId,
      listing,
      onCloseListing,
      onOpenListing,
      onToggleMenu,
      renderSizes,
      availabilityEnabled,
    } = props;
    const classes = classNames(rootClassName || css.root, className);
    const currentListing = ensureOwnListing(listing);
    const id = currentListing.id.uuid;
    const { title = '', price, state } = currentListing.attributes;
    const slug = createSlug(title);
    const isPendingApproval = state === LISTING_STATE_PENDING_APPROVAL;
    const isClosed = state === LISTING_STATE_CLOSED;
    const isDraft = state === LISTING_STATE_DRAFT;
    const firstImage =
      currentListing.images && currentListing.images.length > 0 ? currentListing.images[0] : null;
  
    const menuItemClasses = classNames(css.menuItem, {
      [css.menuItemDisabled]: !!actionsInProgressListingId,
    });
  
    const { formattedPrice, priceTitle } = priceData(price, intl);
  
    const hasError = hasOpeningError || hasClosingError;
    const thisListingInProgress =
      actionsInProgressListingId && actionsInProgressListingId.uuid === id;
  
    const titleClasses = classNames(css.title, {
      [css.titlePending]: isPendingApproval,
      [css.titleDraft]: isDraft,
    });
  
    const editListingLinkType = isDraft
      ? LISTING_PAGE_PARAM_TYPE_DRAFT
      : LISTING_PAGE_PARAM_TYPE_EDIT;
  
    const unitType = config.bookingUnitType;
    const isNightly = unitType === LINE_ITEM_NIGHT;
    const isDaily = unitType === LINE_ITEM_DAY;
  
    const unitTranslationKey = isNightly
      ? 'ManageListingCard.perNight'
      : isDaily
      ? 'ManageListingCard.perDay'
      : 'ManageListingCard.perUnit';
  
    return (
      <div className={classes}>
        <div
          className={css.threeToTwoWrapper}
          tabIndex={0}
          onClick={event => {
            event.preventDefault();
            event.stopPropagation();
  
            // ManageListingCard contains links, buttons and elements that are working with routing.
            // This card doesn't work if <a> or <button> is used to wrap events that are card 'clicks'.
            //
            // NOTE: It might be better to absolute-position those buttons over a card-links.
            // (So, that they have no parent-child relationship - like '<a>bla<a>blaa</a></a>')
            history.push(createListingURL(routeConfiguration(), listing));
          }}
        >
          <div className={css.aspectWrapper}>
            <ResponsiveImage
              rootClassName={css.rootForImage}
              alt={title}
              image={firstImage}
              variants={['landscape-crop', 'landscape-crop2x']}
              sizes={renderSizes}
            />
          </div>
          <div className={classNames(css.menuOverlayWrapper, { [css.menuOverlayOpen]: isMenuOpen })}>
            <div className={classNames(css.menuOverlay)} />
            <div className={css.menuOverlayContent}>
              <FormattedMessage id="ManageListingCard.viewListing" />
            </div>
          </div>
          <div className={css.menubarWrapper}>
            <div className={css.menubarGradient} />
            <div className={css.menubar}>
              <Menu
                className={classNames(css.menu, { [css.cardIsOpen]: !isClosed })}
                contentPlacementOffset={MENU_CONTENT_OFFSET}
                contentPosition="left"
                useArrow={false}
                onToggleActive={isOpen => {
                  const listingOpen = isOpen ? currentListing : null;
                  onToggleMenu(listingOpen);
                }}
                isOpen={isMenuOpen}
              >
                <MenuLabel className={css.menuLabel} isOpenClassName={css.listingMenuIsOpen}>
                  <div className={css.iconWrapper}>
                    <MenuIcon className={css.menuIcon} isActive={isMenuOpen} />
                  </div>
                </MenuLabel>
                <MenuContent rootClassName={css.menuContent}>
                  <MenuItem key="close-listing">
                    <InlineTextButton
                      rootClassName={menuItemClasses}
                      onClick={event => {
                        event.preventDefault();
                        event.stopPropagation();
                        if (!actionsInProgressListingId) {
                          onToggleMenu(null);
                          onCloseListing(currentListing.id);
                        }
                      }}
                    >
                      <FormattedMessage id="ManageListingCard.closeListing" />
                    </InlineTextButton>
                  </MenuItem>
                </MenuContent>
              </Menu>
            </div>
          </div>
          {isDraft ? (
            <React.Fragment>
              <div className={classNames({ [css.draftNoImage]: !firstImage })} />
              <Overlay
                message={intl.formatMessage(
                  { id: 'ManageListingCard.draftOverlayText' },
                  { listingTitle: title }
                )}
              >
                <NamedLink
                  className={css.finishListingDraftLink}
                  name="EditListingPage"
                  params={{ id, slug, type: LISTING_PAGE_PARAM_TYPE_DRAFT, tab: 'photos' }}
                >
                  <FormattedMessage id="ManageListingCard.finishListingDraft" />
                </NamedLink>
              </Overlay>
            </React.Fragment>
          ) : null}
          {isClosed ? (
            <Overlay
              message={intl.formatMessage(
                { id: 'ManageListingCard.closedListing' },
                { listingTitle: title }
              )}
            >
              {
                currentListing.attributes.metadata.sold ? (
                  <FormattedMessage id="ManageListingCard.ListingSold"/>
                ):(
                <button
                  className={css.openListingButton}
                  disabled={!!actionsInProgressListingId}
                  onClick={event => {
                    event.preventDefault();
                    event.stopPropagation();
                    if (!actionsInProgressListingId) {
                      onOpenListing(currentListing.id);
                    }
                  }}
                >
  
                  <FormattedMessage id="ManageListingCard.openListing"/>
                </button>
                )
              }
            </Overlay>
          ) : null}
          {isPendingApproval ? (
            <Overlay
              message={intl.formatMessage(
                { id: 'ManageListingCard.pendingApproval' },
                { listingTitle: title }
              )}
            />
          ) : null}
          {thisListingInProgress ? (
            <Overlay>
              <IconSpinner />
            </Overlay>
          ) : hasError ? (
            <Overlay errorMessage={intl.formatMessage({ id: 'ManageListingCard.actionFailed' })} />
          ) : null}
        </div>
  
        <div className={css.info}>
          <div className={css.price}>
            {formattedPrice ? (
              <React.Fragment>
                <div className={css.priceValue} title={priceTitle}>
                  {formattedPrice}
                </div>
                <div className={css.perUnit}>
                  <FormattedMessage id={unitTranslationKey} />
                </div>
              </React.Fragment>
            ) : (
              <div className={css.noPrice}>
                <FormattedMessage id="ManageListingCard.priceNotSet" />
              </div>
            )}
          </div>
  
          <div className={css.mainInfo}>
            <div className={css.titleWrapper}>
              <InlineTextButton
                rootClassName={titleClasses}
                onClick={event => {
                  event.preventDefault();
                  event.stopPropagation();
                  history.push(createListingURL(routeConfiguration(), listing));
                }}
              >
                {formatTitle(title, MAX_LENGTH_FOR_WORDS_IN_TITLE)}
              </InlineTextButton>
            </div>
          </div>
  
          <div className={css.manageLinks}>
            <NamedLink
              className={css.manageLink}
              name="EditListingPage"
              params={{ id, slug, type: editListingLinkType, tab: 'description' }}
            >
              <FormattedMessage id="ManageListingCard.editListing" />
            </NamedLink>
  
            {availabilityEnabled ? (
              <React.Fragment>
                <span className={css.manageLinksSeparator}>{' • '}</span>
  
                <NamedLink
                  className={css.manageLink}
                  name="EditListingPage"
                  params={{ id, slug, type: editListingLinkType, tab: 'availability' }}
                >
                  <FormattedMessage id="ManageListingCard.manageAvailability" />
                </NamedLink>
              </React.Fragment>
            ) : null}
          </div>
        </div>
      </div>
    );
  };
  
  ManageListingCardComponent.defaultProps = {
    className: null,
    rootClassName: null,
    actionsInProgressListingId: null,
    renderSizes: null,
    availabilityEnabled: config.enableAvailability,
  };
  
  const { bool, func, shape, string } = PropTypes;
  
  ManageListingCardComponent.propTypes = {
    className: string,
    rootClassName: string,
    hasClosingError: bool.isRequired,
    hasOpeningError: bool.isRequired,
    intl: intlShape.isRequired,
    listing: propTypes.ownListing.isRequired,
    isMenuOpen: bool.isRequired,
    actionsInProgressListingId: shape({ uuid: string.isRequired }),
    onCloseListing: func.isRequired,
    onOpenListing: func.isRequired,
    onToggleMenu: func.isRequired,
    availabilityEnabled: bool,
  
    // Responsive image sizes hint
    renderSizes: string,
  
    // from withRouter
    history: shape({
      push: func.isRequired,
    }).isRequired,
  };
  
  export default compose(
    withRouter,
    injectIntl
  )(ManageListingCardComponent);
  