'use client'

import React, { useEffect, useId, useRef, useState } from 'react'
import classNames from 'classnames'
import { CollapsibleArrow } from '@/components/CollapsibleArrow/CollapsibleArrow'
import styles from './styles.module.scss'

type CollapsibleProps = {
  title: string
  children: React.ReactNode
  defaultOpen?: boolean
  id?: string
}

export const Collapsible = ({
  title,
  children,
  defaultOpen = false,
  id,
}: CollapsibleProps) => {
  const reactId = useId()
  const baseId = id ?? reactId
  const headerId = `${baseId}-header`
  const panelId = `${baseId}-panel`

  const [isOpen, setIsOpen] = useState(defaultOpen)
  const [contentHeight, setContentHeight] = useState(0)
  const contentRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const measure = () => {
      if (contentRef.current) {
        setContentHeight(contentRef.current.scrollHeight)
      }
    }
    measure()
    window.addEventListener('resize', measure)
    return () => window.removeEventListener('resize', measure)
  }, [children])

  const toggle = () => setIsOpen(v => !v)

  return (
    <div className={styles.collapsible}>
      <button
        type="button"
        id={headerId}
        className={styles.header}
        aria-expanded={isOpen}
        aria-controls={panelId}
        onClick={toggle}
      >
        <span className={styles.title}>{title}</span>
        <span aria-hidden="true" className={styles.arrow}>
          <CollapsibleArrow direction={isOpen ? 'UP' : 'DOWN'} />
        </span>
      </button>

      <div
        id={panelId}
        role="region"
        aria-labelledby={headerId}
        aria-hidden={!isOpen}
        inert={!isOpen}
        ref={contentRef}
        className={classNames(styles.content, { [styles.open]: isOpen })}
        style={{ maxHeight: isOpen ? contentHeight : 0 }}
      >
        <div className={styles.inner}>{children}</div>
      </div>
    </div>
  )
}
