import React, { useCallback, useState } from 'react';
import { useShadeRuntimeTheme } from '../../ShadeRuntimeProvider.js';

export interface DropZoneProps {
  /** Called when files are dropped or selected via the click-to-pick action. */
  onFiles: (files: File[]) => void;
  /** Allow multiple files (default: true). */
  multiple?: boolean;
  /** `<input type="file">` accept filter (e.g. `'.zip,application/zip'`). */
  accept?: string;
  className?: string;
  style?: React.CSSProperties;
  children?: React.ReactNode;
}

/**
 * Drag-and-drop file zone built on native HTML5 DnD APIs. Falls back to a
 * native file picker when the user clicks or focuses-and-presses-Enter.
 */
export function DropZone({
  onFiles,
  multiple = true,
  accept,
  className,
  style,
  children,
}: DropZoneProps): React.ReactElement {
  const theme = useShadeRuntimeTheme();
  const [isDragging, setIsDragging] = useState(false);
  const inputRef = React.useRef<HTMLInputElement | null>(null);

  const onDragOver = useCallback((e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'copy';
    setIsDragging(true);
  }, []);

  const onDragLeave = useCallback(() => {
    setIsDragging(false);
  }, []);

  const onDrop = useCallback(
    (e: React.DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      setIsDragging(false);
      const files = Array.from(e.dataTransfer.files);
      if (files.length > 0) onFiles(files);
    },
    [onFiles],
  );

  const onChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const files = e.target.files === null ? [] : Array.from(e.target.files);
      if (files.length > 0) onFiles(files);
      e.target.value = ''; // allow re-picking the same file
    },
    [onFiles],
  );

  const onClick = useCallback(() => {
    inputRef.current?.click();
  }, []);

  const onKeyDown = useCallback(
    (e: React.KeyboardEvent<HTMLDivElement>) => {
      if (e.key === 'Enter' || e.key === ' ') {
        e.preventDefault();
        inputRef.current?.click();
      }
    },
    [],
  );

  const borderActive = theme.dropZoneBorderActive ?? theme.accent;

  return (
    <div
      className={className}
      role="button"
      tabIndex={0}
      onDragOver={onDragOver}
      onDragLeave={onDragLeave}
      onDrop={onDrop}
      onClick={onClick}
      onKeyDown={onKeyDown}
      style={{
        border: `2px dashed ${isDragging ? borderActive : theme.border}`,
        borderRadius: theme.radius,
        padding: 32,
        textAlign: 'center',
        background: isDragging ? theme.accentMuted : theme.bg,
        color: theme.textMuted,
        cursor: 'pointer',
        transition: 'border-color 0.15s, background 0.15s',
        fontFamily: theme.font,
        ...style,
      }}
    >
      <input
        ref={inputRef}
        type="file"
        multiple={multiple}
        {...(accept !== undefined ? { accept } : {})}
        onChange={onChange}
        style={{ display: 'none' }}
      />
      {children ?? (
        <span>
          {isDragging ? 'Slipp filer for å laste opp' : 'Dra og slipp filer her, eller klikk for å velge'}
        </span>
      )}
    </div>
  );
}
