/* eslint-disable react/forbid-prop-types */
import { Fragment } from 'react';
import PropTypes from 'prop-types';
import groupBy from 'lodash/groupBy';
import useDateFormat from "../../../hooks/useDateFormat/index.js";
import customizable from "../../../utils/css/customizable.js";
import CommaAnd from "../CommaAnd/index.js";
import getMarginClasses from "../../../utils/css/getMarginClasses.js";
import { useResponsiveValues } from "../../../hooks/breakpoint/index.js";
import CustomPropTypes from "../../../utils/prop-types/index.js";
import cx from "../../../utils/css/cx.js";
import Name from './Name';
import classes from './styles.module.scss';
const cls = cx.merge(classes, {
  customizable: ['Byline', 'Byline__group', 'Byline__published', 'Byline__updated']
});

/**
 * Render a standard POLITICO byline.
 */
const Byline = function Byline(props) {
  const {
    authors,
    published,
    updated,
    nameAs: NameTag,
    separator,
    dateFormat,
    textAlign,
    layout,
    margin
  } = props;
  const publishedFormat = useDateFormat(published, {
    format: dateFormat
  });
  const publishedISO = useDateFormat(published, {
    format: 'iso'
  });
  const updatedFormat = useDateFormat(updated, {
    format: dateFormat
  });
  const updatedISO = useDateFormat(updated, {
    format: 'iso'
  });
  const bylines = groupBy(authors, d => d.by || 'By');
  const showUpdated = new Date(published) < new Date(updated);
  const hasTimes = !!published || showUpdated;
  const marginValue = useResponsiveValues(margin);
  const margins = getMarginClasses(marginValue, {
    defaultSide: 'y',
    sides: ['y', 't', 'b']
  });
  return <div className={cls(customizable('Byline'), 'container', `text-align-${textAlign}`, `layout-${layout}`, margins)}>
      <div className={classes.bylines}>
        {Object.entries(bylines).map(([by, names]) => <Fragment key={by}>
            <div key={by} className={cls(customizable('Byline__group'), 'byline')}>
              {by}
              {' '}
              <CommaAnd items={names.map(name => <NameTag name={name} />)} />
            </div>
            {hasTimes && layout === 'inline' && <>
                {' '}
                {separator}
                {' '}
              </>}
          </Fragment>)}
      </div>

      <div className={classes.times}>
        {published && <span className={cls(customizable('Byline__published'))}>
            <time className={cls('timestamp')} dateTime={publishedISO}>
              {publishedFormat}
            </time>
          </span>}

        {published && updated && showUpdated && <>
            {' '}
            {separator}
            {' '}
          </>}

        {updated && showUpdated && <span className={cls(customizable('Byline__updated'))}>
            Updated
            {' '}
            <time className={cls('timestamp')} dateTime={updatedISO}>
              {updatedFormat}
            </time>
          </span>}
      </div>
    </div>;
};
Byline.defaultProps = {
  published: undefined,
  updated: undefined,
  nameAs: Name,
  dateFormat: 'politico',
  separator: '|',
  layout: 'stacked',
  textAlign: 'left',
  margin: undefined
};
Byline.propTypes = {
  authors: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.shape({
    name: PropTypes.string,
    by: PropTypes.string,
    tagline: PropTypes.string
  }), PropTypes.any])).isRequired,
  published: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]),
  updated: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]),
  dateFormat: PropTypes.string,
  separator: PropTypes.node,
  nameAs: PropTypes.elementType,
  layout: PropTypes.oneOf(['stacked', 'inline']),
  textAlign: PropTypes.oneOf(['left', 'center', 'right']),
  /**
   * The vertical margins of the Byline. Margins can be specified as one
   * spacing value that gets used on both top and bottom, an explicit `y`
   * value, or completely separate `tb` values. The values correspond to levels
   * of our spacing scale (e.g., `"4"` corresponds to `$spacing-4`). Note that
   * `Byline` do not support custom horizontal margins.
   */
  margin: CustomPropTypes.responsive(PropTypes.oneOfType([PropTypes.string, PropTypes.shape({
    y: PropTypes.string
  }), PropTypes.shape({
    t: PropTypes.string,
    b: PropTypes.string
  })]))
};
export default Byline;