'use client';

import * as React from 'react';
import {
  Menu,
  MenuButton,
  MenuItem,
  MenuItems,
  Portal,
} from '@headlessui/react';
import {
  ChevronDownIcon,
  EllipsisVerticalIcon,
} from '@heroicons/react/20/solid';
import clsx from 'clsx';

type DropdownTone = 'default' | 'danger';

export type DropdownItem = {
  id?: string;
  label: string;
  href?: string;
  onClick?: () => void;
  icon?: React.ReactNode;
  tone?: DropdownTone;
  disabled?: boolean;
};

export type DropdownSection = {
  id?: string;
  label?: string;
  items: DropdownItem[];
};

// 🔹 NEU: 'input'
export type DropdownTriggerVariant = 'button' | 'icon' | 'input';

export interface DropdownProps {
  label?: string;
  ariaLabel?: string;
  align?: 'left' | 'right';
  triggerVariant?: DropdownTriggerVariant;
  header?: React.ReactNode;
  sections: DropdownSection[];

  triggerClassName?: string;
  menuClassName?: string;

  /** Dropdown komplett deaktivieren (Trigger klickt nicht) */
  disabled?: boolean;

  /** Nur für triggerVariant="input": gesteuerter Eingabewert */
  inputValue?: string;
  inputPlaceholder?: string;
  onInputChange?: (value: string) => void;
}

/* ───────── interne Helfer ───────── */

const itemBaseClasses =
  'block px-4 py-2 text-sm ' +
  'text-gray-700 dark:text-gray-300 ' +
  'hover:bg-gray-100 hover:text-gray-900 ' +
  'dark:hover:bg-white/5 dark:hover:text-white ' +
  'focus:outline-none';

const itemWithIconClasses =
  'group flex items-center gap-x-3 px-4 py-2 text-sm ' +
  'text-gray-700 dark:text-gray-300 ' +
  'hover:bg-gray-100 hover:text-gray-900 ' +
  'dark:hover:bg-white/5 dark:hover:text-white ' +
  'focus:outline-none';

const iconClasses =
  'flex size-5 shrink-0 items-center justify-center text-gray-400 ' +
  'group-hover:text-gray-500 ' +
  'dark:text-gray-500 dark:group-hover:text-white';

const toneClasses: Record<DropdownTone, string> = {
  default: '',
  danger:
    'text-rose-600 data-focus:text-rose-700 dark:text-rose-400 dark:data-focus:text-rose-300',
};

function renderItemContent(item: DropdownItem) {
  const hasIcon = !!item.icon;

  if (hasIcon) {
    return (
      <span
        className={clsx(
          itemWithIconClasses,
          item.tone && toneClasses[item.tone],
        )}
      >
        <span aria-hidden="true" className={iconClasses}>
          {item.icon}
        </span>
        {item.label}
      </span>
    );
  }

  return (
    <span
      className={clsx(
        itemBaseClasses,
        item.tone && toneClasses[item.tone],
      )}
    >
      {item.label}
    </span>
  );
}

/* ───────── Spezielle Variante: Textfeld + Dropdown (OHNE Menu) ───────── */

function InputDropdown({
  label = 'Options',
  ariaLabel = 'Open options',
  align = 'left',
  header,
  sections,
  triggerClassName,
  menuClassName,
  disabled = false,
  inputValue,
  inputPlaceholder,
  onInputChange,
}: DropdownProps) {
  const [open, setOpen] = React.useState(false);
  const anchorRef = React.useRef<HTMLDivElement | null>(null);
  const menuRef = React.useRef<HTMLDivElement | null>(null); // 🔹 NEU
  const [position, setPosition] = React.useState<{
    top: number;
    left: number;
    width: number;
  } | null>(null);

  const hasDividers = sections.length > 1;
  const effectivePlaceholder = inputPlaceholder ?? label;

  // Position neu berechnen, wenn geöffnet
  React.useEffect(() => {
    if (!open || !anchorRef.current) return;

    const rect = anchorRef.current.getBoundingClientRect();
    const scrollX =
      window.pageXOffset || document.documentElement.scrollLeft;
    const scrollY =
      window.pageYOffset || document.documentElement.scrollTop;

    const leftBase = rect.left + scrollX;

    setPosition({
      top: rect.bottom + scrollY + 4,
      left: leftBase,
      width: rect.width,
    });
  }, [open, align]);

  // Klick außerhalb / ESC schließt das Dropdown
  React.useEffect(() => {
    if (!open) return;

    function handleClickOutside(ev: MouseEvent) {
      const target = ev.target as Node;
      // 🔹 Wenn Klick im Input-Bereich oder im Menü: NICHT schließen
      if (
        (anchorRef.current && anchorRef.current.contains(target)) ||
        (menuRef.current && menuRef.current.contains(target))
      ) {
        return;
      }
      setOpen(false);
    }

    function handleKey(ev: KeyboardEvent) {
      if (ev.key === 'Escape') {
        setOpen(false);
      }
    }

    window.addEventListener('mousedown', handleClickOutside);
    window.addEventListener('keydown', handleKey);
    return () => {
      window.removeEventListener('mousedown', handleClickOutside);
      window.removeEventListener('keydown', handleKey);
    };
  }, [open]);

  return (
    <div className="relative inline-block w-full text-left">
      <div
        ref={anchorRef}
        className={clsx('relative', triggerClassName)}
      >
        <input
          type="text"
          value={inputValue ?? ''}
          placeholder={effectivePlaceholder}
          disabled={disabled}
          onChange={(e) => {
            onInputChange?.(e.target.value);
            if (!disabled && !open) setOpen(true);
          }}
          onFocus={() => {
            if (!disabled) setOpen(true);
          }}
          className="block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 pr-8 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none dark:bg-gray-900/60 dark:ring-gray-600"
        />
        <button
          type="button"
          aria-label={ariaLabel}
          disabled={disabled}
          onClick={() => {
            if (!disabled) setOpen((prev) => !prev);
          }}
          className={clsx(
            'absolute inset-y-0 right-0 flex items-center pr-2',
            disabled && 'cursor-not-allowed opacity-50',
          )}
        >
          <ChevronDownIcon
            aria-hidden="true"
            className="size-4 text-gray-400 dark:text-gray-500"
          />
        </button>
      </div>

      {open && position && !disabled && (
        <Portal>
          <div
            ref={menuRef} // 🔹 WICHTIG: für Outside-Click-Erkennung
            style={{
              position: 'fixed',
              top: position.top,
              left: position.left,
              width: position.width,
            }}
            className={clsx(
              'z-[9999] max-h-[60vh] overflow-y-auto rounded-md bg-white shadow-lg outline-1 outline-black/5 ' +
                'dark:bg-gray-800 dark:shadow-none dark:-outline-offset-1 dark:outline-white/10',
              hasDividers &&
                'divide-y divide-gray-100 dark:divide-white/10',
              menuClassName,
            )}
          >
            {header && <div className="px-4 py-3">{header}</div>}

            {sections.map((section, sectionIndex) => (
              <div
                key={section.id ?? sectionIndex}
                className="py-1"
              >
                {section.label && (
                  <div className="px-4 py-1 text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
                    {section.label}
                  </div>
                )}

                {section.items.map((item, itemIndex) => {
                  const key = item.id ?? `${sectionIndex}-${itemIndex}`;

                  const handleClick = () => {
                    if (item.disabled) return;
                    item.onClick?.();   // 🔹 Auswahl nach außen melden
                    setOpen(false);     // 🔹 Danach Dropdown schließen
                  };

                  if (item.href) {
                    return (
                      <a
                        key={key}
                        href={item.href}
                        onClick={handleClick}
                        className="block"
                      >
                        {renderItemContent(item)}
                      </a>
                    );
                  }

                  return (
                    <button
                      key={key}
                      type="button"
                      disabled={item.disabled}
                      onClick={handleClick}
                      className="block w-full text-left disabled:opacity-60"
                    >
                      {renderItemContent(item)}
                    </button>
                  );
                })}
              </div>
            ))}
          </div>
        </Portal>
      )}
    </div>
  );
}

/* ───────── Standard-Dropdown (Menu) für Button/Icon ───────── */

export function Dropdown(props: DropdownProps) {
  const {
    label = 'Options',
    ariaLabel = 'Open options',
    align = 'right',
    triggerVariant = 'button',
    header,
    sections,
    triggerClassName,
    menuClassName,
    disabled = false,
  } = props;

  const triggerIsInput = triggerVariant === 'input';
  const triggerIsIcon = triggerVariant === 'icon';
  const triggerIsButton = triggerVariant === 'button';

  // 🔹 Spezialfall: Textfeld + Dropdown (ohne Menu)
  if (triggerIsInput) {
    return (
      <InputDropdown
        {...props}
        triggerVariant="input"
      />
    );
  }

  const hasDividers = sections.length > 1;

  return (
    <Menu as="div" className="relative inline-block text-left">
      {({ open }) => {
        const buttonRef =
          React.useRef<HTMLButtonElement | null>(null);
        const [position, setPosition] = React.useState<{
          top: number;
          left: number;
        } | null>(null);

        React.useEffect(() => {
          if (!open || !buttonRef.current) return;

          const rect = buttonRef.current.getBoundingClientRect();
          const scrollX =
            window.pageXOffset || document.documentElement.scrollLeft;
          const scrollY =
            window.pageYOffset || document.documentElement.scrollTop;

          const left =
            align === 'left'
              ? rect.left + scrollX
              : rect.right + scrollX;

          setPosition({
            top: rect.bottom + scrollY + 4,
            left,
          });
        }, [open, align]);

        return (
          <>
            <MenuButton
              ref={buttonRef}
              disabled={disabled}
              className={clsx(
                triggerIsButton
                  ? 'inline-flex w-full justify-center gap-x-1.5 rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-xs inset-ring-1 inset-ring-gray-300 hover:bg-gray-50 dark:bg-white/10 dark:text-white dark:shadow-none dark:inset-ring-white/5 dark:hover:bg-white/20'
                  : 'flex items-center rounded-full text-gray-400 hover:text-gray-600 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 dark:text-gray-400 dark:hover:text-gray-300 dark:focus-visible:outline-indigo-500',
                disabled &&
                  'opacity-50 cursor-not-allowed hover:bg-white dark:hover:bg-white/10',
                triggerClassName,
              )}
            >
              {triggerIsButton ? (
                <>
                  {label}
                  <ChevronDownIcon
                    aria-hidden="true"
                    className="-mr-1 size-5 text-gray-400 dark:text-gray-500"
                  />
                </>
              ) : (
                <>
                  <span className="sr-only">{ariaLabel}</span>
                  <EllipsisVerticalIcon
                    aria-hidden="true"
                    className="size-5"
                  />
                </>
              )}
            </MenuButton>

            {open && position && !disabled && (
              <Portal>
                <MenuItems
                  static
                  style={{
                    position: 'fixed',
                    top: position.top,
                    left:
                      align === 'left' ? position.left : undefined,
                    right:
                      align === 'right'
                        ? window.innerWidth - position.left
                        : undefined,
                  }}
                  className={clsx(
                    'z-[9999] w-56 max-h-[60vh] overflow-y-auto rounded-md bg-white shadow-lg outline-1 outline-black/5 ' +
                      'dark:bg-gray-800 dark:shadow-none dark:-outline-offset-1 dark:outline-white/10',
                    hasDividers &&
                      'divide-y divide-gray-100 dark:divide-white/10',
                    menuClassName,
                  )}
                >
                  {header && (
                    <div className="px-4 py-3">{header}</div>
                  )}

                  {sections.map((section, sectionIndex) => (
                    <div
                      key={section.id ?? sectionIndex}
                      className="py-1"
                    >
                      {section.label && (
                        <div className="px-4 py-1 text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
                          {section.label}
                        </div>
                      )}

                      {section.items.map((item, itemIndex) => {
                        const key =
                          item.id ?? `${sectionIndex}-${itemIndex}`;

                        return (
                          <MenuItem
                            key={key}
                            disabled={item.disabled}
                          >
                            {item.href ? (
                              <a
                                href={item.href}
                                onClick={item.onClick}
                                className="block"
                              >
                                {renderItemContent(item)}
                              </a>
                            ) : (
                              <button
                                type="button"
                                onClick={item.onClick}
                                className="block w-full text-left"
                              >
                                {renderItemContent(item)}
                              </button>
                            )}
                          </MenuItem>
                        );
                      })}
                    </div>
                  ))}
                </MenuItems>
              </Portal>
            )}
          </>
        );
      }}
    </Menu>
  );
}

export default Dropdown;
