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

export const RightWidgetTab = observer(
  ({ value, index }: { value: number; index: number }) => {
    const {
      sight,
      updateRightArticleInfo,
      getRightArticles,
      updateSight,
      updateSightInfo,
      unlinkPreviewMedia,
      linkPreviewMedia,
      unlinkRightArticle,
      deleteRightArticle,
      deleteRightArticleMedia,
      createLinkWithRightArticle,
      setFileToUpload,
      createNewRightArticle,
      updateRightArticles,
    } = editSightStore;

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

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

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

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

    const [uploadMediaOpen, setUploadMediaOpen] = useState(false);
    const { language } = languageStore;
    const [type, setType] = useState<"article" | "media">("media");
    useEffect(() => {
      const fetchData = async () => {
        if (sight.common.id) {
          await getRightArticles(sight.common.id);
        }
      };
      fetchData();
    }, [sight.common.id]);

    const [activeArticleIndex, setActiveArticleIndex] = useState<number | null>(
      null
    );
    const [previewSection, setPreviewSection] = useState<number>(-1);
    const [isSelectMediaModalOpen, setIsSelectMediaModalOpen] = useState(false);
    const [isDeleteArticleModalOpen, setIsDeleteArticleModalOpen] =
      useState(false);

    const handleDeleteArticle = () => {
      const idx = activeArticleIndex || 0;
      deleteRightArticle(sight[language].right[idx].id);
      if (idx > 0) {
        setActiveArticleIndex(idx - 1);
        setPreviewSection(idx - 1);
        setType("article");
      } else {
        setActiveArticleIndex(null);
        setPreviewSection(-1);
        setType("media");
      }
    };

    const handleSelectArticle = (index: number) => {
      setActiveArticleIndex(index);
    };

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

        const newIndex = sight[language].right.findIndex(
          (article) => article.id === newArticleId
        );
        if (newIndex > -1) {
          setActiveArticleIndex(newIndex);
          setType("article");
          setPreviewSection(newIndex);
        }
      } catch (error) {
        console.error("Error creating new article:", error);
      }
    };

    const handleMediaSelected = async (media: {
      id: string;
      filename: string;
      media_name?: string;
      media_type: number;
    }) => {
      await createLinkWithRightArticle(
        media,
        sight[language].right[activeArticleIndex || 0].id
      );
    };

    const handleSave = async () => {
      await updateSight();
      toast.success("Достопримечательность сохранена");
    };

    const handleDragEnd = (result: DropResult) => {
      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.replace(/\n/g, " ")}</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={() => {
                                              handleSelectArticle(index);
                                              setType("article");
                                              setPreviewSection(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"
                    onClick={handleCreateNew}
                  >
                    <Plus size={20} color="white" />
                  </button>
                </Box>

                {type === "article" && (
                  <Box className="w-[80%] border border-gray-300  p-3">
                    {activeArticleIndex !== null && (
                      <>
                        <Box className="flex justify-end gap-2 mb-3">
                          <Button
                            variant="contained"
                            color="primary"
                            startIcon={<Unlink color="white" size={18} />}
                            onClick={() => {
                              unlinkRightArticle(
                                sight[language].right[activeArticleIndex].id
                              );
                              setActiveArticleIndex(null);
                            }}
                          >
                            Открепить
                          </Button>
                          <Button
                            variant="contained"
                            color="error"
                            startIcon={<Trash2 size={18} />}
                            onClick={() => {
                              setIsDeleteArticleModalOpen(true);
                            }}
                          >
                            Удалить
                          </Button>
                        </Box>
                        <Box sx={{ display: "flex", gap: 3, flexGrow: 1 }}>
                          <Box
                            sx={{
                              flex: 2,
                              display: "flex",
                              flexDirection: "column",
                              gap: 2,
                              maxHeight: "70%",
                            }}
                          >
                            <TextField
                              label="Название информации"
                              value={
                                sight[language].right[activeArticleIndex]
                                  .heading
                              }
                              onChange={(e) =>
                                updateRightArticleInfo(
                                  activeArticleIndex,
                                  language,
                                  e.target.value,
                                  sight[language].right[activeArticleIndex].body
                                )
                              }
                              variant="outlined"
                              fullWidth
                            />

                            <ReactMarkdownEditor
                              value={
                                sight[language].right[activeArticleIndex].body
                              }
                              onChange={(value: any) =>
                                updateRightArticleInfo(
                                  activeArticleIndex,
                                  language,
                                  sight[language].right[activeArticleIndex]
                                    .heading,
                                  value
                                )
                              }
                            />

                            <MediaArea
                              articleId={
                                sight[language].right[activeArticleIndex].id
                              }
                              mediaIds={
                                sight[language].right[activeArticleIndex].media
                              }
                              onFilesDrop={(files) => {
                                setFileToUpload(files[0]);
                                setUploadMediaOpen(true);
                              }}
                              deleteMedia={deleteRightArticleMedia}
                              setSelectMediaDialogOpen={() => {
                                setIsSelectMediaModalOpen(true);
                              }}
                            />
                          </Box>
                        </Box>
                      </>
                    )}
                  </Box>
                )}
                {type === "media" && (
                  <Box className="w-[80%] border border-gray-300 rounded-2xl relative flex justify-center items-center">
                    {sight.common.preview_media && (
                      <>
                        {type === "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.common.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.common.preview_font_size ?? ""}
                    onChange={(e) => {
                      const raw = e.target.value;
                      if (raw === "") {
                        updateSightInfo(language, { preview_font_size: undefined }, true);
                        return;
                      }
                      const val = Math.max(1, Math.min(300, Math.round(Number(raw))));
                      if (Number.isFinite(val)) {
                        updateSightInfo(language, { preview_font_size: val }, true);
                      }
                    }}
                    slotProps={{ input: { min: 1, max: 300 } }}
                    sx={{ width: "200px" }}
                  />
                  <Slider
                    value={sight.common.preview_font_size ?? 40}
                    min={1}
                    max={300}
                    step={1}
                    onChange={(_, newValue) => {
                      if (typeof newValue === "number") {
                        updateSightInfo(language, { preview_font_size: newValue }, true);
                      }
                    }}
                    sx={{ flexGrow: 1 }}
                  />
                </Stack>
              )}
              {type === "media" && (
                <Stack direction="row" spacing={1} alignItems="flex-start">
                  <TextField
                    label="Полное название (поддерживает перенос ↵)"
                    multiline
                    minRows={1}
                    maxRows={4}
                    size="small"
                    value={sight[language].name}
                    onChange={(e) => updateSightInfo(language, { name: e.target.value })}
                    onKeyDown={(e) => {
                      if (e.key === "Enter") {
                        e.preventDefault();
                        insertNewline();
                      }
                    }}
                    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) => {
                  handleSelectArticle(idx);
                  setType("article");
                  setPreviewSection(idx);
                }}
                previewFontSize={sight.common.preview_font_size}
                selectedSection={previewSection}
                onSectionChange={(section) => {
                  setPreviewSection(section);
                  if (section === -1) {
                    setType("media");
                  } else {
                    handleSelectArticle(section);
                    setType("article");
                  }
                }}
              />
            </Box>
          </Box>

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

        <UploadMediaDialog
          open={uploadMediaOpen}
          onClose={() => setUploadMediaOpen(false)}
          contextObjectName={sight[language].name}
          contextType="sight"
          isArticle={true}
          articleName={
            activeArticleIndex !== null
              ? sight[language].right[activeArticleIndex].heading
              : "Правая статья"
          }
          afterUpload={async (media) => {
            setUploadMediaOpen(false);
            setFileToUpload(null);
            await createLinkWithRightArticle(
              media,
              sight[language].right[activeArticleIndex || 0].id
            );
          }}
        />

        <DeleteModal
          open={isDeleteArticleModalOpen}
          onCancel={() => setIsDeleteArticleModalOpen(false)}
          onDelete={() => {
            handleDeleteArticle();
            setIsDeleteArticleModalOpen(false);
          }}
        />

        <SelectMediaDialog
          open={isSelectMediaModalOpen}
          onClose={() => setIsSelectMediaModalOpen(false)}
          onSelectMedia={handleMediaSelected}
        />
      </TabPanel>
    );
  }
);
