import { i18nMessage } from "../i18n/LanguageContext";import { useRef, useState, type CSSProperties, type DragEvent as ReactDragEvent, type ReactNode } from "react";
import { UploadCloud } from "lucide-react";
import { resolveDroppedFiles } from "./resolveDroppedFiles";

type RejectedDropReason = "disabled" | "empty" | "unreadable";

export type FileDropZoneProps = {
  accept?: string;
  multiple?: boolean;
  disabled?: boolean;
  busy?: boolean;
  progress?: number | null;
  label?: ReactNode;
  actionLabel?: ReactNode;
  busyLabel?: ReactNode;
  progressLabel?: ReactNode;
  note?: ReactNode;
  className?: string;
  inputLabel?: string;
  onRejectedDrop?: (reason: RejectedDropReason) => void;
  onFiles: (files: File[]) => void | Promise<void>;
};

export default function FileDropZone({
  accept,
  multiple = true,
  disabled = false,
  busy = false,
  progress = null,
  label = "i18n:govoplan-core.drop_files_here.77348907",
  actionLabel = "i18n:govoplan-core.or_click_to_select_files.91b05dc1",
  busyLabel = "i18n:govoplan-core.uploading_files.6536791d",
  progressLabel,
  note,
  className = "",
  inputLabel = "i18n:govoplan-core.drop_files_here_or_click_to_select_files.7eda8608",
  onRejectedDrop,
  onFiles
}: FileDropZoneProps) {
  const inputRef = useRef<HTMLInputElement | null>(null);
  const [dragActive, setDragActive] = useState(false);
  const progressValue = typeof progress === "number" && Number.isFinite(progress) ? Math.max(0, Math.min(100, progress)) : null;
  const showProgress = busy || progressValue !== null;
  const interactionDisabled = disabled || busy;
  const zoneClassName = `file-drop-zone ${dragActive ? "is-active" : ""} ${showProgress ? "is-busy" : ""} ${className}`.trim();
  const roundedProgress = progressValue === null ? null : Math.round(progressValue);
  const progressStyle = progressValue === null ? undefined : { "--file-drop-progress": `${progressValue}%` } as CSSProperties;

  async function handleFiles(fileList: FileList | File[]) {
    if (interactionDisabled) return;
    const files = Array.from(fileList);
    if (files.length === 0) return;
    try {
      await onFiles(files);
    } finally {
      if (inputRef.current) inputRef.current.value = "";
    }
  }

  function prepareFileDrag(event: ReactDragEvent<HTMLDivElement>) {
    event.preventDefault();
    event.stopPropagation();
    event.dataTransfer.dropEffect = interactionDisabled ? "none" : "copy";
    if (!interactionDisabled) setDragActive(true);
  }

  return (
    <>
      <div
        className={zoneClassName}
        role="button"
        tabIndex={interactionDisabled ? -1 : 0}
        aria-label={inputLabel}
        aria-disabled={interactionDisabled}
        aria-busy={showProgress || undefined}
        onClick={() => {
          if (!interactionDisabled) inputRef.current?.click();
        }}
        onKeyDown={(event) => {
          if ((event.key === "Enter" || event.key === " ") && !interactionDisabled) {
            event.preventDefault();
            inputRef.current?.click();
          }
        }}
        onDragEnter={prepareFileDrag}
        onDragOver={prepareFileDrag}
        onDragLeave={(event) => {
          event.preventDefault();
          event.stopPropagation();
          if (event.relatedTarget instanceof Node && event.currentTarget.contains(event.relatedTarget)) return;
          setDragActive(false);
        }}
        onDrop={(event) => {
          event.preventDefault();
          event.stopPropagation();
          setDragActive(false);
          if (interactionDisabled) {
            onRejectedDrop?.("disabled");
            return;
          }
          void resolveDroppedFiles(event.dataTransfer).then((files) => {
            if (files.length === 0) {
              onRejectedDrop?.("empty");
              return;
            }
            void handleFiles(files);
          }).catch(() => onRejectedDrop?.("unreadable"));
        }}>
        
        {showProgress ?
        <span
          className={`file-drop-progress ${progressValue === null ? "is-indeterminate" : ""}`.trim()}
          role="progressbar"
          aria-label="i18n:govoplan-core.upload_progress.927d75fe"
          aria-valuemin={0}
          aria-valuemax={100}
          aria-valuenow={roundedProgress ?? undefined}
          style={progressStyle}>
          
            <span>{roundedProgress === null ? "" : i18nMessage("i18n:govoplan-core.value.8c5f2c0e", { value0: roundedProgress })}</span>
          </span> :

        <UploadCloud size={28} aria-hidden="true" />
        }
        <strong>{showProgress ? busyLabel : label}</strong>
        <span>{showProgress ? progressLabel ?? (roundedProgress === null ? "i18n:govoplan-core.uploading.d921a79a" : i18nMessage("i18n:govoplan-core.value_uploaded.2c4bcc60", { value0: roundedProgress })) : actionLabel}</span>
        {note && <span className="muted small-text">{note}</span>}
      </div>
      <input
        ref={inputRef}
        type="file"
        accept={accept}
        multiple={multiple}
        hidden
        onChange={(event) => event.target.files && void handleFiles(event.target.files)} />
      
    </>);

}
