import { forwardRef, useRef, useState } from 'react';

import { Container, ContainerRef } from '@cleartrip/ct-design-container';
import useIsomorphicEffect from '@cleartrip/ct-design-use-isomorphic-effect';
import { useStyles, useWebMergeStyles } from '@cleartrip/ct-design-style-manager';

import type { IAccordionProps } from './type';
import staticStyles from './style';
import webStaticStyles from './webStyle';

const Accordion = forwardRef<ContainerRef, IAccordionProps>(
  (
    {
      expanded = false,
      label,
      onClick,
      children,
      expandIcon,
      disabled = false,
      styleConfig,
      isWrappedInAccordionGroup = false,
      onAccordionGroupClick,
    },
    forwardedRef,
  ) => {
    const { childrenContainer = [], icon = [], label: labelStyle = [], root = [] } = styleConfig || {};

    const [isExpanded, setIsExpanded] = useState<boolean>(expanded);
    const accordionContentRef = useRef<HTMLDivElement>(null);

    useIsomorphicEffect(() => {
      setIsExpanded(expanded);
    }, [expanded]);

    const onAccordionClick = () => {
      if (disabled) return;

      if (isWrappedInAccordionGroup) {
        onAccordionGroupClick?.();
      } else {
        setIsExpanded((previouslyExpanded) => !previouslyExpanded);
      }
      onClick?.();
    };

    // Dynamic styles that depend on `isExpanded`/`disabled` and the measured
    // scroll height of the collapsible content.
    const dynamicStyles = useStyles(() => {
      const contentScrollHeight = accordionContentRef.current?.scrollHeight ?? 0;
      return {
        labelRow: {
          // cursor: disabled ? 'not-allowed' : 'pointer',
        },
        iconTransform: {
          transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)',
        },
        contentMaxHeight: {
          maxHeight: isExpanded ? contentScrollHeight : 0,
        },
      };
    }, [isExpanded, disabled]);

    const mergedIconClassName = useWebMergeStyles(
      [staticStyles.iconContainer, webStaticStyles.iconTransition, dynamicStyles.iconTransform, ...icon],
      [staticStyles.iconContainer, dynamicStyles.iconTransform, icon],
    );

    const mergedContentClassName = useWebMergeStyles(
      [
        staticStyles.accordionContentRoot,
        webStaticStyles.contentTransition,
        dynamicStyles.contentMaxHeight,
        ...childrenContainer,
      ],
      [staticStyles.accordionContentRoot, dynamicStyles.contentMaxHeight, childrenContainer],
    );

    return (
      <Container styleConfig={{ root }}>
        <Container
          ref={forwardedRef}
          onClick={onAccordionClick}
          styleConfig={{ root: [staticStyles.labelRow, dynamicStyles.labelRow, ...labelStyle] }}
        >
          {label}
          {expandIcon && <div className={mergedIconClassName}>{expandIcon}</div>}
        </Container>
        <div ref={accordionContentRef} className={mergedContentClassName}>
          {children}
        </div>
      </Container>
    );
  },
);

Accordion.displayName = 'Accordion';
export default Accordion;
