// frontend\src\components\ui\Modal.tsx

'use client'

import { Fragment, type ReactNode, useEffect, useRef, useState } from 'react'
import { Dialog, Transition } from '@headlessui/react'
import { XMarkIcon } from '@heroicons/react/24/outline'
import Button from './Button'

type ModalLayout = 'single' | 'split'
type ModalScroll = 'body' | 'right' | 'none'

type ModalProps = {
  open: boolean
  onClose: () => void
  title?: ReactNode
  titleRight?: ReactNode
  children?: ReactNode
  footer?: ReactNode
  icon?: ReactNode

  /**
   * Tailwind max-width Klasse für Dialog.Panel, z.B.:
   * "max-w-lg" (default), "max-w-2xl", "max-w-4xl", "max-w-5xl"
   */
  width?: string

  /**
   * Layout:
   * - single: klassisches Modal (ein Content-Bereich)
   * - split: 2 Spalten (links fix, rechts content)
   */
  layout?: ModalLayout

  /**
   * Split-Layout: linker Inhalt (fixe Spalte)
   */
  left?: ReactNode

  /**
   * Split-Layout: Breite der linken Spalte (Tailwind).
   * Default: "lg:w-80" (320px)
   */
  leftWidthClass?: string

  /**
   * Scroll-Verhalten:
   * - body: der Body-Bereich scrollt (bei single default)
   * - right: nur rechte Spalte scrollt (bei split default)
   * - none: kein Scroll (nur sinnvoll wenn Inhalt garantiert passt)
   */
  scroll?: ModalScroll

  /**
   * Optional: Zusatzklassen
   */
  bodyClassName?: string
  leftClassName?: string
  rightClassName?: string
  className?: string
  

  /**
   * Split-Layout: Header über dem scrollbaren rechten Bereich
   * (z.B. Tabs/Actions)
   */
  rightHeader?: ReactNode

  /**
   * Optional: Zusatzklassen nur für den scrollbaren RIGHT-BODY
   */
  rightBodyClassName?: string

  /** Optional: kleines Bild im mobilen collapsed Header */
  mobileCollapsedImageSrc?: string
  mobileCollapsedImageAlt?: string
}

function cn(...parts: Array<string | false | null | undefined>) {
  return parts.filter(Boolean).join(' ')
}

export default function Modal({
  open,
  onClose,
  title,
  titleRight,
  children,
  footer,
  icon,
  width = 'max-w-lg',
  layout = 'single',
  left,
  leftWidthClass = 'lg:w-80',
  scroll,
  bodyClassName,
  leftClassName,
  rightClassName,
  className,
  rightHeader,
  rightBodyClassName,
  mobileCollapsedImageSrc,
  mobileCollapsedImageAlt,
}: ModalProps) {
  // sensible defaults
  const scrollMode: ModalScroll =
    scroll ?? (layout === 'split' ? 'right' : 'body')

    
  // --- mobile collapse-on-scroll (only used in split+mobile stacked) ---
  const mobileScrollRef = useRef<HTMLDivElement | null>(null)
  const [mobileCollapsed, setMobileCollapsed] = useState(false)

  useEffect(() => {
    if (!open) return
    // reset when opening
    setMobileCollapsed(false)
  }, [open])

  useEffect(() => {
    if (!open) return
    const el = mobileScrollRef.current
    if (!el) return

    const THRESHOLD = 72 // px, ab wann "kompakt" wird

    const onScroll = () => {
      const y = el.scrollTop || 0
      // nur updaten wenn sich der boolean ändert (verhindert re-render spam)
      setMobileCollapsed((prev) => {
        const next = y > THRESHOLD
        return prev === next ? prev : next
      })
    }

    // initial
    onScroll()

    el.addEventListener('scroll', onScroll, { passive: true })
    return () => el.removeEventListener('scroll', onScroll as any)
  }, [open])

  return (
    <Transition show={open} as={Fragment}>
      <Dialog open={open} as="div" className={cn('relative z-[120]', className)} onClose={onClose}>
        {/* Backdrop */}
        <Transition.Child
          as={Fragment}
          enter="ease-out duration-300"
          enterFrom="opacity-0"
          enterTo="opacity-100"
          leave="ease-in duration-200"
          leaveFrom="opacity-100"
          leaveTo="opacity-0"
        >
          <div className="fixed inset-0 bg-gray-500/75 dark:bg-gray-900/50" />
        </Transition.Child>

        {/* Modal Panel */}
        <div className="fixed inset-0 z-50 overflow-y-auto overscroll-contain px-4 py-6 sm:px-6">
          <div className="min-h-full flex items-start justify-center sm:items-center">
            <Transition.Child
              as={Fragment}
              enter="ease-out duration-300"
              enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
              enterTo="opacity-100 translate-y-0 sm:scale-100"
              leave="ease-in duration-200"
              leaveFrom="opacity-100 translate-y-0 sm:scale-100"
              leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
            >
              <Dialog.Panel
                className={cn(
                  'relative w-full rounded-lg bg-white text-left shadow-xl transition-all',
                  'max-h-[calc(100vh-3rem)] sm:max-h-[calc(100vh-4rem)]',
                  // panel is a flex column so we can create a real scroll area
                  'flex flex-col min-h-0',
                  'dark:bg-gray-800 dark:outline dark:-outline-offset-1 dark:outline-white/10',
                  width
                )}
              >
                {icon ? (
                  <div className="mx-auto mb-4 mt-6 flex h-12 w-12 items-center justify-center rounded-full bg-green-100 dark:bg-green-500/10">
                    {icon}
                  </div>
                ) : null}

                {/* Header (desktop/tablet). On mobile+split we use our own sticky header inside the scroll area */}
                <div
                  className={cn(
                    'shrink-0 px-4 pt-4 sm:px-6 sm:pt-6 items-start justify-between gap-3',
                    layout === 'split' ? 'hidden lg:flex' : 'flex'
                  )}
                >
                  <div className="min-w-0 flex-1">
                    {title ? (
                      <Dialog.Title className="block text-base font-semibold text-gray-900 dark:text-white truncate">
                        {title}
                      </Dialog.Title>
                    ) : null}
                  </div>

                  <div className="shrink-0 flex items-center gap-2">
                    {titleRight ? <div className="hidden sm:block">{titleRight}</div> : null}

                    <Button
                      type="button"
                      variant="secondary"
                      size="sm"
                      onClick={onClose}
                      aria-label="Schließen"
                      title="Schließen"
                      className="shrink-0 px-2 min-w-0"
                    >
                      <XMarkIcon className="size-5" />
                    </Button>
                  </div>
                </div>

                {/* Body */}
                {layout === 'single' ? (
                  <div
                    className={cn(
                      'flex-1 min-h-0 h-full',
                      scrollMode === 'body'
                        ? 'overflow-y-auto overscroll-contain'
                        : 'overflow-hidden',
                      rightClassName
                    )}
                  >
                    {children}
                  </div>
                ) : (
                  // split layout
                  <div
                    className={cn(
                      'px-2 pb-4 pt-3 sm:px-4 sm:pb-6 sm:pt-4',
                      'flex-1 min-h-0',
                      'overflow-hidden',
                      'flex flex-col',
                      bodyClassName
                    )}
                  >
                    {/* ========================= */}
                    {/* MOBILE: stacked (no split) */}
                    {/* ========================= */}
                    <div
                      ref={mobileScrollRef}
                      className={cn(
                        'lg:hidden flex-1 min-h-0 relative',
                        // auf Mobile: EIN Scrollcontainer für alles
                        (scrollMode === 'right' || scrollMode === 'body') ? 'overflow-y-auto overscroll-contain' : 'overflow-hidden'
                      )}
                    >
                      {/* Sticky top area: app bar (shrinks) + left (collapses) + tabs/actions (sticky) */}
                      <div
                        className={cn(
                          'sticky top-0 z-50',
                          'bg-white/95 backdrop-blur dark:bg-gray-800/95',
                          'border-b border-gray-200/70 dark:border-white/10'
                        )}
                      >
                        {/* App bar (always visible, shrinks when collapsed) */}
                        <div
                          className={cn(
                            'flex items-center justify-between gap-3 px-3',
                            mobileCollapsed ? 'py-2' : 'py-3'
                          )}
                        >
                          <div className="min-w-0 flex items-center gap-2 flex-1">
                            {mobileCollapsedImageSrc ? (
                              <img
                                src={mobileCollapsedImageSrc}
                                alt={mobileCollapsedImageAlt || (typeof title === 'string' ? title : '')}
                                className={cn(
                                  'shrink-0 rounded-lg object-cover ring-1 ring-black/5 dark:ring-white/10',
                                  mobileCollapsed ? 'size-8' : 'size-10'
                                )}
                                loading="lazy"
                                decoding="async"
                              />
                            ) : null}

                            <div className="min-w-0 flex-1">
                              {title ? (
                                <div
                                  className={cn(
                                    'truncate font-semibold text-gray-900 dark:text-white',
                                    mobileCollapsed ? 'text-sm' : 'text-base'
                                  )}
                                >
                                  {title}
                                </div>
                              ) : null}
                            </div>
                          </div>

                          <div className="shrink-0 flex items-center gap-2">
                            {titleRight ? <div>{titleRight}</div> : null}

                            <Button
                              type="button"
                              variant="secondary"
                              size="sm"
                              onClick={onClose}
                              aria-label="Schließen"
                              title="Schließen"
                              className="shrink-0 px-2 min-w-0"
                            >
                              <XMarkIcon className="size-5" />
                            </Button>
                          </div>
                        </div>

                        {/* Sticky tabs/actions (always sticky because in this sticky wrapper) */}
                        {rightHeader ? <div>{rightHeader}</div> : null}
                      </div>

                      {/* LEFT content on mobile (scrolls away, not sticky) */}
                      {left ? (
                        <div className={cn('lg:hidden px-2 pb-2', leftClassName)}>
                          {left}
                        </div>
                      ) : null}

                      {/* Body (only the right content) */}
                      <div className={cn('px-2 pt-0 min-h-0', rightClassName)}>
                        <div className={cn('min-h-0', rightBodyClassName)}>{children}</div>
                      </div>
                    </div>

                    {/* ========================= */}
                    {/* DESKTOP: real split layout */}
                    {/* ========================= */}
                    <div className="hidden lg:flex flex-1 min-h-0 gap-3">
                      {/* LEFT (fixed) */}
                      <div
                        className={cn(
                          'min-h-0',
                          leftWidthClass,
                          'shrink-0',
                          'overflow-hidden',
                          leftClassName
                        )}
                      >
                        {left}
                      </div>

                      {/* RIGHT */}
                      <div className={cn('flex-1 min-h-0 flex flex-col', rightClassName)}>
                        {rightHeader ? <div className="shrink-0">{rightHeader}</div> : null}

                        <div
                          className={cn(
                            'flex-1 min-h-0',
                            scrollMode === 'right'
                              ? 'overflow-y-auto overscroll-contain'
                              : 'overflow-hidden',
                            rightBodyClassName
                          )}
                        >
                          {children}
                        </div>
                      </div>
                    </div>
                  </div>
                )}

                {/* Footer */}
                {footer ? (
                  <div className="shrink-0 px-6 py-4 border-t border-gray-200/70 dark:border-white/10 flex justify-end gap-3">
                    {footer}
                  </div>
                ) : null}
              </Dialog.Panel>
            </Transition.Child>
          </div>
        </div>
      </Dialog>
    </Transition>
  )
}
