import React, { ReactNode, useState, useRef } from 'react';

import { cn } from '@/lib/helper';

export interface DropdownProps {
  trigger: ReactNode;
  children: ReactNode;
  className?: {
    wrapper?: string;
    trigger?: string;
    content?: string;
  };
  align?: 'start' | 'center' | 'end';
  direction?: 'top' | 'bottom' | 'left' | 'right';
  hover?: boolean;
  defaultOpen?: boolean;
  open?: boolean;
  close?: boolean;
  controlled?: boolean;
}

const Dropdown = ({
  trigger,
  children,
  className,
  align,
  direction,
  hover,
  defaultOpen = false,
  open,
  close,
  controlled = false,
}: DropdownProps) => {
  const [isOpen, setIsOpen] = useState(defaultOpen);
  const dropdownRef = useRef<HTMLDivElement>(null);

  const toggleDropdown = () => {
    if (!controlled) {
      const newState = !isOpen;
      setIsOpen(newState);
    }
  };

  const getWrapperClasses = () => {
    const openState = controlled ? open : isOpen;

    return cn(
      'dropdown',
      {
        'dropdown-start': align === 'start',
        'dropdown-center': align === 'center',
        'dropdown-end': align === 'end',
        'dropdown-top': direction === 'top',
        'dropdown-bottom': direction === 'bottom',
        'dropdown-left': direction === 'left',
        'dropdown-right': direction === 'right',
        'dropdown-hover': hover,
        'dropdown-open': openState && !close,
        'dropdown-close': close,
      },
      className?.wrapper
    );
  };

  const getTriggerClasses = () => {
    return cn(className?.trigger);
  };

  const getContentClasses = () => {
    return cn(
      'dropdown-content z-[9999] shadow-sm bg-base-100 rounded-box',
      className?.content
    );
  };

  if (controlled) {
    return (
      <div className={getWrapperClasses()}>
        {trigger}
        {open && !close && (
          <div tabIndex={-1} className={getContentClasses()}>
            {children}
          </div>
        )}
      </div>
    );
  }

  return (
    <div ref={dropdownRef} className={getWrapperClasses()}>
      <div
        tabIndex={0}
        role='button'
        className={getTriggerClasses()}
        onClick={toggleDropdown}
        onKeyDown={(e) => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            toggleDropdown();
          }
        }}
      >
        {trigger}
      </div>
      {!close && (
        <div tabIndex={-1} className={getContentClasses()}>
          {children}
        </div>
      )}
    </div>
  );
};

export default Dropdown;
