import { clx } from "@/helpers/utils";
import { usePageTitle } from "@/hooks/usePageTitle";
import Konva from "konva";
import { type FC, useEffect, useRef, useState } from "react";
import { useParams } from "react-router-dom";
import { useSharedStore } from "@/shared/store/sharedStore";
import {
  useGetCatalogById,
  useUpdateCatalog,
} from "@/pages/catalogue/hooks/useCatalogueData";
import EditorCanvas from "./components/EditorCanvas";
import EditorSidebar from "./components/EditorSidebar";
import LayersPanel from "./components/LayersPanel";
import { useEditorStore } from "./store/editorStore";

const Editor: FC = () => {
  const { id } = useParams();

  // Konva 10 با legacyTextRendering=false متن را با baseline جدید می‌کشد ولی getWidth/getHeight
  // و کادر ترنسفورمر هنوز بر اساس جعبهٔ قدیمی‌اند؛ نتیجه: متن از کادر آبی بیرون می‌زند.
  useEffect(() => {
    const prev = Konva.legacyTextRendering;
    Konva.legacyTextRendering = true;
    return () => {
      Konva.legacyTextRendering = prev;
    };
  }, []);
  const [isLayersPanelOpen, setIsLayersPanelOpen] = useState(false);
  const [isInitialContentReady, setIsInitialContentReady] = useState(false);
  const loadedCatalogIdRef = useRef<string | null>(null);
  const skipNextAutosaveRef = useRef(true);
  const {
    loadPages,
    resetEditor,
    pages,
    documentSettings,
    gallery,
    objects,
    currentPageId,
  } = useEditorStore();
  const { setEditorCatalogSlug } = useSharedStore();
  const { data, isFetched } = useGetCatalogById(id!);
  const catalogName = data?.data?.name;

  useEffect(() => {
    setEditorCatalogSlug(null);
  }, [id, setEditorCatalogSlug]);

  useEffect(() => {
    if (data?.data?.slug) {
      setEditorCatalogSlug(data.data.slug);
    }
  }, [data?.data?.slug, setEditorCatalogSlug]);

  useEffect(
    () => () => {
      setEditorCatalogSlug(null);
    },
    [setEditorCatalogSlug],
  );
  usePageTitle(
    catalogName ? `ویرایش کاتالوگ ${catalogName}` : "ویرایش کاتالوگ",
  );
  const { scheduleUpdate, cancelPendingUpdate, isSaving } = useUpdateCatalog();

  // هنگام تعویض کاتالوگ: لغو ذخیرهٔ معلق، پاک‌سازی store، و منتظر بارگذاری مجدد بمان
  useEffect(() => {
    cancelPendingUpdate();
    loadedCatalogIdRef.current = null;
    skipNextAutosaveRef.current = true;
    setIsInitialContentReady(false);
    resetEditor();
  }, [id, cancelPendingUpdate, resetEditor]);

  // بارگذاری محتوا فقط یک‌بار برای هر id (نه در هر refetch)
  useEffect(() => {
    if (!id || !isFetched) return;
    if (loadedCatalogIdRef.current === id) return;

    const rawContent = data?.data?.content;
    if (rawContent) {
      try {
        const json = JSON.parse(rawContent);
        if (Array.isArray(json)) {
          loadPages(json);
        } else if (json?.pages) {
          loadPages(json.pages, json.documentSettings, json.gallery);
        } else {
          console.error("Invalid catalog content JSON: missing pages");
          return;
        }
      } catch (error) {
        console.error("Invalid catalog content JSON:", error);
        return;
      }
    } else {
      resetEditor();
    }

    loadedCatalogIdRef.current = id;
    skipNextAutosaveRef.current = true;
    setIsInitialContentReady(true);
  }, [id, isFetched, data?.data?.content, loadPages, resetEditor]);

  useEffect(() => {
    if (!id) return;
    if (!isInitialContentReady) return;
    if (!pages || pages.length === 0) return;
    if (skipNextAutosaveRef.current) {
      skipNextAutosaveRef.current = false;
      return;
    }

    const pagesToSave = currentPageId
      ? pages.map((p) => (p.id === currentPageId ? { ...p, objects } : p))
      : pages;

    scheduleUpdate({
      id,
      content: JSON.stringify({
        pages: pagesToSave,
        documentSettings,
        gallery,
      }),
    });
    // عمداً scheduleUpdate را در وابستگی‌ها نیاوردیم تا از لوپ ذخیره‌سازی جلوگیری شود
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    id,
    isInitialContentReady,
    pages,
    documentSettings,
    gallery,
    objects,
    currentPageId,
  ]);

  return (
    <div
      className={clx(
        "flex h-full w-full",
        isLayersPanelOpen ? "xl:pl-[296px]" : "xl:pl-[80px]",
      )}
    >
      {isSaving ? (
        <div className="fixed bottom-10 left-10 z-50 rounded-full  shadow-sm">
          <div className="flex items-center gap-2 text-sm text-gray-700">
            <span className="h-4 w-4 animate-spin rounded-full border-2 border-gray-300 border-t-black" />
          </div>
        </div>
      ) : null}
      <LayersPanel
        isOpen={isLayersPanelOpen}
        setIsOpen={setIsLayersPanelOpen}
        catalogSize={data?.data?.size}
      />
      <EditorCanvas catalogSize={data?.data?.size} />
      <EditorSidebar catalogSize={data?.data?.size} />
    </div>
  );
};

export default Editor;
