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

import type { FC } from 'react';

import { WarningFilledIcon } from '@redocly/theme/icons/WarningFilledIcon/WarningFilledIcon';
import { CheckmarkFilledIcon } from '@redocly/theme/icons/CheckmarkFilledIcon/CheckmarkFilledIcon';
import { CloseFilledIcon } from '@redocly/theme/icons/CloseFilledIcon/CloseFilledIcon';
import { InformationFilledIcon } from '@redocly/theme/icons/InformationFilledIcon/InformationFilledIcon';

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

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

const IconsMap: Record<AdmonitionTypeProps['type'], FC<{ color?: string }>> = {
  warning: WarningFilledIcon,
  success: CheckmarkFilledIcon,
  danger: CloseFilledIcon,
  info: InformationFilledIcon,
};

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;
  }
`;

const AdmonitionWrapper = styled.div<AdmonitionTypeProps>`
  display: flex;
  flex-direction: row;
  gap: var(--spacing-base);
  margin: var(--admonition-margin-vertical) var(--admonition-margin-horizontal);
  padding: var(--admonition-padding-vertical-xs) var(--admonition-padding-horizontal);
  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-left: var(--admonition-${type}-border);
  `};

  &:has(${Content}) {
    padding: var(--admonition-padding-vertical-md) var(--admonition-padding-horizontal);
  }

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

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

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

    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(--spacing-unit);
  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);
  }
`;
