import { useEffect } from 'react';
import { useDropzone, type Accept } from 'react-dropzone';

import { Icon } from '@iconify/react';
import Button from '@/components/Button';

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

interface DropFileInputProps {
  name: string;
  label?: string;
  bottomLabel?: string;
  caption?: string;
  values?: File[];
  accept?: Accept;
  required?: boolean;
  maxFiles?: number; // defaults to 1
  maxSize?: number; // defaults to 2097152 (2 MB)
  isError?: boolean;
  errorMessage?: string;
  disabled?: boolean;
  onChange?: (files: File[]) => void;
  onDelete?: (index: number) => void;
  className?: {
    wrapper?: string;
    inputContainer?: string;
    label?: string;
    inputWrapper?: string;
    caption?: string;
    bottomLabel?: string;
    errorMessage?: string;
    fileItemContainer?: string;
  };
}

const DropFileInput: React.FC<DropFileInputProps> = ({
  name,
  label,
  bottomLabel,
  caption = 'Seret atau Pilih Dokumen',
  values,
  accept,
  required,
  maxFiles = Infinity,
  maxSize,
  isError,
  errorMessage,
  disabled,
  onChange,
  onDelete,
  className,
}) => {
  const isDisabled =
    Boolean(values && maxFiles && values.length >= maxFiles) || disabled;

  const {
    acceptedFiles,
    getRootProps,
    getInputProps,
    isFocused,
    isDragAccept,
    isDragReject,
  } = useDropzone({
    maxSize,
    maxFiles,
    accept: accept,
    disabled: isDisabled,
  });

  useEffect(() => {
    if (values && maxFiles && values.length <= maxFiles) {
      onChange?.([...values, ...acceptedFiles]);
    }
  }, [acceptedFiles]);

  return (
    <div className={cn('w-full', className?.wrapper)}>
      <div
        className={cn(
          'w-full flex flex-col gap-2 text-start',
          className?.inputContainer
        )}
      >
        {label && (
          <label
            htmlFor={name}
            className={cn(
              'w-full text-sm font-normal leading-5',
              className?.label
            )}
          >
            {label}
            {required && (
              <>
                {' '}
                <span className='tooltip tooltip-error' data-tip='required'>
                  <span className='text-error'>*</span>
                </span>
              </>
            )}
          </label>
        )}

        <div
          {...getRootProps({
            'aria-disabled': isDisabled,
            className: cn(
              'dropzone w-full px-4 py-2 border border-dashed border-gray-300 rounded cursor-pointer transition-all',
              'hover:border-primary hover:bg-primary/10',
              {
                'border-success bg-success/10': isDragAccept,
                'border-error bg-error/10': isDragReject || isError,
                'border-primary bg-primary/10': isFocused,
                'bg-gray-200/20 cursor-not-allowed': isDisabled,
              },
              className?.inputWrapper
            ),
          })}
        >
          <input
            {...getInputProps({
              id: name,
              name,
              disabled: isDisabled,
              'aria-disabled': isDisabled,
            })}
          />
          {caption && (
            <p className={cn('text-gray-500 text-sm', className?.caption)}>
              {caption}
            </p>
          )}
        </div>

        {!isError && bottomLabel && (
          <p
            className={cn(
              'w-full mt-1.5 text-xs opacity-60',
              className?.bottomLabel
            )}
          >
            {bottomLabel}
          </p>
        )}
        {isError && (
          <p
            className={cn(
              'w-full mt-1.5 text-xs text-error',
              className?.errorMessage
            )}
          >
            {errorMessage}
          </p>
        )}
      </div>

      {values && values.length > 0 && (
        <div
          className={cn(
            'w-full mt-1.5 flex flex-col gap-1.5',
            className?.fileItemContainer
          )}
        >
          {values.map((file, idx) => (
            <div
              key={idx}
              className={cn('w-full flex flex-row items-center gap-2')}
            >
              <div className='p-2 rounded-full bg-primary/10'>
                <Icon
                  icon='basil:file-solid'
                  width={24}
                  height={24}
                  className='text-blue-500'
                />
              </div>

              <div className='w-full text-sm'>
                <p>{file.name}</p>
              </div>

              <Button
                variant='ghost'
                color='error'
                onClick={() => {
                  onDelete?.(idx);
                }}
                className='rounded-full text-error focus-visible:text-error-content hover:text-error-content'
              >
                <Icon icon='fluent:delete-12-regular' width={24} height={24} />
              </Button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
};

export default DropFileInput;
