import React from 'react';
import styled, { css } from 'styled-components';

import type { FC, JSX } from 'react';

import { WarningCycleIcon } from '@redocly/theme/icons/WarningCycleIcon/WarningCycleIcon';
import { CheckmarkOutlineIcon } from '@redocly/theme/icons/CheckmarkOutlineIcon/CheckmarkOutlineIcon';
import { ErrorIcon } from '@redocly/theme/icons/ErrorIcon/ErrorIcon';
import { InformationIcon } from '@redocly/theme/icons/InformationIcon/InformationIcon';
import { IdeaIcon } from '@redocly/theme/icons/IdeaIcon/IdeaIcon';

type AdmonitionTypeProps = {
  type: 'warning' | 'success' | 'danger' | 'info' | 'default';
};

export type AdmonitionProps = Partial<AdmonitionTypeProps> & {
  name?: string;
  className?: string;
  'data-source'?: string;
  'data-hash'?: string;
};

const IconsMap: Record<AdmonitionTypeProps['type'], FC<{ color?: string }>> = {
  warning: WarningCycleIcon,
  success: CheckmarkOutlineIcon,
  danger: ErrorIcon,
  info: InformationIcon,
  default: IdeaIcon,
};

export function Admonition({
  type = 'info',
  name,
  children,
  className,
  'data-source': dataSource,
  'data-hash': dataHash,
}: React.PropsWithChildren<AdmonitionProps>): JSX.Element {
  const Icon = IconsMap[type] || IconsMap['info'];
  return (
    <AdmonitionWrapper
      type={type}
      className={className}
      data-component-name="Admonition/Admonition"
      data-source={dataSource}
      data-hash={dataHash}
    >
      <Icon color={`--admonition-${type}-icon-color`} />
      <TextContainer>
        {name ? <Heading type={type}>{name}</Heading> : null}
        {children ? <Content>{children}</Content> : null}
      </TextContainer>
    </AdmonitionWrapper>
  );
}

const Content = styled.div`
  & > p:first-child {
    margin-top: 0;
  }

  & > p:last-child {
    margin-bottom: 0;
  }
`;

const AdmonitionWrapper = styled.div<AdmonitionTypeProps>`
  display: flex;
  flex-direction: row;
  gap: var(--admonition-gap);
  margin: var(--admonition-margin);
  padding: var(--admonition-padding);
  border-radius: var(--admonition-border-radius);
  font-size: var(--admonition-font-size);
  font-weight: var(--admonition-font-weight);
  line-height: var(--admonition-line-height);

  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;

  ${({ type }) => css`
    background-color: var(--admonition-${type}-bg-color);
    color: var(--admonition-${type}-text-color);
    border: var(--admonition-${type}-border);
  `};

  &:not(:has(${Content})) {
    --admonition-heading-font-size: var(--admonition-font-size);
    --admonition-heading-line-height: var(--admonition-line-height);

    align-items: center;
    gap: calc(var(--spacing-xxs) * 1.5);
  }

  svg {
    width: var(--admonition-icon-size);
    height: var(--admonition-icon-size);
    flex-shrink: 0;
    margin: var(--admonition-icon-margin);

    fill: ${({ type }) => `var(--admonition-${type}-icon-color)`};

    background-image: ${({ type }) => `var(--admonition-${type}-icon)`};
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
  }
`;

const TextContainer = styled.div`
  display: flex;
  flex-direction: column;
  gap: var(--admonition-text-gap);
  width: 100%;
`;

const Heading = styled.div<AdmonitionTypeProps>`
  letter-spacing: var(--admonition-heading-letter-spacing);
  color: ${({ type }) => `var(--admonition-${type}-heading-text-color)`};

  && {
    font-size: var(--admonition-heading-font-size);
    font-weight: var(--admonition-heading-font-weight);
    line-height: var(--admonition-heading-line-height);
    text-transform: var(--admonition-heading-transform);
  }
`;
