import React, { forwardRef } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';

import { Icon } from '../icon/Icon';
import { Tooltip } from '../tooltip/Tooltip';
import { modifierCSS } from '../../../helpers';

const propTypes = {
  /**
   * The log line content.
   */
  children: PropTypes.node,
  /**
   * The className property allows you to add more classes to the component.
   */
  className: PropTypes.string,
  /**
   * The component default class.
   */
  defaultClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
  /**
   * Highlight the log line if true.
   */
  isHighlighted: PropTypes.bool,
  /**
   * The log line number.
   */
  number: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  /**
   * Function called when the user clicks on the log line number.
   */
  onNumberClick: PropTypes.func,
  /**
   * The stream to use for this log line. Can be stdout for standard output, or
   * stderr for standard error.
   */
  stream: PropTypes.oneOf(['stdout', 'stderr', 'orchestration_stdout', 'orchestration_stderr']),
  /**
   * The component used for the root node.
   * Either a string to use a DOM element or a component.
   */
  tag: PropTypes.elementType,
  /**
   * The time of the log, useful to give more information to the user.
   */
  time: PropTypes.string,
};

const defaultProps = {
  children: '',
  className: '',
  defaultClassName: 'sui-a-logline',
  isHighlighted: false,
  number: '',
  onNumberClick: undefined,
  stream: 'stdout',
  tag: 'div',
  time: '',
};

export const LogLine = forwardRef(({
  children,
  className,
  defaultClassName,
  isHighlighted,
  number,
  onNumberClick,
  stream,
  time,
  tag: Tag,
  ...props
}, ref) => {
  const classes = classnames(
    defaultClassName,
    modifierCSS(stream),
    {
      'as--highlighted': isHighlighted,
    },
    className
  );

  const buildLogLineNumber = () => {
    const logLineNumberClasses = classnames(
      'sui-a-logline__number',
      {
        'as--button': onNumberClick,
      }
    );

    if (!number) {
      return '';
    }

    const handleLogLineNumberClick = (e) => {
      if (onNumberClick) {
        onNumberClick(e);
      }
    };

    const extraButtonProps = onNumberClick ? {
      role: 'button',
      tabIndex: '0',
      onClick: handleLogLineNumberClick,
      onKeyPress: handleLogLineNumberClick,
    } : {};

    return (
      <div
        className={logLineNumberClasses}
        {...extraButtonProps}
        data-testid="sui-a-logline__number"
      >
        {number}
      </div>
    );
  };

  return (
    <Tag className={classes} ref={ref} {...props}>
      {/* ------------------------------------------------------------------ */}
      {/*
        Don't reorder the clock with the line number as everything is done
        through SCSS to apply a background trick on hover.
      */}
      {buildLogLineNumber()}
      {time && (
        <Tooltip defaultPlacement="left" label={time}>
          <div
            className="sui-a-logline__clock"
            data-testid="sui-a-logline__clock"
          >
            <Icon name="fa-clock-o" />
          </div>
        </Tooltip>
      )}
      {/* ------------------------------------------------------------------ */}

      <div className="sui-a-logline__content" data-testid="sui-a-logline__content">
        {children}
      </div>
    </Tag>
  );
});

LogLine.propTypes = propTypes;
LogLine.defaultProps = defaultProps;
