import { Modal, Box, Button, TextField, Typography } from "@mui/material";
import { articleStore } from "../../../store/ArticleStore";
import { observer } from "mobx-react-lite";
import { useForm } from "@refinedev/react-hook-form";
import { Controller } from "react-hook-form";
import "easymde/dist/easymde.min.css";
import { memo, useMemo, useEffect, useCallback, useState } from "react";
import { MarkdownEditor } from "../../MarkdownEditor";
import { Edit } from "@refinedev/mui";
import { EVERY_LANGUAGE, languageStore } from "../../../store/LanguageStore";
import { LanguageSwitch } from "../../LanguageSwitch/index";
import { useDropzone } from "react-dropzone";
import {
  ALLOWED_IMAGE_TYPES,
  ALLOWED_VIDEO_TYPES,
} from "../../media/MediaFormUtils";
import { TOKEN_KEY, axiosInstance } from "@providers";
import { LinkedItems } from "../../../components/LinkedItems";
import { mediaFields, MediaItem } from "../../../pages/article/types";

const MemoizedSimpleMDE = memo(MarkdownEditor);

type MediaFile = {
  file: File;
  preview: string;
  uploading: boolean;
  media_id?: number;
};

const style = {
  marginLeft: "auto",
  marginRight: "auto",
  //position: "absolute",
  //top: "50%",
  //left: "50%",
  //transform: "translate(-50%, -50%)",
  width: "60%",
  bgcolor: "background.paper",
  border: "2px solid #000",
  boxShadow: 24,
  p: 4
};

export const ArticleEditModal = observer(() => {
  const { language } = languageStore;
  const [articleData, setArticleData] = useState({
    heading: EVERY_LANGUAGE(language),
    body: EVERY_LANGUAGE(language),
  });
  const { articleModalOpen, setArticleModalOpenAction, selectedArticleId } =
    articleStore;

  const [mediaFiles, setMediaFiles] = useState<MediaFile[]>([]);

  const [refresh, setRefresh] = useState(0);

  useEffect(() => {
    return () => {
      setArticleModalOpenAction(false);
    };
  }, []);

  // Load existing media files when editing an article
  const loadExistingMedia = async () => {
    console.log("Called loadExistingMedia")
    if (selectedArticleId) {
      try {
        const response = await axiosInstance.get(
          `${
            import.meta.env.VITE_KRBL_API
          }/article/${selectedArticleId}/media`
        );
        const existingMedia = response.data;

        // Convert existing media to MediaFile format
        const mediaFiles = await Promise.all(
          existingMedia.map(async (media: any) => {
            const response = await fetch(
              `${import.meta.env.VITE_KRBL_MEDIA}${
                media.id
              }/download?token=${localStorage.getItem(TOKEN_KEY)}`
            );
            const blob = await response.blob();
            const file = new File([blob], media.filename, {
              type: media.media_type === 1 ? "image/jpeg" : "video/mp4",
            });

            return {
              file,
              preview: URL.createObjectURL(blob),
              uploading: false,
              mediaId: media.id,
            };
          })
        );

        setMediaFiles(mediaFiles);
        setRefresh(refresh+1);
      } catch (error) {
        console.error("Error loading existing media:", error);
      }
    }
  };

  useEffect(() => {
    loadExistingMedia();
  }, [selectedArticleId]);

  const {
    register,
    control,
    formState: { errors },
    saveButtonProps,
    reset,
    setValue,
    watch,
  } = useForm({
    refineCoreProps: {
      resource: "article",
      id: selectedArticleId ?? undefined,
      action: "edit",
      redirect: false,

      onMutationSuccess: async () => {
        try {
          // Upload new media files
          const newMediaFiles = mediaFiles.filter((file) => !file.media_id);
          const existingMediaAmount = mediaFiles.filter((file) => file.media_id).length;
          const mediaIds = await Promise.all(
            newMediaFiles.map(async (mediaFile) => {
              return await uploadMedia(mediaFile);
            })
          );

          // Associate all media with the article
          await Promise.all(
            mediaIds.map((mediaId, index) =>
              axiosInstance.post(
                `${
                  import.meta.env.VITE_KRBL_API
                }/article/${selectedArticleId}/media/`,
                {
                  media_id: mediaId,
                  media_order: index + existingMediaAmount + 1,
                }
              )
            )
          );

          setArticleModalOpenAction(false);
          reset();
          window.location.reload();
        } catch (error) {
          console.error("Error handling media:", error);
        }
      },
      meta: {
        headers: {
          "Accept-Language": language,
        },
      },
    },
  });

  useEffect(() => {
    if (articleData.heading[language]) {
      setValue("heading", articleData.heading[language])
    }
    if (articleData.body[language]) {
      setValue("body", articleData.body[language])
    }
  }, [language, articleData, setValue]);

  const handleLanguageChange = () => {
    setArticleData((prevData) => ({
      ...prevData,
      heading: {
        ...prevData.heading,
        [language]: watch("heading") ?? ""
      },
      body: {
        ...prevData.body,
        [language]: watch("body") ?? ""
      }
    }));
  };

  const simpleMDEOptions = useMemo(
    () => ({
      placeholder: "Введите контент в формате Markdown...",
      spellChecker: false,
    }),
    []
  );

  const onDrop = useCallback((acceptedFiles: File[]) => {
    const newFiles = acceptedFiles.map((file) => ({
      file,
      preview: URL.createObjectURL(file),
      uploading: false,
    }));
    setMediaFiles((prev) => [...prev, ...newFiles]);
  }, []);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    accept: {
      "image/*": ALLOWED_IMAGE_TYPES,
      "video/*": ALLOWED_VIDEO_TYPES,
    },
    multiple: true,
  });

  const uploadMedia = async (mediaFile: MediaFile) => {
    const formData = new FormData();
    formData.append("media_name", mediaFile.file.name);
    formData.append("filename", mediaFile.file.name);
    formData.append(
      "type",
      mediaFile.file.type.startsWith("image/") ? "1" : "2"
    );
    formData.append("file", mediaFile.file);

    const response = await axiosInstance.post(
      `${import.meta.env.VITE_KRBL_API}/media`,
      formData
    );
    return response.data.id;
  };

  const removeMedia = async (index: number) => {
    const mediaFile = mediaFiles[index];

    // If it's an existing media file (has mediaId), delete it from the server
    if (mediaFile.media_id) {
      try {
        await axiosInstance.delete(
          `${import.meta.env.VITE_KRBL_API}/media/${mediaFile.media_id}`
        );
      } catch (error) {
        console.error("Error deleting media:", error);
        return; // Don't remove from UI if server deletion failed
      }
    }

    // Remove from UI and cleanup
    setMediaFiles((prev) => {
      const newFiles = [...prev];
      URL.revokeObjectURL(newFiles[index].preview);
      newFiles.splice(index, 1);
      return newFiles;
    });
  };

  return (
    <Modal
      open={articleModalOpen}
      onClose={() => setArticleModalOpenAction(false)}
      aria-labelledby="modal-modal-title"
      aria-describedby="modal-modal-description"
      sx={{overflow: "auto"}}
    >
      <Box sx={style}>
        <Edit
          title={<Typography variant="h5">Редактирование статьи</Typography>}
          headerProps={{
            sx: {
              fontSize: "50px",
            },
          }}
          saveButtonProps={saveButtonProps}
        >
          <LanguageSwitch action={handleLanguageChange} />
          <Box
            component="form"
            sx={{ display: "flex", flexDirection: "column" }}
            autoComplete="off"
          >
            <TextField
              {...register("heading", {
                required: "Это поле является обязательным",
              })}
              error={!!errors.heading}
              helperText={errors.heading?.message as string}
              margin="normal"
              fullWidth
              InputLabelProps={{ shrink: true }}
              type="text"
              name="heading"
              label="Заголовок *"
            />

            <Controller
              control={control}
              name="body"
              rules={{ required: "Это поле является обязательным" }}
              defaultValue=""
              render={({ field: { onChange, value } }) => (
                <MemoizedSimpleMDE
                  value={value}
                  onChange={onChange}
                  options={simpleMDEOptions}
                  className="my-markdown-editor"
                />
              )}
            />

            {selectedArticleId && (
              <LinkedItems<MediaItem>
                type="edit"
                parentId={selectedArticleId}
                parentResource="article"
                childResource="media"
                fields={mediaFields}
                title="медиа"
                dontRecurse
                onUpdate={loadExistingMedia}
              />
            )}
          </Box>

          {/* Dropzone для медиа файлов */}
          <Box sx={{ mt: 2, mb: 2 }}>
            <Box
              {...getRootProps()}
              sx={{
                border: "2px dashed",
                borderColor: isDragActive ? "primary.main" : "grey.300",
                borderRadius: 1,
                p: 2,
                textAlign: "center",
                cursor: "pointer",
                "&:hover": {
                  borderColor: "primary.main",
                },
              }}
            >
              <input {...getInputProps()} />
              <Typography>
                {isDragActive
                  ? "Перетащите файлы сюда..."
                  : "Перетащите файлы сюда или кликните для выбора"}
              </Typography>
            </Box>

            {/* Превью загруженных файлов */}
            <Box sx={{ mt: 2, display: "flex", flexWrap: "wrap", gap: 1 }}>
              {mediaFiles.map((mediaFile, index) => (
                <Box
                  key={mediaFile.preview}
                  sx={{
                    position: "relative",
                    width: 100,
                    height: 100,
                  }}
                >
                  {mediaFile.file.type.startsWith("image/") ? (
                    <img
                      src={mediaFile.preview}
                      alt={mediaFile.file.name}
                      style={{
                        width: "100%",
                        height: "100%",
                        objectFit: "cover",
                      }}
                    />
                  ) : (
                    <Box
                      sx={{
                        width: "100%",
                        height: "100%",
                        display: "flex",
                        alignItems: "center",
                        justifyContent: "center",
                        bgcolor: "grey.200",
                      }}
                    >
                      <Typography variant="caption">
                        {mediaFile.file.name}
                      </Typography>
                    </Box>
                  )}
                  <Button
                    size="small"
                    color="error"
                    onClick={() => removeMedia(index)}
                    sx={{
                      position: "absolute",
                      top: 0,
                      right: 0,
                      minWidth: "auto",
                      width: 20,
                      height: 20,
                      p: 0,
                    }}
                  >
                    ×
                  </Button>
                </Box>
              ))}
            </Box>
          </Box>
        </Edit>
      </Box>
    </Modal>
  );
});
