import React from 'react';
import styled from 'styled-components';

import { Link } from '@redocly/theme/components/Link/Link';
import { Tag } from '@redocly/theme/components/Tag/Tag';
import { AiSearchConversationRole } from '@redocly/theme/core/constants';
import { useThemeHooks } from '@redocly/theme/core/hooks';
import { Markdown } from '@redocly/theme/components/Markdown/Markdown';
import { DocumentIcon } from '@redocly/theme/icons/DocumentIcon/DocumentIcon';
import { AiStarsIcon } from '@redocly/theme/icons/AiStarsIcon/AiStarsIcon';

export type SearchAiMessageProps = {
  role: AiSearchConversationRole;
  content: string;
  isThinking?: boolean;
  resources?: {
    url: string;
    title: string;
  }[];
  className?: string;
};

export function SearchAiMessage({
  role,
  content,
  isThinking,
  resources,
  className,
}: SearchAiMessageProps): JSX.Element {
  const { useMarkdownText, useTranslate } = useThemeHooks();
  const markDownContent = useMarkdownText(content || '');
  const { translate } = useTranslate();

  return (
    <SearchAiMessageWrapper
      data-component-name="Search/SearchAiMessage"
      role={role}
      className={className}
      data-testid="search-ai-message"
    >
      {role === AiSearchConversationRole.ASSISTANT && (
        <AiStarsIcon
          size="32px"
          background="var(--search-ai-icon-bg-color)"
          borderRadius="var(--border-radius-lg)"
          color="var(--search-ai-icon-color)"
          margin="0 var(--spacing-xs) 0 0"
        />
      )}
      <MessageWrapper role={role}>
        {role === AiSearchConversationRole.ASSISTANT ? (
          <>
            <ResponseText as="div" children={markDownContent} data-testid="response-text" />
            {!isThinking && resources && resources.length > 0 && (
              <ResourcesWrapper data-testid="resources-wrapper">
                <ResourcesTitle data-translation-key="search.ai.resourcesFound">
                  {translate('search.ai.resourcesFound.basedOn', 'Based on')} {resources.length}{' '}
                  {translate('search.ai.resourcesFound.resources', 'resources')}
                </ResourcesTitle>
                <ResourceTagsWrapper>
                  {resources.map((resource, idx) => (
                    <Link key={idx} to={resource.url} target="_blank">
                      <ResourceTag
                        borderless
                        icon={<DocumentIcon color="--search-ai-resource-tag-icon-color" />}
                      >
                        {resource.title}
                      </ResourceTag>
                    </Link>
                  ))}
                </ResourceTagsWrapper>
              </ResourcesWrapper>
            )}
          </>
        ) : (
          content
        )}
        {isThinking && content.length === 0 && (
          <ThinkingDotsWrapper data-testid="thinking-dots-wrapper">
            <ThinkingDot />
            <ThinkingDot />
            <ThinkingDot />
          </ThinkingDotsWrapper>
        )}
      </MessageWrapper>
    </SearchAiMessageWrapper>
  );
}

const SearchAiMessageWrapper = styled.div<{ role: string }>`
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  width: 100%;
  justify-content: ${({ role }) =>
    role === AiSearchConversationRole.USER ? 'flex-end' : 'flex-start'};
`;

const ResponseText = styled(Markdown)`
  color: var(--search-ai-text-color);
  font-size: var(--search-ai-text-font-size);
  line-height: var(--search-ai-text-line-height);
  font-family: inherit;
  white-space: break-spaces;

  article {
    > *:first-child {
      margin-top: 0;
    }
    > *:last-child {
      margin-bottom: 0;
    }
  }
`;

const MessageWrapper = styled.div<{ role: string }>`
  padding: ${({ role }) =>
      role === AiSearchConversationRole.USER ? 'var(--spacing-sm)' : 'var(--spacing-xs)'}
    var(--spacing-sm);
  border-radius: var(--border-radius-lg);
  max-width: 80%;
  word-wrap: break-word;
  white-space: pre-wrap;
  background-color: ${({ role }) =>
    role === AiSearchConversationRole.USER
      ? 'var(--search-ai-user-bg-color)'
      : 'var(--search-ai-assistant-bg-color)'};
  border: ${({ role }) =>
    role === AiSearchConversationRole.USER ? 'none' : 'var(--search-ai-assistant-border)'};
  color: ${({ role }) =>
    role === AiSearchConversationRole.USER
      ? 'var(--search-ai-user-text-color)'
      : 'var(--search-ai-assistant-text-color)'};
`;

const ResourcesWrapper = styled.div`
  gap: var(--search-ai-resources-gap);
  display: flex;
  flex-direction: column;
  margin: var(--spacing-xs) 0;
`;

const ResourcesTitle = styled.div`
  font-weight: var(--search-ai-resources-title-font-weight);
  font-size: var(--search-ai-resources-title-font-size);
  line-height: var(--search-ai-resources-title-line-height);
`;

const ResourceTagsWrapper = styled.div`
  display: flex;
  flex-wrap: wrap;
  gap: var(--search-ai-resource-tags-gap);
`;

const ResourceTag = styled(Tag)`
  .tag-default {
    --tag-color: var(--search-ai-resource-tag-text-color);
    max-width: 100%;
    overflow: hidden;
    display: inline-block;
  }
  svg {
    min-width: var(--search-ai-resource-tag-icon-size);
    min-height: var(--search-ai-resource-tag-icon-size);
    flex-shrink: 0;
  }
  > div {
    overflow: hidden;
    word-break: break-word;
    white-space: normal;
    max-width: 100%;
  }
`;

const ThinkingDotsWrapper = styled.div`
  display: flex;
  gap: var(--search-ai-thinking-dots-gap);
  padding: var(--search-ai-thinking-dots-padding);
`;

const ThinkingDot = styled.div`
  width: var(--search-ai-thinking-dot-size);
  height: var(--search-ai-thinking-dot-size);
  border-radius: 50%;
  background: var(--search-ai-thinking-dot-color);
  animation: bounce 1.4s infinite ease-in-out;

  &:nth-child(1) {
    animation-delay: -0.32s;
  }
  &:nth-child(2) {
    animation-delay: -0.16s;
  }
  &:nth-child(3) {
    animation-delay: 0s;
  }

  @keyframes bounce {
    0%,
    80%,
    100% {
      opacity: 0.2;
      transform: scale(0.8);
    }
    40% {
      opacity: 1;
      transform: scale(1);
    }
  }
`;
