/**
 * my-editor.js — VvvebJS 儲存與新增頁面橋接腳本
 * 覆蓋 Vvveb.Builder.saveAjax 與 Vvveb.FileManager 行為，無縫串接到 Flask 後端，並引入精美網頁型暗黑系模態框
 */
(function () {
  "use strict";

  const SLUG = window.VVVEB_PROJECT_SLUG || "";

  // ── Toast 通知 ──────────────────────────────────────────────────
  function showToast(msg, type) {
    const existing = document.getElementById("vvveb-save-toast");
    if (existing) existing.remove();

    const toast = document.createElement("div");
    toast.id = "vvveb-save-toast";
    const bg = type === "error" ? "#7f1d1d" : "#14532d";
    const border = type === "error" ? "#ef444460" : "#22c55e60";
    Object.assign(toast.style, {
      position: "fixed",
      top: "1rem",
      right: "1rem",
      zIndex: "99999",
      background: bg,
      border: "1px solid " + border,
      color: "#fff",
      borderRadius: "8px",
      padding: "0.65rem 1.1rem",
      fontSize: "0.85rem",
      fontFamily: "Inter, system-ui, sans-serif",
      fontWeight: "500",
      boxShadow: "0 4px 20px rgba(0,0,0,0.5)",
      opacity: "0",
      transform: "translateY(-8px)",
      transition: "opacity 0.3s ease, transform 0.3s ease",
      pointerEvents: "none",
    });
    toast.textContent = msg;
    document.body.appendChild(toast);

    requestAnimationFrame(() => {
      toast.style.opacity = "1";
      toast.style.transform = "translateY(0)";
    });
    setTimeout(() => {
      toast.style.opacity = "0";
      toast.style.transform = "translateY(-8px)";
      setTimeout(() => toast.remove(), 350);
    }, 3000);
  }

  // ── 頂級網頁型模態框 (Web-based Custom Dialogs) ──────────────────────
  function showModalPrompt(title, defaultValue, callback) {
    const existing = document.getElementById("vvveb-custom-modal");
    if (existing) existing.remove();

    const overlay = document.createElement("div");
    overlay.id = "vvveb-custom-modal";
    Object.assign(overlay.style, {
      position: "fixed",
      top: "0",
      left: "0",
      width: "100%",
      height: "100%",
      zIndex: "100000",
      background: "rgba(10, 11, 18, 0.65)",
      backdropFilter: "blur(12px)",
      webkitBackdropFilter: "blur(12px)",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      opacity: "0",
      transition: "opacity 0.25s ease-out"
    });

    const card = document.createElement("div");
    Object.assign(card.style, {
      background: "rgba(22, 24, 38, 0.95)",
      border: "1px solid rgba(255, 255, 255, 0.08)",
      boxShadow: "0 20px 50px rgba(0, 0, 0, 0.6), 0 0 40px rgba(99, 102, 241, 0.1)",
      borderRadius: "16px",
      width: "420px",
      padding: "2rem",
      color: "#f8fafc",
      fontFamily: "Inter, system-ui, sans-serif",
      transform: "scale(0.95)",
      transition: "transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1)",
      display: "flex",
      flexDirection: "column",
      gap: "1.25rem"
    });

    card.innerHTML = `
      <div style="font-size: 1.15rem; font-weight: 600; color: #fff; display: flex; align-items: center; gap: 0.6rem;">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#818cf8" stroke-width="2">
          <path d="M11 4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
          <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
        </svg>
        ${title}
      </div>
      <div>
        <input type="text" id="vvveb-modal-input" style="
          width: 100%;
          background: rgba(13, 14, 24, 0.8);
          border: 1px solid rgba(255, 255, 255, 0.1);
          border-radius: 8px;
          padding: 0.65rem 0.9rem;
          color: #fff;
          font-size: 0.9rem;
          outline: none;
          transition: border-color 0.2s, box-shadow 0.2s;
        " />
      </div>
      <div style="display: flex; justify-content: flex-end; gap: 0.75rem; margin-top: 0.5rem;">
        <button id="vvveb-modal-cancel" style="
          background: transparent;
          border: 1px solid rgba(255, 255, 255, 0.1);
          border-radius: 8px;
          padding: 0.55rem 1.1rem;
          color: #94a3b8;
          font-size: 0.85rem;
          font-weight: 500;
          cursor: pointer;
          transition: background 0.2s, color 0.2s;
        ">取消</button>
        <button id="vvveb-modal-confirm" style="
          background: #4f46e5;
          border: none;
          border-radius: 8px;
          padding: 0.55rem 1.25rem;
          color: #fff;
          font-size: 0.85rem;
          font-weight: 600;
          cursor: pointer;
          transition: background 0.2s;
          box-shadow: 0 4px 12px rgba(79, 70, 229, 0.3);
        ">確定</button>
      </div>
    `;

    overlay.appendChild(card);
    document.body.appendChild(overlay);

    const input = card.querySelector("#vvveb-modal-input");
    input.value = defaultValue;
    input.addEventListener("focus", () => {
      input.style.borderColor = "#818cf8";
      input.style.boxShadow = "0 0 12px rgba(129, 140, 248, 0.25)";
    });
    input.addEventListener("blur", () => {
      input.style.borderColor = "rgba(255, 255, 255, 0.1)";
      input.style.boxShadow = "none";
    });

    const cancelBtn = card.querySelector("#vvveb-modal-cancel");
    cancelBtn.addEventListener("mouseover", () => {
      cancelBtn.style.background = "rgba(255, 255, 255, 0.05)";
      cancelBtn.style.color = "#fff";
    });
    cancelBtn.addEventListener("mouseout", () => {
      cancelBtn.style.background = "transparent";
      cancelBtn.style.color = "#94a3b8";
    });

    const confirmBtn = card.querySelector("#vvveb-modal-confirm");
    confirmBtn.addEventListener("mouseover", () => {
      confirmBtn.style.background = "#4338ca";
    });
    confirmBtn.addEventListener("mouseout", () => {
      confirmBtn.style.background = "#4f46e5";
    });

    // Fade in
    setTimeout(() => {
      overlay.style.opacity = "1";
      card.style.transform = "scale(1)";
    }, 10);

    input.focus();
    input.select();

    function close(value) {
      overlay.style.opacity = "0";
      card.style.transform = "scale(0.95)";
      setTimeout(() => {
        overlay.remove();
        if (value !== undefined) {
          const finalVal = value.trim ? value.trim() : value;
          callback(finalVal);
        }
      }, 250);
    }

    cancelBtn.onclick = () => close();
    confirmBtn.onclick = () => close(input.value);
    
    input.onkeydown = (e) => {
      if (e.key === "Enter") {
        close(input.value);
      } else if (e.key === "Escape") {
        close();
      }
    };
  }

  function showModalConfirm(title, message, callback) {
    const existing = document.getElementById("vvveb-custom-modal");
    if (existing) existing.remove();

    const overlay = document.createElement("div");
    overlay.id = "vvveb-custom-modal";
    Object.assign(overlay.style, {
      position: "fixed",
      top: "0",
      left: "0",
      width: "100%",
      height: "100%",
      zIndex: "100000",
      background: "rgba(10, 11, 18, 0.65)",
      backdropFilter: "blur(12px)",
      webkitBackdropFilter: "blur(12px)",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      opacity: "0",
      transition: "opacity 0.25s ease-out"
    });

    const card = document.createElement("div");
    Object.assign(card.style, {
      background: "rgba(22, 24, 38, 0.95)",
      border: "1px solid rgba(255, 255, 255, 0.08)",
      boxShadow: "0 20px 50px rgba(0, 0, 0, 0.6), 0 0 40px rgba(239, 68, 68, 0.1)",
      borderRadius: "16px",
      width: "420px",
      padding: "2rem",
      color: "#f8fafc",
      fontFamily: "Inter, system-ui, sans-serif",
      transform: "scale(0.95)",
      transition: "transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1)",
      display: "flex",
      flexDirection: "column",
      gap: "1.25rem"
    });

    card.innerHTML = `
      <div style="font-size: 1.15rem; font-weight: 600; color: #fff; display: flex; align-items: center; gap: 0.6rem;">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2">
          <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
          <line x1="12" y1="9" x2="12" y2="13"/>
          <line x1="12" y1="17" x2="12.01" y2="17"/>
        </svg>
        ${title}
      </div>
      <div style="font-size: 0.9rem; color: #cbd5e1; line-height: 1.5;">
        ${message}
      </div>
      <div style="display: flex; justify-content: flex-end; gap: 0.75rem; margin-top: 0.5rem;">
        <button id="vvveb-modal-cancel" style="
          background: transparent;
          border: 1px solid rgba(255, 255, 255, 0.1);
          border-radius: 8px;
          padding: 0.55rem 1.1rem;
          color: #94a3b8;
          font-size: 0.85rem;
          font-weight: 500;
          cursor: pointer;
          transition: background 0.2s, color 0.2s;
        ">取消</button>
        <button id="vvveb-modal-confirm" style="
          background: #ef4444;
          border: none;
          border-radius: 8px;
          padding: 0.55rem 1.25rem;
          color: #fff;
          font-size: 0.85rem;
          font-weight: 600;
          cursor: pointer;
          transition: background 0.2s;
          box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);
        ">確定</button>
      </div>
    `;

    overlay.appendChild(card);
    document.body.appendChild(overlay);

    const cancelBtn = card.querySelector("#vvveb-modal-cancel");
    cancelBtn.addEventListener("mouseover", () => {
      cancelBtn.style.background = "rgba(255, 255, 255, 0.05)";
      cancelBtn.style.color = "#fff";
    });
    cancelBtn.addEventListener("mouseout", () => {
      cancelBtn.style.background = "transparent";
      cancelBtn.style.color = "#94a3b8";
    });

    const confirmBtn = card.querySelector("#vvveb-modal-confirm");
    confirmBtn.addEventListener("mouseover", () => {
      confirmBtn.style.background = "#dc2626";
    });
    confirmBtn.addEventListener("mouseout", () => {
      confirmBtn.style.background = "#ef4444";
    });

    // Fade in
    setTimeout(() => {
      overlay.style.opacity = "1";
      card.style.transform = "scale(1)";
    }, 10);

    confirmBtn.focus();

    function close(confirmed) {
      overlay.style.opacity = "0";
      card.style.transform = "scale(0.95)";
      setTimeout(() => {
        overlay.remove();
        if (confirmed) callback();
      }, 250);
    }

    cancelBtn.onclick = () => close(false);
    confirmBtn.onclick = () => close(true);

    const keyHandler = (e) => {
      if (e.key === "Escape") {
        close(false);
        window.removeEventListener("keydown", keyHandler);
      }
    };
    window.addEventListener("keydown", keyHandler);
  }

  // ── 覆蓋 Vvveb.Builder.saveAjax ──────────────────────────────────
  function patchSaveAjax() {
    if (typeof Vvveb === "undefined" || !Vvveb.Builder) {
      setTimeout(patchSaveAjax, 200);
      return;
    }

    /**
     * VvvebJS 原始簽名: saveAjax(data, saveUrl, callback, error)
     */
    Vvveb.Builder.saveAjax = function (data, saveUrl, callback, error) {
      if (!SLUG) {
        showToast("錯誤：找不到專案識別碼 (slug)", "error");
        if (error) error(new Error("Missing slug"));
        return;
      }

      // 確保 data 為物件並填入專案識別碼
      if (typeof data !== "object" || data === null) {
        data = {};
      }
      data.slug = SLUG;

      // 扁平化處理新檔案檔名
      if (data.file) {
        const parts = data.file.split("/");
        data.file = parts[parts.length - 1];
      }

      // 如果不是新增頁面（即一般的儲存頁面），且未帶有 HTML 內容，則動態獲取目前 HTML
      const isNewPage = !!data.startTemplateUrl;
      if (!isNewPage && !data.html) {
        try {
          data.html = Vvveb.Builder.getHtml ? Vvveb.Builder.getHtml() : "";
        } catch (e) {
          console.error("[my-editor] getHtml failed:", e);
        }
      }

      // 顯示儲存中狀態
      const saveBtn = document.querySelector(".save-btn");
      if (saveBtn && !isNewPage) {
        saveBtn.querySelector(".loading")?.classList.remove("d-none");
        saveBtn.querySelector(".button-text")?.classList.add("d-none");
      }

      // 發送 POST 請求至 Flask API
      fetch("/api/save", {
        method: "POST",
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        body: new URLSearchParams(data).toString(),
      })
        .then((res) => {
          if (!res.ok) {
            return res.json().then((errData) => {
              throw new Error(errData.error || "伺服器儲存錯誤");
            });
          }
          return res.json();
        })
        .then((resData) => {
          if (isNewPage) {
            // 新增頁面成功：秀出通知並執行 Vvveb 原生 callback 以載入新頁面
            showToast("✓ 成功建立新頁面：" + resData.file);
            if (callback) {
              callback({
                name: resData.name,
                title: resData.title,
                file: resData.file,
                url: resData.url
              });
            }
          } else {
            // 一般儲存成功
            showToast("✓ 已儲存：" + (resData.saved || data.file));
            if (callback) callback(resData);
            // 停用儲存按鈕（直至下一次變更）
            document.querySelectorAll("#top-panel .save-btn").forEach((e) =>
              e.setAttribute("disabled", "true")
            );
          }
        })
        .catch((err) => {
          showToast("儲存失敗：" + err.message, "error");
          if (error) error(err);
        })
        .finally(() => {
          if (saveBtn && !isNewPage) {
            saveBtn.querySelector(".loading")?.classList.add("d-none");
            saveBtn.querySelector(".button-text")?.classList.remove("d-none");
          }
        });
    };

    console.log("[my-editor] Robust Vvveb.Builder.saveAjax patched for slug:", SLUG);
  }

  // ── 覆蓋 Vvveb.FileManager 頁面操作 ──────────────────────────────
  function patchFileManager() {
    if (typeof Vvveb === "undefined" || !Vvveb.FileManager) {
      setTimeout(patchFileManager, 200);
      return;
    }

    // 覆蓋 init 方法以修正 VvvebJS 使用全球廢棄的 `event.target` 導致在某些瀏覽器/嚴格模式下點擊無效的 Bug
    const originalInit = Vvveb.FileManager.init;
    Vvveb.FileManager.init = function (allowedComponents = {}) {
      originalInit.call(this, allowedComponents);

      // 利用 Clone 移除舊有包含 Bug 的匿名字選區接聽器
      const newTree = this.tree.cloneNode(true);
      this.tree.parentNode.replaceChild(newTree, this.tree);
      this.tree = newTree;

      // 綁定符合標準且高度相容 (e.target) 的新接聽器
      this.tree.addEventListener("click", function (e) {
        let element = e.target.closest("a");
        if (element) {
          e.stopImmediatePropagation();
          if (element.classList.contains('view')) return;
          e.preventDefault();
          return false;
        }
      });

      this.tree.addEventListener("click", function (e) {
        let element = e.target.closest(".delete");
        if (element) {
          Vvveb.FileManager.deletePage(element.closest("li"), e);
          e.stopImmediatePropagation();
          e.preventDefault();
          return false;
        }
      });

      this.tree.addEventListener("click", function (e) {
        let element = e.target.closest(".rename");
        if (element) {
          Vvveb.FileManager.renamePage(element.closest("li"), e, false);
          e.stopImmediatePropagation();
          e.preventDefault();
          return false;
        }
      });

      this.tree.addEventListener("click", function (e) {
        let element = e.target.closest(".duplicate");
        if (element) {
          Vvveb.FileManager.renamePage(element.closest("li"), e, true);
          e.stopImmediatePropagation();
          e.preventDefault();
          return false;
        }
      });

      this.tree.addEventListener("click", function (e) {
        let element = e.target.closest("li[data-page] label");
        if (element) {
          let page = element.parentNode.dataset.page;
          if (page) {
            Vvveb.FileManager.loadPage(page);
            e.stopImmediatePropagation();
            e.preventDefault();
            return false;
          }
        }
      });
    };

    // 覆蓋重新命名 / 複製頁面
    Vvveb.FileManager.renamePage = function (element, e, duplicate = false) {
      let page = element.dataset;
      showModalPrompt(`請輸入 "${page.file}" 的新檔名：`, page.file, function (newfile) {
        if (!newfile) return;

        // 確保副檔名為 .html
        if (!newfile.endsWith(".html")) {
          newfile += ".html";
        }

        const bodyData = {
          slug: SLUG,
          file: page.file,
          newfile: newfile,
          duplicate: duplicate ? "true" : "false"
        };

        fetch(`/api/save?action=rename`, {
          method: "POST",
          headers: { "Content-Type": "application/x-www-form-urlencoded" },
          body: new URLSearchParams(bodyData).toString()
        })
          .then((res) => {
            if (!res.ok) {
              return res.json().then((err) => {
                throw new Error(err.error || "操作失敗");
              });
            }
            return res.json();
          })
          .then((data) => {
            showToast(`✓ ${data.message}`);
            let baseName = data.newfile.replace('.html', '');
            let newName = friendlyName(data.newfile.replace(/.*[\/\\]+/, '')).replace('.html', '');

            if (duplicate) {
              // 複製頁面：在 FileManager 中加入新頁面
              let pageData = Object.assign({}, Vvveb.FileManager.pages[page.page]);
              pageData["file"] = data.newfile;
              pageData["title"] = newName;
              pageData["url"] = data.url;
              pageData["name"] = baseName;
              Vvveb.FileManager.addPage(baseName, pageData);
            } else {
              // 重新命名：更新現有節點資訊
              const oldPageKey = page.page;
              Vvveb.FileManager.pages[oldPageKey]["file"] = data.newfile;
              Vvveb.FileManager.pages[oldPageKey]["title"] = newName;
              Vvveb.FileManager.pages[oldPageKey]["url"] = data.url;
              Vvveb.FileManager.pages[oldPageKey]["name"] = baseName;

              let link = element.querySelector("a.view");
              if (link) {
                link.setAttribute("href", data.url);
              }
              let span = element.querySelector("label > span");
              if (!span) {
                span = element.querySelector("span");
              }
              if (span) {
                span.textContent = newName;
              }
              element.dataset.file = data.newfile;
              element.dataset.page = baseName;
              
              // 將 key 重新綁定
              Vvveb.FileManager.pages[baseName] = Vvveb.FileManager.pages[oldPageKey];
              if (baseName !== oldPageKey) {
                delete Vvveb.FileManager.pages[oldPageKey];
              }
            }
          })
          .catch((err) => {
            showToast(`操作失敗：${err.message}`, "error");
          });
      });
    };

    // 覆蓋刪除頁面
    Vvveb.FileManager.deletePage = function (element, e) {
      let page = element.dataset;
      if (page.file.toLowerCase() === "index.html") {
        showToast("錯誤：無法刪除主頁 index.html", "error");
        return;
      }

      showModalConfirm("確認刪除頁面", `確定要刪除 "${page.file}" 頁面嗎？此動作將無法復原。`, function () {
        const bodyData = {
          slug: SLUG,
          file: page.file
        };

        fetch(`/api/save?action=delete`, {
          method: "POST",
          headers: { "Content-Type": "application/x-www-form-urlencoded" },
          body: new URLSearchParams(bodyData).toString()
        })
          .then((res) => {
            if (!res.ok) {
              return res.json().then((err) => {
                throw new Error(err.error || "刪除失敗");
              });
            }
            return res.json();
          })
          .then((data) => {
            showToast(`✓ ${data.message}`);
            
            // 從內部 pages 列表中移除
            delete Vvveb.FileManager.pages[page.page];
            element.remove();
            
            // 如果刪除的是目前正在編輯的頁面，切換回第一個頁面
            if (Vvveb.FileManager.currentPage === page.page) {
              let firstPage = Object.keys(Vvveb.FileManager.pages)[0];
              if (firstPage) {
                Vvveb.FileManager.loadPage(firstPage);
              }
            }
          })
          .catch((err) => {
            showToast(`刪除失敗：${err.message}`, "error");
          });
      });
    };

    console.log("[my-editor] Vvveb.FileManager operations patched.");
  }

  // ── 覆蓋 Vvveb.NewSection 防止佈局崩潰 ─────────────────────────────
  function patchNewSection() {
    if (typeof Vvveb === "undefined" || !Vvveb.NewSection) {
      setTimeout(patchNewSection, 200);
      return;
    }

    Vvveb.NewSection.insert = function () {
      let position = 'before';
      let lastSection = Vvveb.Builder.frameBody.querySelector(':scope > footer:last-of-type');
      if (!lastSection) {
        position = 'after';
        lastSection = Vvveb.Builder.frameBody.querySelector(':scope > main:last-of-type') || 
                      Vvveb.Builder.frameBody.querySelector(':scope > section:last-of-type') ||
                      Vvveb.Builder.frameBody.querySelector(':scope > div:last-of-type') ||
                      Vvveb.Builder.frameBody; // 最安全的回退點：整個 body 節點
      }
      
      this.container = generateElements(this.template)[0];
      if (lastSection === Vvveb.Builder.frameBody) {
        Vvveb.Builder.frameBody.appendChild(this.container);
      } else {
        if (position == 'after') {
          lastSection.after(this.container);
        } else {
          lastSection.before(this.container);
        }
      }
      
      return this.container;
    };

    console.log("[my-editor] Vvveb.NewSection.insert patched to prevent layout crashes.");
  }

  // ── 動態中文化 VvvebJS 元件與區塊 ─────────────────────────────────
  function patchI18n() {
    if (typeof Vvveb === "undefined" || !Vvveb.ComponentsGroup || Object.keys(Vvveb.ComponentsGroup).length === 0) {
      setTimeout(patchI18n, 500);
      return;
    }

    const translateMap = {
      // 分類 (Groups)
      "Grid": "網格系統",
      "Components": "基礎元件",
      "Basic": "基本",
      "Typography": "排版",
      "Media": "媒體",
      "Forms": "表單",
      "Widgets": "小工具",
      "Advanced": "進階",
      "Content": "內容區塊",
      "Layout": "佈局",
      "Blocks": "區塊",
      "Features": "功能特色",
      "Headers": "頁首",
      "Footers": "頁尾",
      "Pricing": "價格表",
      "Testimonials": "客戶評價",
      "Cards": "卡片",
      "Services": "服務",
      "Team": "團隊",
      "About": "關於我們",

      // 元件 (Components)
      "Grid Row": "網格列 (Row)",
      "Grid Column": "網格欄 (Column)",
      "Container": "容器 (Container)",
      "Heading": "標題 (Heading)",
      "Link": "超連結 (Link)",
      "Image": "圖片 (Image)",
      "Video": "影片 (Video)",
      "Paragraph": "段落文字",
      "List": "列表",
      "List item": "列表項目",
      "Button": "按鈕",
      "Button Group": "按鈕群組",
      "Button Toolbar": "按鈕工具列",
      "Form": "表單",
      "Text Input": "文字輸入框",
      "Textarea": "多行文字框",
      "Checkbox": "核取方塊",
      "Radio": "單選按鈕",
      "Select": "下拉選單",
      "Label": "標籤文字",
      "Alert": "警告提示",
      "Badge": "徽章 (Badge)",
      "Card": "卡片 (Card)",
      "Table": "表格",
      "Progress": "進度條",
      "Navbar": "導覽列 (Navbar)",
      "Breadcrumb": "麵包屑 (Breadcrumb)",
      "Pagination": "分頁",
      "Jumbotron": "大型看板",
      "Panel": "面板",
      "Icon": "圖示",
      "Divider": "分隔線",
      "Map": "地圖",
      "Audio": "音訊",
      "File Upload": "檔案上傳",
      "Date Input": "日期輸入框",
      "Password Input": "密碼輸入框",
      "Email Input": "Email 輸入框",

      // 屬性面板 - 標題與一般屬性
      "General": "一般",
      "Id": "ID",
      "Title": "標題 (Title)",
      "Class": "類別 (Class)",
      "Display": "顯示 (Display)",
      "Position": "定位 (Position)",
      "Top": "上",
      "Left": "左",
      "Bottom": "下",
      "Right": "右",
      "Float": "浮動 (Float)",
      "Opacity": "透明度 (Opacity)",
      "Background": "背景 (Background)",
      "Background Color": "背景顏色",
      "Text Color": "文字顏色",
      "Color": "顏色",

      // 排版與字體
      "Font size": "字體大小",
      "Font weight": "字體粗細",
      "Font family": "字體家族",
      "Text align": "文字對齊",
      "Line height": "行高",
      "Letter spacing": "字距",
      "Text decoration": "文字裝飾",
      "Decoration Color": "裝飾顏色",
      "Decoration style": "裝飾樣式",

      // 尺寸與間距
      "Size": "尺寸",
      "Width": "寬度",
      "Height": "高度",
      "Min Width": "最小寬度",
      "Min Height": "最小高度",
      "Max Width": "最大寬度",
      "Max Height": "最大高度",
      "Margin": "外邊距 (Margin)",
      "Padding": "內邊距 (Padding)",

      // 邊框與陰影
      "Border": "邊框 (Border)",
      "Style": "樣式",
      "Radius": "圓角 (Radius)",
      "Radius Top Left": "左上圓角",
      "Radius Top Right": "右上圓角",
      "Radius Bottom Left": "左下圓角",
      "Radius Bottom Right": "右下圓角",
      "Background Image": "背景圖片",
      "Box Shadow": "盒子陰影",
      "Text Shadow": "文字陰影",
      "Filter": "濾鏡",
      "Transform": "變形",
      "Transition": "過渡效果",

      // 選項值
      "Default": "預設",
      "Primary": "主要 (Primary)",
      "Secondary": "次要 (Secondary)",
      "Success": "成功 (Success)",
      "Danger": "危險 (Danger)",
      "Warning": "警告 (Warning)",
      "Info": "資訊 (Info)",
      "Light": "亮色 (Light)",
      "Dark": "暗色 (Dark)",
      "White": "白色",
      "Block": "區塊 (Block)",
      "Inline": "行內 (Inline)",
      "Inline Block": "行內區塊 (Inline Block)",
      "Flex": "彈性 (Flex)",
      "Inline Flex": "行內彈性 (Inline Flex)",
      "Grid": "網格 (Grid)",
      "Static": "靜態 (Static)",
      "Fixed": "固定 (Fixed)",
      "Relative": "相對 (Relative)",
      "Absolute": "絕對 (Absolute)",

      // 裝置響應式顯示
      "Hide based on device screen width": "依裝置螢幕寬度隱藏",
      "Extra small devices": "超小螢幕 (xs)",
      "Small devices": "小螢幕 (sm)",
      "Medium devices": "中螢幕 (md)",
      "Large devices": "大螢幕 (lg)",
      "Xl devices": "超大螢幕 (xl)",
      "Xxl devices": "超超大螢幕 (xxl)",

      // AOS 動畫
      "Animate on scroll": "滾動動畫 (AOS)",
      "Animation type": "動畫類型",
      "Duration": "持續時間",
      "Delay": "延遲",
      "Play animation": "播放動畫",
      "[none]": "[無]",
      "Fade animations": "淡入淡出動畫",
      "Fade": "淡入",
      "Fade Up": "向上淡入",
      "Fade down": "向下淡入",
      "Fade left": "向左淡入",
      "Fade right": "向右淡入",
      "Fade up right": "向右上淡入",
      "Fade up left": "向左上淡入",
      "Fade down right": "向右下淡入",
      "Fade down left": "向左下淡入",
      "Flip animations": "翻轉動畫",
      "Flip Up": "向上翻轉",
      "Flip Down": "向下翻轉",
      "Flip left": "向左翻轉",
      "Flip right": "向右翻轉",
      "Slide animations": "滑動動畫",
      "Slide up": "向上滑動",
      "Slide down": "向下滑動",
      "Slide left": "向左滑動",
      "Slide right": "向右滑動",
      "Zoom animations": "縮放動畫",
      "Zoom in": "放大",
      "Zoom in up": "向上放大",
      "Zoom in down": "向下放大",
      "Zoom in left": "向左放大",
      "Zoom in right": "向右放大",
      "Zoom out": "縮小",
      "Zoom out up": "向上縮小",
      "Zoom out down": "向下縮小",
      "Zoom out left": "向左縮小",
      "Zoom out right": "向右縮小",

      // 連結樣式提示
      "Linked styles": "共用樣式提示"
    };

    const translateText = (text) => {
      if (!text || typeof text !== "string") return text;
      const trimmed = text.trim();
      return translateMap[trimmed] ? translateMap[trimmed] : text;
    };

    // 1. 翻譯 Vvveb 物件內的資料 (供重新渲染時使用)
    if (Vvveb.ComponentsGroup) {
      const newGroups = {};
      for (let group in Vvveb.ComponentsGroup) {
        let tGroup = translateText(group);
        newGroups[tGroup] = Vvveb.ComponentsGroup[group];
        newGroups[tGroup].forEach(compName => {
          let comp = Vvveb.Components.get(compName);
          if (comp && comp.name) {
            comp.name = translateText(comp.name);
          }
        });
      }
      Vvveb.ComponentsGroup = newGroups;
    }

    if (Vvveb.BlocksGroup) {
      const newBlockGroups = {};
      for (let group in Vvveb.BlocksGroup) {
        let tGroup = translateText(group);
        newBlockGroups[tGroup] = Vvveb.BlocksGroup[group];
      }
      Vvveb.BlocksGroup = newBlockGroups;
    }

    // 2. 翻譯所有元件的屬性面板 (Style, Advanced, etc)
    if (Vvveb.Components && Vvveb.Components._components) {
      Object.keys(Vvveb.Components._components).forEach(key => {
        let comp = Vvveb.Components._components[key];
        if (comp.properties) {
          comp.properties.forEach(prop => {
            if (prop.name) prop.name = translateText(prop.name);
            if (prop.data) {
              if (prop.data.header) prop.data.header = translateText(prop.data.header);
              if (prop.data.text) prop.data.text = translateText(prop.data.text);
              if (prop.data.options && Array.isArray(prop.data.options)) {
                prop.data.options.forEach(opt => {
                  if (opt.text) opt.text = translateText(opt.text);
                  if (opt.title) opt.title = translateText(opt.title);
                  if (opt.optgroup) opt.optgroup = translateText(opt.optgroup);
                });
              }
            }
          });
        }
      });
    }

    // 3. 直接修改當前已渲染的 DOM 文字
    document.querySelectorAll(".components-list .header span, .blocks-list .header span, .sections-list .header span").forEach(el => {
      const txt = el.textContent.trim();
      if (translateMap[txt]) {
        el.textContent = translateMap[txt];
      }
    });

    document.querySelectorAll(".components-list li .name, .blocks-list li .name, .sections-list li .name").forEach(el => {
      const txt = el.textContent.trim();
      if (translateMap[txt]) {
        // 如果有子元素，只替換文本節點
        if (el.childNodes.length > 0) {
           for (let i = 0; i < el.childNodes.length; i++) {
             if (el.childNodes[i].nodeType === 3 && el.childNodes[i].textContent.trim() === txt) {
                el.childNodes[i].textContent = translateMap[txt];
                break;
             }
           }
        } else {
           el.textContent = translateMap[txt];
        }
      }
    });

    console.log("[my-editor] VvvebJS components and blocks localized.");
  }

  // ── 啟用 Save 按鈕（vvvebjs 預設 disabled）──────────────────────
  function enableSaveBtn() {
    const btn = document.querySelector(".save-btn");
    if (btn) {
      btn.removeAttribute("disabled");
    } else {
      setTimeout(enableSaveBtn, 300);
    }
  }

  // ── Ctrl+S 快捷鍵 ────────────────────────────────────────────────
  document.addEventListener("keydown", function (e) {
    if ((e.ctrlKey || e.metaKey) && e.key === "s") {
      e.preventDefault();
      if (typeof Vvveb !== "undefined" && Vvveb.Builder && Vvveb.Builder.saveAjax) {
        // 觸發原生儲存按鈕的 click
        const btn = document.querySelector(".save-btn");
        if (btn) {
          btn.click();
        } else {
          Vvveb.Builder.saveAjax({});
        }
      }
    }
  });

  // ── 初始化 ────────────────────────────────────────────────────────
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", () => {
      patchSaveAjax();
      patchFileManager();
      patchNewSection();
      patchI18n();
      enableSaveBtn();
    });
  } else {
    patchSaveAjax();
    patchFileManager();
    patchNewSection();
    patchI18n();
    enableSaveBtn();
  }
})();
