import {
  Typography,
  Button,
  Box,
  Accordion,
  AccordionSummary,
  AccordionDetails,
  useTheme,
  TextField,
} from "@mui/material";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import { axiosInstance } from "../providers/data";
import { useForm, Controller } from "react-hook-form";
import { MarkdownEditor } from "./MarkdownEditor";
import React, { useState, useCallback, useEffect } from "react";
import { useDropzone } from "react-dropzone";
import {
  ALLOWED_IMAGE_TYPES,
  ALLOWED_VIDEO_TYPES,
} from "../components/media/MediaFormUtils";
import { EVERY_LANGUAGE, Languages } from "@stores";
import { useNotification } from "@refinedev/core";

const MemoizedSimpleMDE = React.memo(MarkdownEditor);

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

type Props = {
  parentId?: string | number;
  parentResource: string;
  childResource: string;
  title: string;
  left?: boolean;
  language: Languages;
  setHeadingParent?: (heading: string) => void;
  setBodyParent?: (body: string) => void;
  onSave?: (something: any) => void;
  noReset?: boolean;
};

export const CreateSightArticle = ({
  parentId,
  parentResource,
  childResource,
  title,
  left,
  language,
  setHeadingParent,
  setBodyParent,
  onSave,
  noReset,
}: Props) => {
  const notification = useNotification();
  const theme = useTheme();
  const [mediaFiles, setMediaFiles] = useState<MediaFile[]>([]);
  const [workingLanguage, setWorkingLanguage] = useState<Languages>(language);

  const {
    register: registerItem,
    watch,
    control: controlItem,
    handleSubmit: handleSubmitItem,
    reset: resetItem,
    setValue,
    formState: { errors: itemErrors },
  } = useForm({
    defaultValues: {
      heading: "",
      body: "",
    },
  });

  const [articleData, setArticleData] = useState({
    heading: EVERY_LANGUAGE(""),
    body: EVERY_LANGUAGE(""),
  });

  function updateTranslations() {
    const newArticleData = {
      ...articleData,
      heading: {
        ...articleData.heading,
        [workingLanguage]: watch("heading") ?? "",
      },
      body: {
        ...articleData.body,
        [workingLanguage]: watch("body") ?? "",
      },
    };
    setArticleData(newArticleData);
    return newArticleData;
  }

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

  useEffect(() => {
    updateTranslations();
    setWorkingLanguage(language);
  }, [language]);

  useEffect(() => {
    setHeadingParent?.(watch("heading"));
    setBodyParent?.(watch("body"));
  }, [watch("heading"), watch("body"), setHeadingParent, setBodyParent]);

  const simpleMDEOptions = React.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/jpeg": [".jpeg", ".jpg"],
      "image/png": [".png"],
      "image/webp": [".webp"],
      "video/mp4": [".mp4"],
      "video/webm": [".webm"],
      "video/ogg": [".ogg"],
    },
    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 handleCreate = async (data: { heading: string; body: string }) => {
    try {
      // Создаем статью
      const response = await axiosInstance.post(
        `${import.meta.env.VITE_KRBL_API}/${childResource}`,
        {
          ...data,
          translations: updateTranslations(),
        }
      );
      const itemId = response.data.id;

      if (parentId) {
        // Получаем существующие статьи для определения порядкового номера
        const existingItemsResponse = await axiosInstance.get(
          `${
            import.meta.env.VITE_KRBL_API
          }/${parentResource}/${parentId}/${childResource}`
        );
        const existingItems = existingItemsResponse.data ?? [];
        const nextPageNum = existingItems.length + 1;

        if (!left) {
          await axiosInstance.post(
            `${
              import.meta.env.VITE_KRBL_API
            }/${parentResource}/${parentId}/${childResource}/`,
            {
              [`${childResource}_id`]: itemId,
              page_num: nextPageNum,
            }
          );
        } else {
          const response = await axiosInstance.get(
            `${import.meta.env.VITE_KRBL_API}/${parentResource}/${parentId}/`
          );
          const data = response.data;
          if (data) {
            await axiosInstance.patch(
              `${import.meta.env.VITE_KRBL_API}/${parentResource}/${parentId}/`,
              {
                ...data,
                left_article: itemId,
              }
            );
          }
        }
      }

      // Загружаем все медиа файлы и получаем их ID
      const mediaIds = await Promise.all(
        mediaFiles.map(async (mediaFile) => {
          return await uploadMedia(mediaFile);
        })
      );

      // Привязываем все медиа к статье
      await Promise.all(
        mediaIds.map((mediaId, index) =>
          axiosInstance.post(
            `${import.meta.env.VITE_KRBL_API}/article/${itemId}/media/`,
            {
              media_id: mediaId,
              media_order: index + 1,
            }
          )
        )
      );
      if (noReset) {
        setValue("heading", "");
        setValue("body", "");
      } else {
        resetItem();
      }
      if (onSave) {
        onSave(response.data);
        if (notification && typeof notification.open === "function") {
          notification.open({
            message: "Статья успешно создана",
            type: "success",
          });
        }
      } else {
        window.location.reload();
      }
    } catch (err: any) {
      console.error("Error creating item:", err);
    }
  };

  const removeMedia = (index: number) => {
    setMediaFiles((prev) => {
      const newFiles = [...prev];
      URL.revokeObjectURL(newFiles[index].preview);
      newFiles.splice(index, 1);
      return newFiles;
    });
  };

  return (
    <Box>
      <TextField
        {...registerItem("heading", {
          required: "Это поле является обязательным",
        })}
        error={!!(itemErrors as any)?.heading}
        helperText={(itemErrors as any)?.heading?.message}
        margin="normal"
        fullWidth
        slotProps={{ inputLabel: { shrink: true } }}
        type="text"
        sx={{
          backgroundColor: theme.palette.background.paper,
        }}
        label="Заголовок *"
      />

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

      {/* 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>

      <Box sx={{ mt: 2, display: "flex", gap: 2 }}>
        <Button
          variant="contained"
          color="primary"
          type="submit"
          onClick={handleSubmitItem(handleCreate)}
        >
          Создать
        </Button>
        <Button
          variant="outlined"
          onClick={() => {
            resetItem();
            mediaFiles.forEach((file) => URL.revokeObjectURL(file.preview));
            setMediaFiles([]);
          }}
        >
          Очистить
        </Button>
      </Box>
    </Box>
  );
};
