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

import type { BaseSyntheticEvent, PropsWithChildren, ReactNode, JSX } from 'react';
import type { AccordionHeaderProps } from '@redocly/theme/components/Accordion/AccordionHeader';

import { AccordionBody } from '@redocly/theme/components/Accordion/AccordionBody';
import { AccordionHeader } from '@redocly/theme/components/Accordion/AccordionHeader';
import { AccordionTitle } from '@redocly/theme/components/Accordion/AccordionTitle';
import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon';
import { ChevronRightIcon } from '@redocly/theme/icons/ChevronRightIcon/ChevronRightIcon';

export type AccordionProps = {
  expanded?: boolean;
  isExpandable?: boolean;
  className?: string;
  renderChildrenHidden?: boolean;
  header?: ReactNode | ((props: AccordionHeaderProps) => ReactNode);
  onToggle?: (expanded: boolean) => void;
  dataTestId?: string;
};

export function Accordion({
  expanded = true,
  isExpandable = true,
  renderChildrenHidden = false,
  header,
  className,
  children,
  onToggle,
  dataTestId,
}: PropsWithChildren<AccordionProps>): JSX.Element {
  const [isExpanded, setExpanded] = useState(expanded);
  const [animate, setAnimate] = useState(false);

  const toggle = ({ target }: BaseSyntheticEvent): void => {
    if (target instanceof HTMLAnchorElement || !isExpandable) return;
    setAnimate(true);
    setExpanded(!isExpanded);
    onToggle?.(!isExpanded);
  };

  useEffect(() => setExpanded(expanded), [expanded]);

  return (
    <AccordionWrapper
      className={className}
      data-testid={dataTestId}
      data-component-name="Accordion/Accordion"
    >
      {header &&
        (typeof header === 'function' ? (
          header({ expanded: isExpanded })
        ) : (
          <AccordionHeader
            data-testid="accordion-header"
            onClick={toggle}
            expanded={isExpanded}
            isExpandable={isExpandable}
          >
            <HeaderContent>
              <AccordionTitle data-testid="title">{header}</AccordionTitle>
              {isExpandable &&
                (isExpanded ? (
                  <ChevronDownIcon color="--accordion-chevron-icon-color" />
                ) : (
                  <ChevronRightIcon color="--accordion-chevron-icon-color" />
                ))}
            </HeaderContent>
          </AccordionHeader>
        ))}

      {(isExpanded || renderChildrenHidden) && (
        <AccordionBody data-testid="accordion-body" hidden={!isExpanded} animate={animate}>
          {children}
        </AccordionBody>
      )}
    </AccordionWrapper>
  );
}

const AccordionWrapper = styled.div`
  background-color: transparent;
  font-family: var(--accordion-font-family);
  font-size: var(--accordion-font-size);
  font-weight: var(--accordion-font-weight);
  border-radius: var(--accordion-border-radius);
  border: var(--accordion-border);

  &:not(:last-child) {
    margin-bottom: var(--accordion-gap);
  }
`;

const HeaderContent = styled.div`
  display: flex;
  align-items: center;
  width: 100%;
  gap: var(--spacing-xs);
`;
