import React, { ReactNode, ReactElement, useState } from 'react';
import css from '../../utils/css';

import Editor from './Editor';
import { CommonProps } from '../common';
import {
  Avatar,
  AuthorWrapper,
  Author,
  AuthorDetails,
  TimeWrapper,
  TimeSeparator,
  ContentWrapper,
  CommentWrapper,
  ContentDetail,
  ActionsWrapper,
  ReactionsWrapper,
  CommentInner,
  NestedCommentWrapper,
} from './StyledComment';

export interface CommentProps extends CommonProps {
  /**
   * Custom actions for the comment, eg. Edit, Share, Copy.
   */
  actions?: ReactElement;
  /**
   * Whether to always show actions or on hover only.
   */
  alwaysShowActions?: boolean;
  /**
   * Author text.
   */
  author: string;
  /**
   * Details about author.
   */
  authorDetails?: string;
  /**
   * Author avatar.
   */
  avatar?: string | ReactElement;
  /**
   * Nested comments should be provided as children of the Comment.
   */
  children?: ReactNode;
  /**
   * The main content of the comment.
   */
  content: string | ReactElement;
  /**
   * A datetime element containing the time to be displayed.
   */
  datetime?: string;
  /**
   * Custom reaction section for the comment.
   */
  reactions?: ReactElement;
}

const Comment = ({
  avatar,
  author,
  authorDetails,
  datetime,
  content,
  children,
  actions,
  reactions,
  alwaysShowActions = false,
  id,
  className,
  style,
  sx = {},
  'data-test-id': dataTestId,
}: CommentProps): ReactElement => {
  const [actionsShown, setActionsShown] = useState<boolean>(false);

  const renderNestedComments = (nestedChildren: ReactNode): ReactElement => {
    return <NestedCommentWrapper>{nestedChildren}</NestedCommentWrapper>;
  };

  const avatarElement = avatar !== undefined && (
    <Avatar>
      {typeof avatar === 'string' ? (
        <img src={avatar} alt="comment-avatar" />
      ) : (
        avatar
      )}
    </Avatar>
  );

  const authorElement = (
    <AuthorWrapper>
      <Author>
        {author}
        {datetime !== undefined && (
          <TimeWrapper>
            <TimeSeparator>-</TimeSeparator>
            {datetime}
          </TimeWrapper>
        )}
      </Author>
      {authorDetails !== undefined && (
        <AuthorDetails>{authorDetails}</AuthorDetails>
      )}
    </AuthorWrapper>
  );

  const contentElement = (
    <ContentWrapper>
      {authorElement}
      <ContentDetail>{content}</ContentDetail>
      {actions !== undefined && (
        <ActionsWrapper themeShown={alwaysShowActions || actionsShown}>
          {actions}
        </ActionsWrapper>
      )}
      {reactions !== undefined && (
        <ReactionsWrapper>{reactions}</ReactionsWrapper>
      )}
    </ContentWrapper>
  );

  return (
    <CommentWrapper
      id={id}
      className={className}
      style={{ ...style, ...css(sx) }}
      data-test-id={dataTestId}
    >
      <CommentInner
        data-test-id="inner-comment"
        onMouseEnter={(): void => setActionsShown(true)}
        onMouseLeave={(): void => setActionsShown(false)}
      >
        {avatarElement}
        {contentElement}
      </CommentInner>
      {children !== undefined ? renderNestedComments(children) : null}
    </CommentWrapper>
  );
};

Comment.Editor = Editor;

export default Comment;
