window.jQuery(document).ready(() => {
  function changeLibraryPosition() {
    if (document.querySelector(".brandy-patterns-library-wrapper")) {
      setTimeout(() => {
        if (document.querySelector(".brandy-patterns-library-wrapper")) {
          observer.disconnect();
        }
      }, 1000);
      return;
    }

    const Modal = wp.components.Modal;
    const { Spinner, SearchControl, Button } = wp.components;
    const BlockPatternList = wp.blockEditor.__experimentalBlockPatternsList;
    const { __ } = wp.i18n;

    // Create a React element for the App using wp.element
    const { createElement, createRoot, useState, useMemo, useCallback } =
      wp.element;
    const { useSelect, useDispatch } = wp.data;
    const { cloneBlock, createBlock } = wp.blocks;
    const { store: noticesStore } = wp.notices;

    // Patterns Library Content Component
    const PatternsLibraryContent = ({ onCloseDialog, patternsData }) => {
      const [searchValue, setSearchValue] = useState("");
      const [selectedCategory, setSelectedCategory] = useState("brandy-call-to-action");

      // Use provided patterns data if available, otherwise fetch from store
      const storePatternsData = useSelect(
        (select) => {
          // If patterns data provided via props, skip fetching from store
          if (patternsData) {
            return { patterns: [], patternCategories: [] };
          }

          const blockEditorStore = select("core/block-editor");
          const coreStore = select("core");

          if (!blockEditorStore || !coreStore) {
            return { patterns: [], patternCategories: [] };
          }

          const settings = blockEditorStore.getSettings();

          // Get patterns from both block editor and core store
          let allPatterns =
            blockEditorStore.__experimentalGetAllowedPatterns?.() || [];

          // If no patterns from block editor, try from settings directly
          if (
            allPatterns.length === 0 &&
            settings.__experimentalBlockPatterns
          ) {
            allPatterns = settings.__experimentalBlockPatterns;
          }

          // If still no patterns, try from core store
          if (allPatterns.length === 0) {
            const corePatterns = coreStore.getBlockPatterns?.() || [];
            allPatterns = corePatterns;
          }

          // Filter Brandy patterns
          const brandyPatterns = allPatterns.filter((pattern) =>
            pattern.categories?.some((cat) =>
              cat.toLowerCase().includes("brandy")
            )
          );

          return {
            patterns: brandyPatterns,
            patternCategories:
              settings.__experimentalBlockPatternCategories?.filter((cat) =>
                cat.name.toLowerCase().includes("brandy")
              ) || [],
          };
        },
        [patternsData]
      );

      // Use patterns from props if available, otherwise from store
      const patterns = patternsData?.patterns || storePatternsData.patterns;
      const patternCategories =
        patternsData?.categories || storePatternsData.patternCategories;

      // Filter patterns based on category and search
      const filteredPatterns = useMemo(() => {
        let filtered = patterns;

        // Filter by category
        if (selectedCategory !== "all") {
          filtered = filtered.filter((pattern) =>
            pattern.categories?.includes(selectedCategory)
          );
        }

        // Filter by search
        if (searchValue) {
          filtered = filtered.filter((pattern) =>
            pattern.title.toLowerCase().includes(searchValue.toLowerCase())
          );
        }

        // Ensure all patterns have required properties for BlockPatternList
        // Parse blocks from content if not already parsed
        return filtered.map((pattern) => {
          let blocks = pattern.blocks;

          // If blocks don't exist, parse them from content
          if (!blocks && pattern.content && wp.blocks && wp.blocks.parse) {
            try {
              blocks = wp.blocks.parse(pattern.content);
            } catch (e) {
              blocks = [];
            }
          }

          return {
            ...pattern,
            name: pattern.name || pattern.slug || `pattern-${Math.random()}`,
            title: pattern.title || "Untitled Pattern",
            categories: pattern.categories || [],
            content: pattern.content || "",
            description: pattern.description || "",
            blockTypes: pattern.blockTypes || [],
            blocks: blocks || [],
          };
        });
      }, [patterns, selectedCategory, searchValue]);

      // Handle pattern insertion
      const { createSuccessNotice } = useDispatch(noticesStore);
      const { insertBlocks } = useDispatch("core/block-editor");

      const onClickPattern = useCallback(
        (pattern, blocks) => {
          const insertionPoint =
            wp.data.select("core/block-editor").getBlockInsertionPoint()
              ?.rootClientId || "";

          insertBlocks(blocks, undefined, insertionPoint);

          createSuccessNotice(`Pattern "${pattern.title}" inserted.`, {
            type: "snackbar",
            id: "inserter-notice",
          });

          onCloseDialog();
        },
        [insertBlocks, createSuccessNotice, onCloseDialog]
      );

      // Prepare categories list
      const categoriesList = useMemo(() => {
        if (!patternCategories || patternCategories.length === 0) {
          return [
            {
              name: "all",
              label: __("All Brandy Patterns") || "All Brandy Patterns",
            },
          ];
        }

        const cats = [...patternCategories]
          .sort((a, b) => (a.name || "").localeCompare(b.name || ""))
          .filter((cat) => cat.name !== "brandy");

        return [
          ...cats,
          {
            name: "all",
            label: __("All Brandy Patterns") || "All Brandy Patterns",
          },
        ];
      }, [patternCategories]);

      return createElement(
        "div",
        { className: "block-editor-block-patterns-explorer" },
        createElement(
          "div",
          { className: "block-editor-block-patterns-explorer__sidebar" },
          createElement(SearchControl, {
            __nextHasNoMarginBottom: true,
            onChange: setSearchValue,
            value: searchValue,
            label: __("Search") || "Search",
            placeholder: __("Search") || "Search",
            className: "block-editor-block-patterns-explorer__search",
          }),
          createElement(
            "div",
            {
              className:
                "block-editor-block-patterns-explorer__sidebar__categories-list",
            },
            categoriesList.map(({ name, label }) =>
              createElement(
                Button,
                {
                  __next40pxDefaultSize: true,
                  key: name,
                  label: label,
                  className:
                    "block-editor-block-patterns-explorer__sidebar__categories-list__item",
                  isPressed: selectedCategory === name,
                  onClick: () => setSelectedCategory(name),
                },
                label
              )
            )
          )
        ),
        createElement(
          "div",
          { className: "block-editor-block-patterns-explorer__list" },
          filteredPatterns.length > 0
            ? createElement(BlockPatternList, {
                blockPatterns: filteredPatterns,
                onClickPattern: onClickPattern,
                isDraggable: false,
              })
            : createElement(
                "div",
                {
                  style: {
                    padding: "40px",
                    textAlign: "center",
                    color: "#757575",
                  },
                },
                createElement(
                  "p",
                  null,
                  "No patterns found. Try refreshing the page or check if Brandy Blocks is properly activated."
                )
              )
        )
      );
    };

    const App = () => {
      const [openDialog, setOpenDialog] = useState(false);
      const [isInstalling, setIsInstalling] = useState(false);
      const [installError, setInstallError] = useState(null);
      const [isPluginInstalled, setIsPluginInstalled] = useState(false);
      const [isLoadingPatterns, setIsLoadingPatterns] = useState(false);
      const [patternsData, setPatternsData] = useState(null);

      // Check if plugin is already installed (from PHP)
      const isPluginAlreadyInstalled =
        brandyPatternsLibrary.isBrandyBlocksInstalled || false;
      const pluginBasename =
        brandyPatternsLibrary.brandyBlocksPluginBasename ||
        "brandy-blocks/brandy-blocks.php";

      const handleOpenDialog = () => {
        setOpenDialog(true);
      };

      const handleInstallPlugin = async () => {
        setIsInstalling(true);
        setInstallError(null);

        try {
          let pluginFile = pluginBasename;
          let pluginName = "Brandy Blocks";

          // Step 1: Install the plugin only if not already installed
          if (!isPluginAlreadyInstalled) {
            const installFormData = new URLSearchParams();
            installFormData.append("action", "install-plugin");
            installFormData.append("slug", "brandy-blocks");
            installFormData.append("_wpnonce", brandyPatternsLibrary.nonce);

            const installResponse = await fetch(
              brandyPatternsLibrary.ajaxUrl,
              {
                method: "POST",
                headers: {
                  "Content-Type": "application/x-www-form-urlencoded",
                },
                body: installFormData.toString(),
              }
            );

            const installResult = await installResponse.json();

            if (!installResult.success) {
              throw new Error(
                installResult.data?.errorMessage || "Failed to install plugin"
              );
            }

            pluginFile = installResult.data?.plugin || pluginBasename;
            pluginName = installResult.data?.pluginName || "Brandy Blocks";
          }

          // Step 2: Activate the plugin
          const activateFormData = new URLSearchParams();
          activateFormData.append("action", "activate-plugin");
          activateFormData.append("slug", "brandy-blocks");
          activateFormData.append("plugin", pluginFile);
          activateFormData.append("name", pluginName);
          activateFormData.append("_wpnonce", brandyPatternsLibrary.nonce);

          const activateResponse = await fetch(brandyPatternsLibrary.ajaxUrl, {
            method: "POST",
            headers: {
              "Content-Type": "application/x-www-form-urlencoded",
            },
            body: activateFormData.toString(),
          });

          const activateResult = await activateResponse.json();

          if (!activateResult.success) {
            throw new Error(
              activateResult.data?.errorMessage || "Failed to activate plugin"
            );
          }

          // Plugin installed and activated successfully
          // Fetch patterns data and parse them
          setIsLoadingPatterns(true);
          await loadPatternsLibrary();
          setIsPluginInstalled(true);
          setIsLoadingPatterns(false);
        } catch (error) {
          setInstallError(error.message);
        } finally {
          setIsInstalling(false);
        }
      };

      const loadPatternsLibrary = async () => {
        try {
          // Wait a bit for WordPress to activate the plugin
          await new Promise((resolve) => setTimeout(resolve, 1500));

          // Fetch patterns via custom AJAX endpoint
          const formData = new URLSearchParams();
          formData.append("action", "brandy_get_patterns_after_activation");
          formData.append("nonce", brandyPatternsLibrary.patternsNonce);
          formData.append("_nocache", Date.now());

          const response = await fetch(brandyPatternsLibrary.ajaxUrl, {
            method: "POST",
            headers: {
              "Content-Type": "application/x-www-form-urlencoded",
              "Cache-Control": "no-cache, no-store, must-revalidate",
              Pragma: "no-cache",
            },
            body: formData.toString(),
          });

          const result = await response.json();

          if (!result.success) {
            throw new Error(result.data?.message || "Failed to fetch patterns");
          }

          // Set patterns data to state
          setPatternsData(result.data);
        } catch (error) {
          setInstallError(
            "Plugin activated but patterns failed to load. Please refresh the page."
          );
        }
      };

      return createElement(
        "div",
        { className: "brandy-patterns-library-wrapper" },
        createElement(
          "button",
          { className: "button", onClick: handleOpenDialog },
          "Brandy Patterns Library"
        ),
        openDialog &&
          createElement(
            Modal,
            {
              title: "Brandy Patterns Library",
              onRequestClose: () => {
                setOpenDialog(false);
              },
              open: openDialog,
              isFullScreen: isPluginInstalled,
            },
            createElement(
              "div",
              { className: "brandy-patterns-library-dialog" },
              isLoadingPatterns
                ? createElement(
                    "div",
                    {
                      className: "brandy-patterns-library-loading",
                      style: {
                        display: "flex",
                        alignItems: "center",
                        justifyContent: "center",
                        padding: "40px",
                        flexDirection: "column",
                        gap: "20px",
                      },
                    },
                    createElement(Spinner),
                    createElement("p", null, "Loading patterns library...")
                  )
                : isPluginInstalled
                ? createElement(PatternsLibraryContent, {
                    onCloseDialog: () => setOpenDialog(false),
                    patternsData: patternsData,
                  })
                : createElement(
                    "div",
                    { className: "brandy-patterns-library-install-prompt" },
                    createElement(
                      "p",
                      { className: "brandy-patterns-library-dialog-content" },
                      createElement(
                        "span",
                        {
                          className:
                            "brandy-patterns-library-dialog-content-text",
                        },
                        isPluginAlreadyInstalled
                          ? "Please activate Brandy Blocks plugin to use the patterns library."
                          : "Please install Brandy Blocks plugin to use the patterns library."
                      )
                    ),
                    createElement(
                      "button",
                      {
                        className: "button button-primary",
                        onClick: handleInstallPlugin,
                        disabled: isInstalling,
                        style: { marginTop: "15px" },
                      },
                      isInstalling
                        ? createElement(
                            "span",
                            null,
                            createElement(Spinner),
                            isPluginAlreadyInstalled
                              ? " Activating..."
                              : " Installing..."
                          )
                        : isPluginAlreadyInstalled
                        ? "Activate Plugin"
                        : "Install & Activate"
                    ),
                    installError &&
                      createElement(
                        "p",
                        {
                          className: "brandy-patterns-library-error",
                          style: { color: "red", marginTop: "10px" },
                        },
                        installError
                      )
                  )
            )
          )
      );
    };

    const library = document.createElement("div");
    createRoot(library).render(createElement(App));

    setTimeout(() => {
      if (document.querySelector(".brandy-patterns-library-wrapper")) {
        return;
      }
      document
        .querySelector(".editor-document-tools__left")
        .appendChild(library);
    }, 1);
  }

  const observer = new MutationObserver(function (mutations) {
    changeLibraryPosition();
  });

  if (!window.wp) {
    return;
  }

  const { registerPlugin } = window.wp.plugins ?? {};
  const { PluginSidebar } = window.wp.editSite ?? window.wp.editPost ?? {};

  if (PluginSidebar) {
    registerPlugin("brandy-patterns-library", {
      render: function () {
        const interval = setInterval(() => {
          const targetElement = document.querySelector(
            ".editor-header__toolbar"
          );

          if (targetElement) {
            observer.observe(
              document.querySelector(".editor-header__toolbar"),
              {
                childList: true,
                subtree: true,
              }
            );

            changeLibraryPosition();
            clearInterval(interval);
          }
        }, 100);
      },
    });
  }
});
