import { Box, Button } from "@mui/material";
import { MediaViewer } from "@widgets";
import {
  PreviewMediaDialog,
  filterValidFiles,
  getAllAcceptString,
} from "@shared";
import { X, Upload } from "lucide-react";
import { observer } from "mobx-react-lite";
import { useState, DragEvent, useRef } from "react";
import { toast } from "react-toastify";

interface MediaAreaProps {
  articleId: number;
  mediaIds: { id: string; media_type: number; filename: string }[];
  deleteMedia: (id: number, media_id: string) => void;
  onFilesDrop?: (files: File[]) => void;
  setSelectMediaDialogOpen: (open: boolean) => void;
}

export const MediaArea = observer(
  ({
    articleId,
    mediaIds,
    deleteMedia,
    onFilesDrop,
    setSelectMediaDialogOpen,
  }: MediaAreaProps) => {
    const [mediaModal, setMediaModal] = useState<boolean>(false);
    const [mediaId, setMediaId] = useState<string>("");
    const [isDragging, setIsDragging] = useState<boolean>(false);
    const fileInputRef = useRef<HTMLInputElement>(null);

    const handleMediaModal = (mediaId: string) => {
      setMediaModal(true);
      setMediaId(mediaId);
    };

    const processFiles = (files: File[]) => {
      if (!files.length || !onFilesDrop) {
        return;
      }

      const { validFiles, errors } = filterValidFiles(files);

      if (errors.length > 0) {
        errors.forEach((error) => toast.error(error));
      }

      if (validFiles.length > 0) {
        onFilesDrop(validFiles);
      }
    };

    const handleDrop = (e: DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      e.stopPropagation();
      setIsDragging(false);

      const files = Array.from(e.dataTransfer.files);
      processFiles(files);
    };

    const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      setIsDragging(true);
    };

    const handleDragLeave = () => {
      setIsDragging(false);
    };

    const handleClick = () => {
      fileInputRef.current?.click();
    };

    const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
      const files = Array.from(event.target.files || []);
      processFiles(files);

      if (event.target) {
        event.target.value = "";
      }
    };

    return (
      <>
        <input
          type="file"
          ref={fileInputRef}
          onChange={handleFileSelect}
          accept={getAllAcceptString()}
          multiple
          style={{ display: "none" }}
        />
        <Box className="w-full flex flex-col items-center justify-center border rounded-md p-4">
          <div className="w-full flex flex-col items-center justify-center">
            <div
              className={`w-full h-40 flex flex-col justify-center items-center text-gray-400 border-dashed border-2 rounded-md border-gray-400 p-4 cursor-pointer hover:bg-gray-50 transition-colors ${
                isDragging ? "bg-blue-100 border-blue-400" : ""
              }`}
              onDrop={handleDrop}
              onDragOver={handleDragOver}
              onDragLeave={handleDragLeave}
              onClick={handleClick}
            >
              <Upload size={32} className="mb-2" />
              <span className="text-center">
                Перетащите медиа файлы сюда или нажмите для выбора
              </span>
            </div>
            <div className="my-2">или</div>
            <Button
              variant="contained"
              color="primary"
              onClick={() => setSelectMediaDialogOpen(true)}
            >
              Выбрать существующие медиа файлы
            </Button>
          </div>

          {mediaIds.length > 0 && (
            <div className="w-full flex flex-start flex-wrap gap-2 mt-4 py-10">
              {mediaIds.map((m) => (
                <button
                  className="relative w-[100px] h-[80px]"
                  key={m.id}
                  onClick={() => handleMediaModal(m.id)}
                  type="button"
                >
                  <MediaViewer
                    media={{
                      id: m.id,
                      media_type: m.media_type,
                      filename: m.filename,
                    }}
                    compact
                  />
                  <button
                    className="absolute top-2 right-2 bg-white rounded-full p-1 shadow-md hover:shadow-lg transition-shadow"
                    onClick={(e) => {
                      e.stopPropagation();
                      deleteMedia(articleId, m.id);
                    }}
                    type="button"
                    aria-label="Удалить медиа"
                  >
                    <X size={16} color="red" />
                  </button>
                </button>
              ))}
            </div>
          )}
        </Box>

        <PreviewMediaDialog
          open={mediaModal}
          onClose={() => setMediaModal(false)}
          mediaId={mediaId}
        />
      </>
    );
  }
);
