'use client'

import React, { useCallback, useEffect, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
import { AnimatePresence } from 'motion/react'
import {
  getNotebookPickerPosition,
  NotebookHierarchyPanel,
  type NotebookPickerItem,
} from '@/components/notebook-hierarchy-panel'
import { useLanguage } from '@/lib/i18n'

type MoveToNotebookPickerProps = {
  notebooks: NotebookPickerItem[]
  currentNotebookId?: string | null
  onSelect: (notebookId: string | null) => void
  children: React.ReactElement
  align?: 'start' | 'end'
  preferDropUp?: boolean
}

export function MoveToNotebookPicker({
  notebooks,
  currentNotebookId = null,
  onSelect,
  children,
  align = 'end',
  preferDropUp = false,
}: MoveToNotebookPickerProps) {
  const { t } = useLanguage()
  const [open, setOpen] = useState(false)
  const triggerRef = useRef<HTMLElement>(null)
  const [panelStyle, setPanelStyle] = useState<React.CSSProperties | undefined>()

  const close = useCallback(() => setOpen(false), [])

  const updatePosition = useCallback(() => {
    if (!triggerRef.current) return
    setPanelStyle(
      getNotebookPickerPosition(triggerRef.current.getBoundingClientRect(), { align, preferDropUp }),
    )
  }, [align, preferDropUp])

  useEffect(() => {
    if (!open) {
      setPanelStyle(undefined)
      return
    }
    updatePosition()
    window.addEventListener('scroll', updatePosition, true)
    window.addEventListener('resize', updatePosition)
    return () => {
      window.removeEventListener('scroll', updatePosition, true)
      window.removeEventListener('resize', updatePosition)
    }
  }, [open, updatePosition])

  const handleSelect = (notebookId: string | null) => {
    onSelect(notebookId)
    close()
  }

  const child = React.cloneElement(children, {
    ref: (node: HTMLElement | null) => {
      triggerRef.current = node
      const childRef = (children as React.ReactElement & { ref?: React.Ref<HTMLElement> }).ref
      if (typeof childRef === 'function') childRef(node)
      else if (childRef && typeof childRef === 'object') {
        ;(childRef as React.MutableRefObject<HTMLElement | null>).current = node
      }
    },
    onClick: (e: React.MouseEvent) => {
      e.stopPropagation()
      children.props.onClick?.(e)
      setOpen((prev) => !prev)
    },
  })

  return (
    <>
      {child}
      {typeof window !== 'undefined' &&
        createPortal(
          <AnimatePresence>
            {open && panelStyle && (
              <>
                <div className="fixed inset-0 z-[9998]" onClick={close} aria-hidden />
                <NotebookHierarchyPanel
                  key="move-notebook-picker"
                  notebooks={notebooks}
                  selectedId={currentNotebookId}
                  onSelect={(id) => handleSelect(id)}
                  onClose={close}
                  showGeneralNotes
                  generalNotesLabel={t('notebookSuggestion.generalNotes') || 'Notes générales'}
                  onSelectGeneralNotes={() => handleSelect(null)}
                  searchPlaceholder={t('notebookSuggestion.filterNotebooks') || 'Filtrer les carnets…'}
                  closeLabel={t('general.close') || 'Fermer'}
                  style={panelStyle}
                />
              </>
            )}
          </AnimatePresence>,
          document.body,
        )}
    </>
  )
}

type MoveToNotebookPickerPortalProps = {
  open: boolean
  onOpenChange: (open: boolean) => void
  anchorRef: React.RefObject<HTMLElement | null>
  notebooks: NotebookPickerItem[]
  currentNotebookId?: string | null
  onSelect: (notebookId: string | null) => void
  align?: 'start' | 'end'
  preferDropUp?: boolean
}

export function MoveToNotebookPickerPortal({
  open,
  onOpenChange,
  anchorRef,
  notebooks,
  currentNotebookId = null,
  onSelect,
  align = 'end',
  preferDropUp = false,
}: MoveToNotebookPickerPortalProps) {
  const { t } = useLanguage()
  const [panelStyle, setPanelStyle] = useState<React.CSSProperties | undefined>()

  useEffect(() => {
    if (!open || !anchorRef.current) {
      setPanelStyle(undefined)
      return
    }
    const update = () => {
      if (!anchorRef.current) return
      setPanelStyle(
        getNotebookPickerPosition(anchorRef.current.getBoundingClientRect(), { align, preferDropUp }),
      )
    }
    update()
    window.addEventListener('scroll', update, true)
    window.addEventListener('resize', update)
    return () => {
      window.removeEventListener('scroll', update, true)
      window.removeEventListener('resize', update)
    }
  }, [open, anchorRef, align, preferDropUp])

  const handleSelect = (notebookId: string | null) => {
    onSelect(notebookId)
    onOpenChange(false)
  }

  if (typeof window === 'undefined') return null

  return createPortal(
    <AnimatePresence>
      {open && panelStyle && (
        <>
          <div className="fixed inset-0 z-[9998]" onClick={() => onOpenChange(false)} aria-hidden />
          <NotebookHierarchyPanel
            key="move-notebook-picker-portal"
            notebooks={notebooks}
            selectedId={currentNotebookId}
            onSelect={(id) => handleSelect(id)}
            onClose={() => onOpenChange(false)}
            showGeneralNotes
            generalNotesLabel={t('notebookSuggestion.generalNotes') || 'Notes générales'}
            onSelectGeneralNotes={() => handleSelect(null)}
            searchPlaceholder={t('notebookSuggestion.filterNotebooks') || 'Filtrer les carnets…'}
            closeLabel={t('general.close') || 'Fermer'}
            style={panelStyle}
          />
        </>
      )}
    </AnimatePresence>,
    document.body,
  )
}
