/**
 * LiteMall 移动端商城 - MobileModules 模块加载器
 * 协议：window.MobileModules.load(name, selector, context) => Promise
 *
 * 每个模块是一个独立的 HTML 文件，包含三部分：
 *   <style>    模块样式（注入一次，全局复用）
 *   <template> （可选）DOM 骨架，注入到容器
 *   <script>   模块逻辑（每次加载重新执行，context 以同名变量注入）
 *
 * 模块内可直接使用全局变量：context（承载 api/token/Vue/vant/formatPrice/page 等）
 */

(function (global) {
  'use strict';

  var baseUrl = null;      // 模块根目录，按当前路径推导
  var styleCache = {};     // style 只注入一次
  var inflight = {};       // 防止同一模块并发重复加载

  // 根据当前页面 URL 推导 modules 根目录
  function resolveBase() {
    if (baseUrl) return baseUrl;
    var path = location.pathname;
    // 形如 /mobile/ 或 /mobile/index.html 或 /h5/
    var dir = '/';
    var m = path.match(/^(.*\/)(index\.html)?$/);
    if (m && m[1] && m[1] !== '/') dir = m[1];
    else if (path.indexOf('.') === -1) dir = path.replace(/\/?$/, '/');
    baseUrl = dir + 'modules/';
    return baseUrl;
  }

  // 简单 HTML 解析：提取 style / template / script 块
  function parseModule(html) {
    var res = { styles: [], templates: [], scripts: [] };
    var styleRe = /<style[^>]*>([\s\S]*?)<\/style>/gi;
    var tplRe = /<template[^>]*>([\s\S]*?)<\/template>/gi;
    var scriptRe = /<script([^>]*)>([\s\S]*?)<\/script>/gi;
    var m;
    while ((m = styleRe.exec(html))) res.styles.push(m[1]);
    while ((m = tplRe.exec(html))) res.templates.push(m[1].trim());
    while ((m = scriptRe.exec(html))) {
      var attrs = m[1] || '';
      // 跳过带 src 的外链 script
      if (/\bsrc\s*=/.test(attrs)) continue;
      res.scripts.push(m[2]);
    }
    return res;
  }

  // 注入样式（仅一次）
  function injectStyles(name, css) {
    if (styleCache[name] || !css) return;
    styleCache[name] = true;
    var el = document.createElement('style');
    el.setAttribute('data-module', name);
    el.textContent = css;
    document.head.appendChild(el);
  }

  // 执行脚本：将 context 作为同名变量注入，并注入 exports 对象（修复模块 exports.destroy 报 undefined 的既有 bug）
  function runScript(code, context) {
    var exportsObj = { __module: true };
    // 用一个函数包裹，形参 context/exports 绑定全局同名变量供模块直接引用
    var fn = new Function('context', 'exports', code + '\n;return typeof context!=="undefined"?context:null;');
    fn(context, exportsObj);
    return context;
  }

  function load(name, selector, context) {
    context = context || {};
    var key = name;
    if (inflight[key]) return inflight[key];

    var container = null;
    if (selector) {
      container = typeof selector === 'string' ? document.querySelector(selector) : selector;
    }

    inflight[key] = (function () {
      var url = resolveBase() + encodeURIComponent(name) + '.html';
      return fetch(url, { cache: 'no-cache' })
        .then(function (r) {
          if (!r.ok) throw new Error('module load failed: ' + r.status + ' ' + url);
          return r.text();
        })
        .then(function (html) {
          var parsed = parseModule(html);
          parsed.styles.forEach(function (css) { injectStyles(name, css); });

          // 挂载模板骨架到容器
          if (container && parsed.templates.length) {
            container.innerHTML = parsed.templates.join('\n');
          } else if (container) {
            container.innerHTML = '';
          }

          // 顺序执行脚本（context 注入）
          var lastCtx = context;
          parsed.scripts.forEach(function (code) {
            lastCtx = runScript(code, context);
            if (lastCtx === null || lastCtx === undefined) lastCtx = context;
          });
          return { name: name, ctx: lastCtx || context };
        })
        .catch(function (err) {
          console.error('[MobileModules] load error:', name, err);
          if (container) {
            container.innerHTML = '<div style="text-align:center;padding:40px;color:#999;font-size:13px">模块加载失败</div>';
          }
          throw err;
        })
        .finally(function () {
          delete inflight[key];
        });
    })();

    return inflight[key];
  }

  /**
   * 预加载：提前 fetch 模块并缓存样式与脚本，供后续 load 复用
   */
  var prefetchCache = {};
  function prefetch(name) {
    var url = resolveBase() + encodeURIComponent(name) + '.html';
    if (prefetchCache[name]) return prefetchCache[name];
    prefetchCache[name] = fetch(url, { cache: 'no-cache' })
      .then(function (r) { return r.text(); })
      .then(function (html) {
        var parsed = parseModule(html);
        parsed.styles.forEach(function (css) { injectStyles(name, css); });
        return parsed;
      })
      .catch(function (e) { delete prefetchCache[name]; return null; });
    return prefetchCache[name];
  }

  // 暴露接口
  global.MobileModules = {
    load: load,
    prefetch: prefetch,
    parse: parseModule,
    _resolveBase: resolveBase,
    version: '1.0.0'
  };
})(window);
