import React, { useCallback, useEffect, useState } from 'react'

import styles from './_accordion.module.scss'
import Checkbox from '../Form/Checkbox'
import Icon from '../Icons/Icon'

/** Currently, the only available option is 'faint-gray' as specified by UX. */
type AccordionBackgroundColors = 'faint-gray'

export type AccordionItemProps = {
  /** The main heading/title of the accordion item. Can be text or a React component */
  title: React.ReactNode
  /** Optional secondary text or component that appears below the title */
  subtitle?: React.ReactNode
  /** The content to be displayed when the accordion item is expanded */
  children: React.ReactNode
  /** Optional React elements for action buttons/elements (e.g., edit, delete buttons) */
  actions?: React.ReactNode
  /** Optional flag to disable the accordion item */
  disabled?: boolean
  /** Optionally set the state of the Accordion. If set to true the Accordion will be in Expanded state initially */
  isExpanded?: boolean
  /** Callout function to be called when the Accordion is expanded or collapsed. Receives a boolean indicating the state. */
  callout?: (isExpanded: boolean) => void
  /** Optionally pass a boolean to control the state of the radio button in left part of the Accordion Header.
   * If not passed, the radio button will be controlled by the expand/ collapse state.
   */
  checked?: boolean
  /** Optional background color for the Accordion, this will be applied to the header and content. */
  backgroundColor?: AccordionBackgroundColors
  /** Optional text to be displayed instead the caret icon */
  caretText?: React.ReactNode
  /** Optional prop to show the radio button in the Accordion header */
  showRadioButton?: boolean
  /** Optional prop to add a test id to the Accordion for QA testing */
  qaTestId?: string
}

const Accordion = ({
  title,
  subtitle,
  children,
  actions,
  disabled = false,
  isExpanded,
  callout,
  checked,
  backgroundColor,
  caretText,
  showRadioButton = true,
  qaTestId = 'accordion',
}: AccordionItemProps): React.JSX.Element => {
  const [isOpen, setIsOpen] = useState(isExpanded ?? false)

  const inlineStyles = {
    ...(backgroundColor
      ? { backgroundColor: `var(--${backgroundColor})` }
      : {}),
  }

  const handleClick = useCallback(() => {
    if (!disabled) {
      const newState = !isOpen
      setIsOpen(newState)
      callout?.(newState)
    }
  }, [callout, disabled, isOpen])

  useEffect(() => {
    if (isExpanded !== undefined) setIsOpen(isExpanded)
  }, [isExpanded])

  return (
    <div
      className={`${styles.accordionItem} ${isOpen ? styles.isOpen : ''} ${disabled ? styles.disabled : ''} ${showRadioButton ? '' : styles.showRadioButton}`}
      style={inlineStyles}
      data-testid='accordion-container'
      qa-test-id={qaTestId}
    >
      <div
        className={styles.accordionHeader}
        onClick={handleClick}
        data-testid='accordion-header'
      >
        <div className={styles.accordionTitleContainer}>
          <div className={styles.titleWrapper}>
            <div className={styles.accordionSection}>
              {showRadioButton ? (
                <Checkbox
                  label=''
                  checked={checked !== undefined ? checked : isOpen}
                  checkboxColor='blue'
                  type='radio'
                  disabled={disabled}
                />
              ) : null}
              <span
                className={styles.accordionTitle}
                data-testid='accordion-title'
              >
                {title}
              </span>
            </div>
            {subtitle ? (
              <span
                className={styles.accordionSubtitle}
                data-testid='accordion-subtitle'
              >
                {subtitle}
              </span>
            ) : null}
          </div>
          {actions ? (
            <div
              className={styles.actionGroup}
              onClick={(e) => e.stopPropagation()}
              data-testid='accordion-actions'
            >
              {actions}
            </div>
          ) : null}
        </div>
        {caretText ? (
          <span data-testid='accordion-caret-text'>{caretText}</span>
        ) : (
          <Icon
            icon='caretDown'
            className={`${isOpen ? styles.rotate : ''} ${styles.caret}`}
          />
        )}
      </div>

      <div
        className={styles.accordionContent}
        style={inlineStyles}
        data-testid='accordion-content'
      >
        {children}
      </div>
    </div>
  )
}

export default Accordion
