// LINKS
HOMEPAGE_EN       = "https://5dplus.info";
HOMEPAGE_VI       = "https://5dplus.info";
FACEBOOK          = "https://facebook.com/5dplus.sketchup";
STORE             = "https://5dplus.lemonsqueezy.com";
USER_MANUAL_EN    = "https://5dplus.info";
USER_MANUAL_VI    = "https://5dplus.info";
RELEASE_NOTES_EN  = "https://5dplus.info";
RELEASE_NOTES_VI  = "https://5dplus.info";
NOTICE_EN         = "https://5dplus.info";
NOTICE_VI         = "https://5dplus.info";

// Store user selection
const extensionName                 = 'YuemuCloudAssets-'
const legacyExtensionName           = '5d_library-'

if (typeof localStorage !== 'undefined') {
  Object.keys(localStorage).forEach((key) => {
    if (!key.startsWith(legacyExtensionName)) return;
    const migratedKey = `${extensionName}${key.slice(legacyExtensionName.length)}`;
    if (localStorage.getItem(migratedKey) === null) {
      localStorage.setItem(migratedKey, localStorage.getItem(key));
    }
  });
}
const themeKey                      = `${extensionName}theme`;
const activeTabKey                  = `${extensionName}activeTab`;
const sidebarKey                    = `${extensionName}sidebar`;
const sidebarWidthKey               = `${extensionName}sidebarWidth`;
// 左侧一级目录最小宽度（允许拖得更靠左）
const SIDEBAR_WIDTH_MIN             = 60;
const SIDEBAR_WIDTH_MAX             = 420;
const SIDEBAR_WIDTH_DEFAULT         = 230;

const subfolderColumnVisibleKey     = `${extensionName}subfolderColumnVisible`;

const subfolderColumnWidthKey      = `${extensionName}subfolderColumnWidth`;
// 二级目录最小宽度调小，让中间分隔线可以拖得更靠左
const SUBFOLDER_WIDTH_MIN          = 80;
const SUBFOLDER_WIDTH_MAX          = 280;
const SUBFOLDER_WIDTH_DEFAULT      = 160;

// Global variable to store toast timer
let toastTimer = null;

const modelShowAllStateKey          = `${extensionName}modelShowAllState`;
const modelSortedByKey              = `${extensionName}modelSortedBy`;
const modelOnlineStateKey           = `${extensionName}modelOnlineState`;
const modelDetailsStateKey          = `${extensionName}modelDetailsState`;
const recentModelUrlKey             = `${extensionName}recentModelUrl`;
const recentModelChildFolderKey     = `${extensionName}recentModelChildFolder`;
const modelViewOptionsKey           = `${extensionName}modelViewOptions`;

const materialSortedByKey           = `${extensionName}materialSortedBy`;
const materialOnlineStateKey        = `${extensionName}materialOnlineState`;
const materialDetailsStateKey       = `${extensionName}materialDetailsState`;
const recentMaterialUrlKey          = `${extensionName}recentMaterialUrl`;
const recentMaterialChildFolderKey  = `${extensionName}recentMaterialChildFolder`;
const materialViewOptionsKey        = `${extensionName}materialViewOptions`;

const doorSortedByKey               = `${extensionName}doorSortedBy`;
const doorOnlineStateKey            = `${extensionName}doorOnlineState`;
const doorDetailsStateKey           = `${extensionName}doorDetailsState`;
const recentDoorUrlKey              = `${extensionName}recentDoorUrl`;
const recentDoorChildFolderKey      = `${extensionName}recentDoorChildFolder`;
const doorViewOptionsKey            = `${extensionName}doorViewOptions`;
const doorShowAllStateKey           = `${extensionName}doorShowAllState`;

const handleSortedByKey             = `${extensionName}handleSortedBy`;
const handleOnlineStateKey          = `${extensionName}handleOnlineState`;
const handleDetailsStateKey         = `${extensionName}handleDetailsState`;
const recentHandleUrlKey            = `${extensionName}recentHandleUrl`;
const recentHandleChildFolderKey    = `${extensionName}recentHandleChildFolder`;
const handleViewOptionsKey          = `${extensionName}handleViewOptions`;
const handleShowAllStateKey         = `${extensionName}handleShowAllState`;

const showAllKey                    = `${extensionName}showAllModels`;
const showDetailsKey                = `${extensionName}showDetails`;
const viewOptionsKey                = `${extensionName}viewOptions`;
const recentPrefixKey               = `${extensionName}recentPrefix`;

/** 将本地文件路径转为 file:// URL，编码特殊字符（# % 等）避免 img src 解析错误 */
function fileUrlFromPath(path) {
  if (!path) return '';
  const s = String(path).replace(/\\/g, '/');
  return 'file:///' + s.split('/').map(function (seg) { return encodeURIComponent(seg); }).join('/');
}
window.fileUrlFromPath = fileUrlFromPath;

document.addEventListener("contextmenu", function (event) {
  event.preventDefault();
});

function loadLanguage(context) {
  axios
    .get(`../languages/resources/${context.language}.json`)
    .then((response) => {
      context.languageData = response.data;
    });
}

/** 语言由悦木云「全局配置」统一管理，资产库只接收 Ruby 推送 */
function applyPluginLanguage(lang) {
  const root = document.getElementById('app');
  if (!root || !root.__vue__ || !lang) return;
  root.__vue__.applyPluginLanguage(lang);
}
window.applyPluginLanguage = applyPluginLanguage;

function applyTheme(theme) {
  const themeStylesheet = document.getElementById('theme-stylesheet');

  if (theme === 'dark') {
    document.documentElement.setAttribute('data-theme', 'dark');
    themeStylesheet.href = '../css/modus-dark.min.css';
  } else {
    document.documentElement.setAttribute('data-theme', 'light');
    themeStylesheet.href = '../css/modus.min.css';
  }
}

function handleTooltip(context) {
  // console.log("Initializing tooltips...");
  context.$nextTick(() => {
    // Dispose existing
    $('[data-toggle="tooltip"]').tooltip("dispose");
    $('[data-toggle="dropdown"]').tooltip("dispose");

    // Get the element via data-toggle
    const tooltipElements = context.$el.querySelectorAll(
      "[data-toggle='tooltip'], [data-toggle='dropdown']"
    );
    tooltipElements.forEach((el) => {
      new bootstrap.Tooltip(el, {
        trigger: "hover",
        delay: { show: 750, hide: 100 },
      });
    });
  });
}

// Function to hide all tooltips immediately 
function hideAllTooltips() {
  // Hide all currently visible tooltips using Bootstrap 4 + jQuery method
  $('[data-toggle="tooltip"], [data-toggle="dropdown"]').tooltip('hide');

  // Also remove any dangling tooltip elements
  $('.tooltip').remove();
}

// Base constants aligned with Bootstrap 4 defaults
const BASE_MODAL  = 1050;
const BASE_STEP   = 20;
const BASE_GAP    = 10;

function bringModalToFront($modal) {
  // Compute the top z-index for the new modal
  const modalZ = BASE_MODAL + BASE_STEP;

  // Set modal z-index before showing
  $modal.css("z-index", modalZ);

  // On show (before animation), adjust backdrop z-index immediately
  $modal.off("show.bs.modal.bringToFront").on("show.bs.modal.bringToFront", function () {
    setTimeout(function () {
      const $bd = $(".modal-backdrop").last();
      if ($bd.length) {
        $bd.css("z-index", modalZ - BASE_GAP);
      }
    }, 10);
  });

  // Show with chosen backdrop/keyboard behaviors
  $modal.modal({
    show: true,
  });
}

function bringModalToDefault($modal) {
  // Reset z-index
  $modal.css("z-index", "");

  // Reset backdrop z-index
  const $bd = $(".modal-backdrop").last();
  if ($bd.length) {
    $bd.css("z-index", "");
  }
}

function showToast(delay = 1500) {
  const $msg = $("#messageModal");

  // Clear any existing timer to prevent multiple hide calls
  if (toastTimer) {
    clearTimeout(toastTimer);
    toastTimer = null;
  }

  // If modal is already shown, just update content and reset timer
  if ($msg.hasClass('show')) {
    // Auto close if needed
    const dur =
      delay === "wait" || delay === false
        ? null
        : typeof delay === "number"
        ? delay
        : 1500;

    if (dur) {
      toastTimer = setTimeout(function () {
        $msg.one("hidden.bs.modal", function () {
          bringModalToDefault($msg);
          toastTimer = null;
        });
        $msg.modal("hide");
      }, dur);
    }
    return;
  }

  // Remove any existing backdrops before showing new modal
  $('.modal-backdrop').remove();
  $('body').removeClass('modal-open');
  
  // Reset any stuck state from previous show
  $msg.removeData('bs.modal');
  
  // Bring modal to front and show
  bringModalToFront($msg);

  // Auto close if needed
  const dur =
    delay === "wait" || delay === false
      ? null
      : typeof delay === "number"
      ? delay
      : 1500;

  if (dur) {
    toastTimer = setTimeout(function () {
      $msg.one("hidden.bs.modal", function () {
        bringModalToDefault($msg);
        toastTimer = null;
      });
      $msg.modal("hide");
    }, dur);
  }
}

function showModal(id, delay) {
  return new Promise(function (resolve) {
    $(id).modal("show");

    if (
      delay !== "wait" &&
      delay !== false &&
      typeof delay === "number" &&
      delay > 0
    ) {
      setTimeout(function () {
        $(id).one("hidden.bs.modal", function () {
          resolve();
        });
        $(id).modal("hide");
      }, delay);
    } else {
      resolve();
    }
  });
}

function hideModal(id) {
  return new Promise(function (resolve) {
    $(id).one("hidden.bs.modal", function () {
      resolve();
    });
    $(id).modal("hide");
  });
}

function hideAllModals() {
  return new Promise(function (resolve) {
    const $modals = $(".modal.show");

    if ($modals.length === 0) {
      resolve();
      return;
    }

    let hiddenCount = 0;
    const totalModals = $modals.length;

    $modals.each(function () {
      const $modal = $(this);

      $modal.one("hidden.bs.modal", function () {
        hiddenCount++;
        if (hiddenCount === totalModals) {
          resolve();
        }
      });

      $modal.modal("hide");
    });
  });
}

// Force hide all modals synchronously without animation
// Use this when you need to immediately close all modals before showing a new one
function forceHideAllModals() {
  // Remove all modal backdrops
  $('.modal-backdrop').remove();

  // Force hide all modals and reset Bootstrap internal state
  $('.modal').each(function() {
    const $modal = $(this);
    
    // Remove Bootstrap modal data to reset internal state
    $modal.removeData('bs.modal');
    
    // Force hide without animation
    $modal.removeClass('show fade');
    $modal.css('display', 'none');
    $modal.attr('aria-hidden', 'true');
    $modal.removeAttr('aria-modal');
    $modal.removeAttr('role');
    
    // Re-add fade class for next show
    $modal.addClass('fade');
  });

  // Clean up body classes and styles
  $('body').removeClass('modal-open');
  $('body').css('padding-right', '');
  $('body').css('overflow', '');

  // Reset processing state if exists
  if (typeof app !== 'undefined' && app) {
    app.isProcessing = false;
  }
}

function hideAllDropdowns() {
  return new Promise(function (resolve) {
    const $dropdowns = $(".dropdown-menu.show");

    if ($dropdowns.length === 0) {
      resolve();
      return;
    }

    let hiddenCount = 0;
    const totalDropdowns = $dropdowns.length;

    $dropdowns.each(function () {
      const $dropdown = $(this);

      $dropdown.one("hidden.bs.dropdown", function () {
        hiddenCount++;
        if (hiddenCount === totalDropdowns) {
          resolve();
        }
      });

      $dropdown.dropdown("hide");
    });
  });
}
