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

export interface AddonTeaserNoteApi {
  /** Component name of the currently open teaser, or null when none is open. */
  openTeaser: string | null
  /** Opens `name`'s note, or closes it if it's already the open one. */
  toggle: ( name: string ) => void
  close: () => void
}

/**
 * Tracks which add-on teaser's note is open in one palette (fields or
 * actions) — at most one at a time, across every section of that palette.
 * Closes on Escape or a mousedown outside both the open tile and its note.
 * The tile and its note render in different parts of the section tree (the
 * note sits in normal document flow under the section, not layered over the
 * tile), so "inside" is matched via `data-addon-teaser="<name>"` /
 * `data-addon-note="<name>"` attributes rather than a shared ref.
 */
export default function useAddonTeaserNote(): AddonTeaserNoteApi {
  const [ openTeaser, setOpenTeaser ] = useState<string | null>( null )

  const toggle = useCallback( ( name: string ) => {
    setOpenTeaser( current => current === name ? null : name )
  }, [] )

  const close = useCallback( () => setOpenTeaser( null ), [] )

  useEffect( () => {
    if ( ! openTeaser ) return

    const isInside = ( target: EventTarget | null ) =>
      target instanceof Element && (
        target.closest( `[data-addon-teaser="${ openTeaser }"]` )
        || target.closest( `[data-addon-note="${ openTeaser }"]` )
      )

    const handleMouseDown = ( e: MouseEvent ) => {
      if ( ! isInside( e.target ) ) close()
    }
    const handleKeyDown = ( e: KeyboardEvent ) => {
      if ( 'Escape' === e.key ) close()
    }

    document.addEventListener( 'mousedown', handleMouseDown )
    document.addEventListener( 'keydown', handleKeyDown )
    return () => {
      document.removeEventListener( 'mousedown', handleMouseDown )
      document.removeEventListener( 'keydown', handleKeyDown )
    }
  }, [ openTeaser, close ] )

  return { openTeaser, toggle, close }
}
