import {
  Box,
  Button,
  Typography,
  TextField,
  Slider,
  Stack,
} from "@mui/material";
import {
  BackButton,
  createSightStore,
  editSightStore,
  languageStore,
  TabPanel,
  SelectMediaDialog,
  UploadMediaDialog,
  Media,
} from "@shared";
import {
  LanguageSwitcher,
  MediaArea,
  MediaAreaForSight,
  ReactMarkdownEditor,
  DeleteModal,
} from "@widgets";
import { Plus, Save, Trash2, Unlink, X } from "lucide-react";
import { observer } from "mobx-react-lite";
import { useState, useEffect, useRef } from "react";
import { useNavigate } from "react-router-dom";
import { MediaViewer } from "../../MediaViewer/index";
import { toast } from "react-toastify";
import { authInstance } from "@shared";
import { DragDropContext, Droppable, Draggable } from "@hello-pangea/dnd";
import { SightFramePreview } from "../RightWidgetTab/SightFramePreview";

type MediaItemShared = {
  id: string;
  filename: string;
  media_name?: string;
  media_type: number;
};

export const CreateRightTab = observer(
  ({ value, index }: { value: number; index: number }) => {
    const {
      sight,
      createNewRightArticle,
      updateRightArticleInfo,
      linkPreviewMedia,
      unlinkPreviewMedia,
      createLinkWithRightArticle,
      deleteRightArticleMedia,
      unlinkRightAritcle,
      deleteRightArticle,
      createSight,
      updateRightArticles,
      updateSightInfo,
    } = createSightStore;
    const { language } = languageStore;
    const navigate = useNavigate();
    const { setFileToUpload, setUploadMediaOpen, uploadMediaOpen } =
      editSightStore;

    const [activeArticleIndex, setActiveArticleIndex] = useState<number | null>(
      null,
    );
    const [type, setType] = useState<"article" | "media">("media");
    const [previewSection, setPreviewSection] = useState<number>(-1);
    const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
    const [isSelectMediaDialogOpen, setIsSelectMediaDialogOpen] =
      useState(false);
    const [mediaTarget, setMediaTarget] = useState<
      "sightPreview" | "rightArticle" | null
    >(null);

    const [previewMedia, setPreviewMedia] = useState<Media | null>(null);
    const shortNameRef = useRef<HTMLTextAreaElement | null>(null);

    const insertNewline = () => {
      const input = shortNameRef.current;
      const currentValue = sight[language].name || "";
      if (!input) {
        updateSightInfo({ name: currentValue + "\n" }, language);
        return;
      }
      const start = input.selectionStart ?? currentValue.length;
      const end = input.selectionEnd ?? start;
      const newValue =
        currentValue.slice(0, start) + "\n" + currentValue.slice(end);
      updateSightInfo({ name: newValue }, language);
      requestAnimationFrame(() => {
        if (shortNameRef.current) {
          shortNameRef.current.selectionStart = start + 1;
          shortNameRef.current.selectionEnd = start + 1;
          shortNameRef.current.focus();
        }
      });
    };

    useEffect(() => {
      if (sight.preview_media) {
        const fetchMedia = async () => {
          const response = await authInstance.get(
            `/media/${sight.preview_media}`,
          );
          setPreviewMedia(response.data);
        };
        fetchMedia();
      }
    }, [sight.preview_media]);

    useEffect(() => {
      if (
        activeArticleIndex !== null &&
        activeArticleIndex >= sight[language].right.length
      ) {
        setActiveArticleIndex(null);
        setType("media");
        setPreviewSection(-1);
      }
    }, [language, sight[language].right, activeArticleIndex]);

    const handleSave = async () => {
      try {
        const newSightId = await createSight(language);
        console.log("[handleSave] newSightId:", newSightId, "needLeaveAgree:", createSightStore.needLeaveAgree);
        toast.success("Достопримечательность успешно создана!");
        navigate(`/sight/${newSightId}/edit`);
        console.log("[handleSave] navigate called to:", `/sight/${newSightId}/edit`);
      } catch (error) {
        console.error("Failed to save sight:", error);
        toast.error("Ошибка при создании достопримечательности.");
      }
    };

    const handleDisplayArticleFromList = (idx: number) => {
      setActiveArticleIndex(idx);
      setType("article");
      setPreviewSection(idx);
    };

    const handleCreateNewLocalArticle = async () => {
      try {
        const newArticleId = await createNewRightArticle();

        const newIndex = sight[language].right.findIndex(
          (a) => a.id === newArticleId,
        );
        const resolvedIndex =
          newIndex > -1 ? newIndex : sight[language].right.length - 1;
        setActiveArticleIndex(resolvedIndex);
        setType("article");
        setPreviewSection(resolvedIndex);
      } catch (error) {
        toast.error("Не удалось создать новую статью.");
      }
    };

    const currentRightArticle =
      activeArticleIndex !== null && sight[language].right[activeArticleIndex]
        ? sight[language].right[activeArticleIndex]
        : null;

    const handleOpenUploadMedia = () => {
      setUploadMediaOpen(true);
    };

    const handleOpenSelectMediaDialog = (
      target: "sightPreview" | "rightArticle",
    ) => {
      setMediaTarget(target);
      setIsSelectMediaDialogOpen(true);
    };

    const handleMediaSelectedFromDialog = async (media: MediaItemShared) => {
      setIsSelectMediaDialogOpen(false);

      if (mediaTarget === "sightPreview") {
        await linkPreviewMedia(media.id);
      } else if (mediaTarget === "rightArticle" && currentRightArticle) {
        await createLinkWithRightArticle(media, currentRightArticle.id);
      }
      setMediaTarget(null);
    };

    const handleUnlinkPreviewMedia = async () => {
      await unlinkPreviewMedia();
      setPreviewMedia(null);
    };

    const handleMediaUploaded = async (media: MediaItemShared) => {
      setUploadMediaOpen(false);
      setFileToUpload(null);
      if (mediaTarget === "sightPreview") {
        linkPreviewMedia(media.id);
      } else if (mediaTarget === "rightArticle" && currentRightArticle) {
        await createLinkWithRightArticle(media, currentRightArticle.id);
      }
      setMediaTarget(null);
    };

    const handleDragEnd = (result: any) => {
      const { source, destination } = result;

      if (!destination) return;

      const sourceIndex = source.index;
      const destinationIndex = destination.index;

      if (sourceIndex === destinationIndex) return;

      const newRightArticles = [...sight[language].right];
      const [movedArticle] = newRightArticles.splice(sourceIndex, 1);
      newRightArticles.splice(destinationIndex, 0, movedArticle);
      updateRightArticles(newRightArticles);
    };

    return (
      <TabPanel value={value} index={index}>
        <LanguageSwitcher />
        <Box
          sx={{
            display: "flex",
            flexDirection: "column",
            height: "100%",
            minHeight: "calc(100vh - 200px)",
            gap: 2,
            paddingBottom: "70px",
            position: "relative",
          }}
        >
          <div className="flex gap-10 items-center mb-5 max-w-[80%]">
            <BackButton />
            <h1 className="text-3xl break-words">{sight[language].name}</h1>
          </div>

          <Box sx={{ display: "flex", flexGrow: 1, gap: 2.5 }}>
            <Box
              className="flex flex-col gap-2"
              sx={{ flexGrow: 1, minWidth: 0 }}
            >
              <Box className="w-full flex gap-2">
                <Box className="relative w-[20%] h-[70vh] flex flex-col rounded-2xl overflow-y-auto gap-3 border border-gray-300 p-3">
                  <Box className="flex flex-col gap-3 max-h-[60vh] overflow-y-auto">
                    <Box
                      onClick={() => {
                        setType("media");
                        setPreviewSection(-1);
                      }}
                      className={`w-full p-4 rounded-2xl cursor-pointer text-sm transition-all duration-300 ${
                        type === "media"
                          ? "bg-blue-400 text-white"
                          : "bg-gray-200 hover:bg-gray-300"
                      }`}
                    >
                      <Typography>Предпросмотр медиа</Typography>
                    </Box>
                    <Box>
                      <DragDropContext onDragEnd={handleDragEnd}>
                        <Droppable droppableId="articles">
                          {(provided) => (
                            <Box
                              ref={provided.innerRef}
                              {...provided.droppableProps}
                              className="flex flex-col gap-2"
                            >
                              {sight[language].right.length > 0
                                ? sight[language].right.map(
                                    (article, index) => (
                                      <Draggable
                                        key={article.id.toString()}
                                        draggableId={article.id.toString()}
                                        index={index}
                                      >
                                        {(provided, snapshot) => (
                                          <Box
                                            ref={provided.innerRef}
                                            {...provided.draggableProps}
                                            className={`w-full p-4 rounded-2xl text-sm cursor-pointer transition-all duration-300 ${
                                              snapshot.isDragging
                                                ? "shadow-lg bg-gray-200"
                                                : activeArticleIndex ===
                                                      index &&
                                                    type === "article"
                                                  ? "bg-blue-400 text-white"
                                                  : "bg-gray-200 hover:bg-gray-300"
                                            }`}
                                            onClick={() => {
                                              handleDisplayArticleFromList(
                                                index,
                                              );
                                            }}
                                          >
                                            <Box {...provided.dragHandleProps}>
                                              <Typography>
                                                {article.heading}
                                              </Typography>
                                            </Box>
                                          </Box>
                                        )}
                                      </Draggable>
                                    ),
                                  )
                                : null}
                              {provided.placeholder}
                            </Box>
                          )}
                        </Droppable>
                      </DragDropContext>
                    </Box>
                  </Box>
                  <button
                    className="w-10 h-10 bg-blue-500 rounded-full absolute bottom-5 left-5 flex items-center justify-center hover:bg-blue-600"
                    onClick={handleCreateNewLocalArticle}
                  >
                    <Plus size={20} color="white" />
                  </button>
                </Box>

                {type === "article" && currentRightArticle ? (
                  <Box className="w-[80%] border border-gray-300 p-3 flex flex-col gap-2 overflow-hidden">
                    <Box className="flex justify-end gap-2 mb-1 flex-shrink-0">
                      <Button
                        variant="contained"
                        color="primary"
                        size="small"
                        startIcon={<Unlink color="white" size={18} />}
                        onClick={() => {
                          if (currentRightArticle) {
                            unlinkRightAritcle(currentRightArticle.id);
                            setActiveArticleIndex(null);
                            setType("media");
                            setPreviewSection(-1);
                          }
                        }}
                      >
                        Открепить
                      </Button>
                      <Button
                        variant="contained"
                        color="error"
                        size="small"
                        startIcon={<Trash2 size={18} />}
                        onClick={() => setIsDeleteModalOpen(true)}
                      >
                        Удалить
                      </Button>
                    </Box>
                    <Box
                      sx={{
                        flexGrow: 1,
                        display: "flex",
                        flexDirection: "column",
                        gap: 2,
                        overflowY: "auto",
                        pt: 7,
                      }}
                    >
                      <TextField
                        label="Название информации (правый виджет)"
                        value={currentRightArticle.heading}
                        onChange={(e) =>
                          activeArticleIndex !== null &&
                          updateRightArticleInfo(
                            activeArticleIndex,
                            language,
                            e.target.value,
                            currentRightArticle.body,
                          )
                        }
                        variant="outlined"
                        fullWidth
                      />
                      <Box sx={{ minHeight: 200, flexGrow: 1 }}>
                        <ReactMarkdownEditor
                          value={currentRightArticle.body}
                          onChange={(mdValue: any) =>
                            activeArticleIndex !== null &&
                            updateRightArticleInfo(
                              activeArticleIndex,
                              language,
                              currentRightArticle.heading,
                              mdValue || "",
                            )
                          }
                        />
                      </Box>
                      <MediaArea
                        articleId={currentRightArticle.id}
                        mediaIds={currentRightArticle.media || []}
                        onFilesDrop={(files) => {
                          if (files.length > 0) {
                            setFileToUpload(files[0]);
                            setMediaTarget("rightArticle");
                            handleOpenUploadMedia();
                          }
                        }}
                        deleteMedia={deleteRightArticleMedia}
                        setSelectMediaDialogOpen={() =>
                          handleOpenSelectMediaDialog("rightArticle")
                        }
                      />
                    </Box>
                  </Box>
                ) : (
                  <Box className="w-[80%] border border-gray-300 rounded-2xl relative flex justify-center items-center">
                    {sight.preview_media && (
                      <Box className="w-full h-full rounded-2xl relative flex items-center justify-center">
                        {previewMedia && (
                          <>
                            <Box className="absolute top-4 right-4 z-10">
                              <button
                                className="w-10 h-10 flex items-center justify-center z-10"
                                onClick={handleUnlinkPreviewMedia}
                              >
                                <X size={20} color="red" />
                              </button>
                            </Box>
                            <Box className="w-1/2 h-1/2 flex justify-center items-center">
                              <MediaViewer
                                media={{
                                  id: previewMedia.id || "",
                                  media_type: previewMedia.media_type,
                                  filename: previewMedia.filename || "",
                                }}
                                fullWidth
                                fullHeight
                              />
                            </Box>
                          </>
                        )}
                      </Box>
                    )}

                    {!sight.preview_media && (
                      <Box className="w-full h-full flex justify-center items-center">
                        <Box
                          sx={{
                            maxWidth: "500px",
                            maxHeight: "100%",
                            display: "flex",
                            flexGrow: 1,
                            margin: "0 auto",
                            justifyContent: "center",
                          }}
                        >
                          <MediaAreaForSight
                            onFinishUpload={(mediaId) => {
                              linkPreviewMedia(mediaId);
                            }}
                            onFilesDrop={() => {}}
                            contextObjectName={sight[language].name}
                            contextType="sight"
                            isArticle={false}
                          />
                        </Box>
                      </Box>
                    )}
                  </Box>
                )}
              </Box>
            </Box>

            <Box
              sx={{
                flexShrink: 0,
                width: "550px",
                display: "flex",
                flexDirection: "column",
                gap: 1,
              }}
            >
              {type === "media" && (
                <Stack direction="row" spacing={2} alignItems="center">
                  <TextField
                    type="number"
                    label="Размер шрифта превью (px)"
                    size="small"
                    value={sight.preview_font_size ?? ""}
                    onChange={(e) => {
                      const raw = e.target.value;
                      if (raw === "") {
                        updateSightInfo({ preview_font_size: undefined });
                        return;
                      }
                      const val = Math.max(
                        1,
                        Math.min(300, Math.round(Number(raw))),
                      );
                      if (Number.isFinite(val)) {
                        updateSightInfo({ preview_font_size: val });
                      }
                    }}
                    slotProps={{ input: { min: 1, max: 300 } }}
                    sx={{ width: "200px" }}
                  />
                  <Slider
                    value={sight.preview_font_size ?? 40}
                    min={1}
                    max={300}
                    step={1}
                    onChange={(_, newValue) => {
                      if (typeof newValue === "number") {
                        updateSightInfo({ preview_font_size: newValue });
                      }
                    }}
                    sx={{ flexGrow: 1 }}
                  />
                </Stack>
              )}
              <Stack direction="row" spacing={1} alignItems="flex-start">
                <TextField
                  label="Полное название (поддерживает перенос ↵)"
                  multiline
                  minRows={1}
                  maxRows={4}
                  size="small"
                  value={sight[language].name}
                  onChange={(e) =>
                    updateSightInfo({ name: e.target.value }, language)
                  }
                  inputRef={shortNameRef}
                  sx={{ flexGrow: 1 }}
                />
                <Button
                  variant="outlined"
                  size="small"
                  onClick={insertNewline}
                  title="Вставить перенос строки"
                  sx={{
                    minWidth: 40,
                    height: 40,
                    fontSize: 18,
                    p: 0,
                    flexShrink: 0,
                  }}
                >
                  ↵
                </Button>
              </Stack>
              <SightFramePreview
                sightName={sight[language].name}
                previewMedia={previewMedia}
                articles={sight[language].right}
                onArticleSelect={(idx) => {
                  handleDisplayArticleFromList(idx);
                }}
                previewFontSize={sight.preview_font_size}
                selectedSection={previewSection}
                onSectionChange={(section) => {
                  setPreviewSection(section);
                  if (section === -1) {
                    setType("media");
                  } else {
                    handleDisplayArticleFromList(section);
                  }
                }}
              />
            </Box>
          </Box>

          <Box
            sx={{
              position: "absolute",
              bottom: "-20px",
              left: 0,
              right: 0,
              padding: 2,
              backgroundColor: "background.paper",
              width: "100%",
              display: "flex",
              justifyContent: "flex-end",
            }}
          >
            <Button
              variant="contained"
              color="success"
              onClick={handleSave}
              size="large"
              startIcon={<Save color="white" size={18} />}
            >
              Сохранить
            </Button>
          </Box>
        </Box>

        <UploadMediaDialog
          open={uploadMediaOpen}
          onClose={() => {
            setUploadMediaOpen(false);
            setFileToUpload(null);
            setMediaTarget(null);
          }}
          contextObjectName={sight[language].name}
          contextType="sight"
          isArticle={mediaTarget === "rightArticle"}
          articleName={
            mediaTarget === "rightArticle" && activeArticleIndex !== null
              ? sight[language].right[activeArticleIndex].heading
              : undefined
          }
          afterUpload={handleMediaUploaded}
        />
        <SelectMediaDialog
          open={isSelectMediaDialogOpen}
          onClose={() => {
            setIsSelectMediaDialogOpen(false);
            setMediaTarget(null);
          }}
          onSelectMedia={handleMediaSelectedFromDialog}
        />
        <DeleteModal
          open={isDeleteModalOpen}
          onDelete={async () => {
            try {
              const idx = activeArticleIndex ?? 0;
              await deleteRightArticle(currentRightArticle?.id || 0);
              setIsDeleteModalOpen(false);
              if (idx > 0) {
                setActiveArticleIndex(idx - 1);
                setPreviewSection(idx - 1);
                setType("article");
              } else {
                setActiveArticleIndex(null);
                setPreviewSection(-1);
                setType("media");
              }
              toast.success("Статья удалена");
            } catch {
              toast.error("Не удалось удалить статью");
            }
          }}
          onCancel={() => setIsDeleteModalOpen(false)}
        />
      </TabPanel>
    );
  },
);
