import type { MouseEvent, ReactNode } from 'react'
import { Children, cloneElement, isValidElement, useState } from 'react'
import cx from 'classnames'

interface CollapsedProps {
  children: ReactNode
  handleOpen?: (e: MouseEvent<HTMLButtonElement>) => void
  id: string
  active?: boolean
  containerClasses?: string
}

interface ExpandedProps {
  children: ReactNode
}

interface ItemProps {
  children: ReactNode
}

interface AccordionProps {
  children: ReactNode
  initial: string
  containerClasses?: string
}

const Collapsed = ({ children, handleOpen = () => null, id, active = false, containerClasses }: CollapsedProps) => {
  return (
    <div className={containerClasses}>
      <div id={id}>
        <button
          role="button"
          tabIndex={0}
          className={cx(
            'group flex justify-between items-center w-full text-h2 text-left py-[40px] cursor-pointer',
            !active && 'border-b-4'
          )}
          onClick={e => {
            location.href = `#${id}`
            handleOpen(e)
          }}
          data-id={id}
        >
          {children}
          <span
            className={cx(
              "pointer-events-none block relative w-[30px] h-[30px] before:w-1 before:h-full before:-ml-0.5 before:left-2/4 before:top-0 after:w-full after:h-1 after:-mt-0.5 after:left-0 after:top-2/4 group-hover:cursor-pointer group-hover:before:rotate-90 group-hover:after:rotate-180 before:content-[''] before:absolute before:bg-accent-blue before:transition-transform before:duration-[0.25s] before:ease-[ease-out] after:content-[''] after:absolute after:bg-accent-blue after:transition-transform after:duration-[0.25s] after:ease-[ease-out]",
              active && 'before:rotate-90 after:rotate-180'
            )}
            aria-hidden
          >
            <span className="sr-only">Expand</span>
          </span>
        </button>
      </div>
    </div>
  )
}

const Expanded = ({ children }: ExpandedProps) => {
  return <div className="bar">{children}</div>
}

const Item = ({ children }: ItemProps) => {
  return <>{children}</>
}

const Accordion = ({ children, initial, containerClasses }: AccordionProps) => {
  const [open, setOpen] = useState(initial)

  const handleOpen = (e: MouseEvent<HTMLButtonElement>) => {
    const el = e.target as HTMLInputElement
    const id = el.getAttribute('data-id')
    if (!id) return
    id === open ? setOpen('') : setOpen(id)
  }
  return (
    <div className="accordion">
      {Children.map(children, child => {
        if (!isValidElement(child)) return
        const id = child.props.children[0].props.id
        const active = id === open

        const collapsed = cloneElement(child.props.children[0], {
          handleOpen,
          active,
          containerClasses,
        })

        const expanded = child.props.children[1]

        return (
          <div className="accordion-item">
            {collapsed}
            {id === open && expanded}
          </div>
        )
      })}
    </div>
  )
}

Accordion.Collapsed = Collapsed
Accordion.Expanded = Expanded
Accordion.Item = Item

export default Accordion
