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

import type { BaseSyntheticEvent, PropsWithChildren, ReactNode, JSX } from 'react';
import type { PanelHeaderProps } from '@redocly/theme/components/Panel/PanelHeader';

import { PanelBody } from '@redocly/theme/components/Panel/PanelBody';
import { PanelHeader } from '@redocly/theme/components/Panel/PanelHeader';
import { PanelHeaderTitle } from '@redocly/theme/components/Panel/PanelHeaderTitle';
import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon';
import { ChevronRightIcon } from '@redocly/theme/icons/ChevronRightIcon/ChevronRightIcon';

export type PanelProps = {
  expanded?: boolean;
  isExpandable?: boolean;
  className?: string;
  renderChildrenHidden?: boolean;
  header?: ReactNode | ((props: PanelHeaderProps) => ReactNode);
  footer?: ReactNode;
  onToggle?: (expanded: boolean) => void;
  description?: React.ReactNode;
};

export function Panel({
  expanded = true,
  isExpandable = true,
  renderChildrenHidden = false,
  header,
  footer,
  className = 'panel-default',
  children,
  onToggle,
  description,
}: PropsWithChildren<PanelProps>): 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 (
    <PanelWrapper
      className={className}
      data-testid={
        typeof header === 'string' ? ('panel-' + header).replace(/ /g, '-').toLowerCase() : null
      }
      data-component-name="Panel/Panel"
    >
      {header &&
        (typeof header === 'function' ? (
          header({ expanded: isExpanded, toggle })
        ) : (
          <PanelHeader
            data-testid="panel-header"
            onClick={toggle}
            expanded={isExpanded}
            isExpandable={isExpandable}
          >
            <InlineBox>
              <PanelHeaderTitle data-testid="title">{header}</PanelHeaderTitle>
              {isExpandable &&
                (isExpanded ? (
                  <ChevronDownIcon color="--panel-chevron-icon-color" />
                ) : (
                  <ChevronRightIcon color="--panel-chevron-icon-color" />
                ))}
              {description}
            </InlineBox>
          </PanelHeader>
        ))}

      {(isExpanded || renderChildrenHidden) && (
        <PanelBody data-testid="panel-body" hidden={!isExpanded} animate={animate}>
          {children}
        </PanelBody>
      )}

      {footer}
    </PanelWrapper>
  );
}

const PanelWrapper = styled.div`
  background-color: var(--panel-bg-color);
  color: var(--panel-text-color);
  font-family: var(--panel-font-family-local);
  font-size: var(--panel-font-size-local);
  font-weight: var(--panel-font-weight-local);
  border-radius: var(--panel-border-radius-local);
  border: var(--panel-border-local);

  ${PanelHeader} + ${PanelBody} {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
  }

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

const InlineBox = styled.div`
  display: inline-flex;
  align-items: center;
`;
