/**
 * 切换 pages.json 到不同端的专属编译模式。
 *
 * 用法：
 *   npm run pages:consumer   → 仅编译 consumer 相关页面
 *   npm run pages:merchant   → 仅编译 merchant 相关页面
 *   npm run pages:admin      → 仅编译 admin 相关页面
 *   npm run pages:full       → 恢复完整 pages.json
 */
const fs = require("fs");
const path = require("path");

const root = path.resolve(__dirname, "..");
const pagesJson = path.join(root, "pages.json");
const pagesFull = path.join(root, "pages.full.json");
const backupDir = path.join(root, ".pages-backup");
const pagesModeFile = path.join(root, "utils", "pagesMode.uts");
const currentClientFile = path.join(root, "config", "current-client.uts");
const pageExtensions = [".uvue", ".vue", ".nvue"];

const consumerUserPages = [
  "pages/user/boot",
  "pages/user/login",
  "pages/user/register",
  "pages/user/forgot-password",
  "pages/user/terms",
  "pages/user/center",
  "pages/user/profile",
  "pages/user/change-password",
  "pages/user/bind-phone",
  "pages/user/bind-email",
];

const merchantUserPages = [
  "pages/user/login",
  "pages/user/boot",
  "pages/user/register",
  "pages/user/forgot-password",
  "pages/user/terms",
  "pages/user/change-password",
];

const adminUserPages = [
  "pages/user/login",
  "pages/user/boot",
  "pages/user/forgot-password",
  "pages/user/terms",
  "pages/user/change-password",
];

const targetConfigs = {
  consumer: {
    fileName: "pages.consumer.json",
    label: "消费者端",
    entryPath: "pages/main/index",
    homeRedirect: "/pages/main/index",
    tabBarPath: "/pages/main/index",
    orderedTopLevelPaths: [
      "pages/main/index",
      ...consumerUserPages,
      "pages/main/messages",
      "pages/main/cart",
      "pages/main/profile",
    ],
    topLevelMatcher(pagePath) {
      return (
        pagePath.startsWith("pages/main/") ||
        consumerUserPages.includes(pagePath)
      );
    },
    subPackageMatcher(rootPath) {
      return rootPath === "pages/mall/consumer";
    },
    tabBarMatcher(pagePath) {
      return pagePath.startsWith("pages/main/");
    },
    defaultCondition() {
      return {
        current: 0,
        list: [
          {
            name: "consumer端",
            path: "pages/main/index",
            query: "role=consumer",
          },
        ],
      };
    },
  },
  merchant: {
    fileName: "pages.merchant.json",
    label: "商家端",
    entryPath: "pages/user/login",
    homeRedirect: "/pages/mall/merchant/index",
    tabBarPath: "",
    orderedTopLevelPaths: [
      "pages/user/login",
      "pages/user/boot",
      "pages/user/register",
      "pages/user/forgot-password",
      "pages/user/terms",
      "pages/user/change-password",
      "pages/mall/merchant/index",
      "pages/mall/merchant/messages",
      "pages/mall/merchant/orders",
      "pages/mall/merchant/growth",
      "pages/mall/merchant/profile",
    ],
    topLevelMatcher(pagePath) {
      return (
        merchantUserPages.includes(pagePath) ||
        pagePath.startsWith("pages/mall/merchant/")
      );
    },
    subPackageMatcher() {
      return false;
    },
    defaultCondition() {
      return {
        current: 0,
        list: [
          {
            name: "merchant端",
            path: "pages/mall/merchant/index",
            query: "role=merchant",
          },
        ],
      };
    },
  },
  admin: {
    fileName: "pages.admin.json",
    label: "管理后台",
    entryPath: "pages/user/login",
    homeRedirect: "/pages/mall/admin/homePage/index",
    tabBarPath: "",
    orderedTopLevelPaths: [
      "pages/user/login",
      "pages/user/boot",
      "pages/user/forgot-password",
      "pages/user/terms",
      "pages/user/change-password",
      "pages/mall/admin/homePage/index",
      "pages/mall/admin/userCenter/index",
    ],
    topLevelMatcher(pagePath) {
      return (
        adminUserPages.includes(pagePath) ||
        pagePath === "pages/mall/admin/homePage/index" ||
        pagePath === "pages/mall/admin/userCenter/index"
      );
    },
    subPackageMatcher(rootPath) {
      return rootPath.startsWith("pages/mall/admin/");
    },
    defaultCondition() {
      return {
        current: 0,
        list: [
          {
            name: "admin端",
            path: "pages/mall/admin/homePage/index",
            query: "role=admin",
          },
        ],
      };
    },
  },
  delivery: {
    fileName: "pages.delivery.json",
    label: "服务人员端/上门服务端",
    entryPath: "pages/user/login",
    homeRedirect: "/pages/mall/delivery/home/index",
    tabBarPath: "/pages/mall/delivery/home/index",
    standalone: true,
  },
};

const fullModeConfig = {
  homeRedirect: "/pages/main/index",
  tabBarPath: "/pages/main/index",
};

const mode = process.argv[2]; // 'consumer' | 'merchant' | 'admin' | 'full'

function readJson(filePath) {
  const rawContent = fs.readFileSync(filePath, "utf8").replace(/^\uFEFF/, "");
  return JSON.parse(rawContent);
}

function writeJson(filePath, content) {
  fs.writeFileSync(filePath, `${JSON.stringify(content, null, 2)}\n`, "utf8");
}

function writePagesMode(modeName) {
  fs.writeFileSync(
    pagesModeFile,
    `export const CURRENT_PAGES_MODE = '${modeName}'\n`,
    "utf8",
  );
}

function writeCurrentClient(modeName) {
  fs.mkdirSync(path.dirname(currentClientFile), { recursive: true });
  fs.writeFileSync(
    currentClientFile,
    `export const CURRENT_CLIENT: string = '${modeName}'\n`,
    "utf8",
  );
  console.log(`🔁 已同步当前端标识 → ${modeName}`);
}

function ensureFullBackup() {
  if (fs.existsSync(pagesFull)) {
    return;
  }
  fs.copyFileSync(pagesJson, pagesFull);
  console.log("📦 已备份 pages.json → pages.full.json");
}

function backupCurrentPages(targetName) {
  if (!fs.existsSync(pagesJson)) {
    return;
  }

  fs.mkdirSync(backupDir, { recursive: true });
  const timestamp = new Date().toISOString().replace(/[.:]/g, "-");
  const backupPath = path.join(
    backupDir,
    `pages.${targetName}.${timestamp}.json`,
  );
  fs.copyFileSync(pagesJson, backupPath);
  console.log(`📦 已备份当前 pages.json → ${path.relative(root, backupPath)}`);
}

function getPageMap(fullConfig) {
  return new Map(fullConfig.pages.map((page) => [page.path, page]));
}

function findMatchingPageFile(routePath) {
  for (const extension of pageExtensions) {
    const candidate = path.join(root, `${routePath}${extension}`);
    if (fs.existsSync(candidate)) {
      return candidate;
    }
  }
  return null;
}

function clonePage(page) {
  return JSON.parse(JSON.stringify(page));
}

function flattenSubPackagePages(fullConfig, rootPath) {
  const targetPackage = fullConfig.subPackages.find(
    (item) => item.root === rootPath,
  );
  if (!targetPackage) {
    return [];
  }

  return targetPackage.pages.map((page) => ({
    path: `${rootPath}/${page.path}`,
    style: page.style ? JSON.parse(JSON.stringify(page.style)) : {},
  }));
}

function getTopLevelPages(fullConfig, targetConfig) {
  const pageMap = getPageMap(fullConfig);
  const matchedFromTopLevel = fullConfig.pages
    .filter((page) => targetConfig.topLevelMatcher(page.path))
    .map((page) => clonePage(page));

  const flattenedPages = (targetConfig.flattenRoots || []).flatMap((rootPath) =>
    flattenSubPackagePages(fullConfig, rootPath),
  );

  const mergedMap = new Map();
  for (const page of [...matchedFromTopLevel, ...flattenedPages]) {
    mergedMap.set(page.path, page);
  }

  const orderedPages = [];
  for (const pagePath of targetConfig.orderedTopLevelPaths) {
    if (mergedMap.has(pagePath)) {
      orderedPages.push(mergedMap.get(pagePath));
      mergedMap.delete(pagePath);
    } else if (pageMap.has(pagePath)) {
      orderedPages.push(clonePage(pageMap.get(pagePath)));
    }
  }

  for (const page of [...matchedFromTopLevel, ...flattenedPages]) {
    if (mergedMap.has(page.path)) {
      orderedPages.push(mergedMap.get(page.path));
      mergedMap.delete(page.path);
    }
  }

  return dedupePages(orderedPages);
}

function getSubPackages(fullConfig, targetConfig) {
  return fullConfig.subPackages
    .filter((item) => targetConfig.subPackageMatcher(item.root))
    .map((item) => JSON.parse(JSON.stringify(item)));
}

function dedupePages(pages) {
  const seen = new Set();
  return pages.filter((page) => {
    if (seen.has(page.path)) {
      return false;
    }
    seen.add(page.path);
    return true;
  });
}

function getCondition(targetConfig, sourceCondition) {
  if (sourceCondition && Array.isArray(sourceCondition.list)) {
    const filteredList = sourceCondition.list.filter(
      (item) => item.path === targetConfig.entryPath,
    );
    if (filteredList.length > 0) {
      return {
        current: 0,
        list: filteredList,
      };
    }
  }

  return targetConfig.defaultCondition();
}

function validateGeneratedConfig(targetName, config) {
  const missingRoutes = [];
  const routeSet = new Set();

  for (const page of config.pages || []) {
    routeSet.add(page.path);
    if (!findMatchingPageFile(page.path)) {
      missingRoutes.push(page.path);
    }
  }

  for (const subPackage of config.subPackages || []) {
    for (const page of subPackage.pages || []) {
      const fullPath = `${subPackage.root}/${page.path}`;
      routeSet.add(fullPath);
      if (!findMatchingPageFile(fullPath)) {
        missingRoutes.push(fullPath);
      }
    }
  }

  for (const tabItem of config.tabBar?.list || []) {
    if (!routeSet.has(tabItem.pagePath)) {
      missingRoutes.push(`tabBar -> ${tabItem.pagePath}`);
    }
  }

  for (const conditionItem of config.condition?.list || []) {
    if (!routeSet.has(conditionItem.path)) {
      missingRoutes.push(`condition -> ${conditionItem.path}`);
    }
  }

  if (missingRoutes.length > 0) {
    console.error(`❌ ${targetName} 配置存在无效页面引用：`);
    for (const routePath of missingRoutes) {
      console.error(`   - ${routePath}`);
    }
    process.exit(1);
  }
}

function buildTargetConfig(fullConfig, targetName, sourceCondition) {
  const targetConfig = targetConfigs[targetName];
  const nextConfig = {};

  nextConfig.pages = getTopLevelPages(fullConfig, targetConfig);
  nextConfig.subPackages = getSubPackages(fullConfig, targetConfig);

  if (targetConfig.tabBarMatcher) {
    const filteredTabBarList = (fullConfig.tabBar?.list || []).filter((item) =>
      targetConfig.tabBarMatcher(item.pagePath),
    );
    if (filteredTabBarList.length > 0 && fullConfig.tabBar) {
      nextConfig.tabBar = {
        ...JSON.parse(JSON.stringify(fullConfig.tabBar)),
        list: filteredTabBarList,
      };
    }
  }

  for (const key of Object.keys(fullConfig)) {
    if (["pages", "subPackages", "tabBar", "condition"].includes(key)) {
      continue;
    }
    nextConfig[key] = JSON.parse(JSON.stringify(fullConfig[key]));
  }

  nextConfig.condition = getCondition(targetConfig, sourceCondition);

  validateGeneratedConfig(targetName, nextConfig);
  return nextConfig;
}

function writeTargetConfig(targetName, config) {
  const targetPath = path.join(root, targetConfigs[targetName].fileName);
  writeJson(targetPath, config);
  fs.copyFileSync(targetPath, pagesJson);
  writePagesMode(targetName);
  writeCurrentClient(targetName);

  const pageCount = config.pages.length;
  const subPackageCount = config.subPackages.length;
  const tabBarCount = config.tabBar?.list?.length || 0;

  console.log(`✅ 已切换为【${targetConfigs[targetName].label}专属编译模式】`);
  console.log(`   目标配置：${targetConfigs[targetName].fileName}`);
  console.log(`   pages：${pageCount} 个`);
  console.log(`   subPackages：${subPackageCount} 个`);
  console.log(`   tabBar：${tabBarCount} 个`);
  console.log("   恢复完整版本：npm run pages:full");
}

function switchStandaloneConfig(targetName) {
  const targetPath = path.join(root, targetConfigs[targetName].fileName);
  if (!fs.existsSync(targetPath)) {
    console.error(`❌ ${targetConfigs[targetName].fileName} 不存在。`);
    process.exit(1);
  }

  const config = readJson(targetPath);
  validateGeneratedConfig(targetName, config);
  fs.copyFileSync(targetPath, pagesJson);
  writePagesMode(targetName);
  writeCurrentClient(targetName);

  const pageCount = config.pages != null ? config.pages.length : 0;
  const subPackageCount =
    config.subPackages != null ? config.subPackages.length : 0;
  const tabBarCount =
    config.tabBar != null && Array.isArray(config.tabBar.list)
      ? config.tabBar.list.length
      : 0;

  console.log(`✅ 已切换为【${targetConfigs[targetName].label}专属编译模式】`);
  console.log(`   目标配置：${targetConfigs[targetName].fileName}`);
  console.log(`   pages：${pageCount} 个`);
  console.log(`   subPackages：${subPackageCount} 个`);
  console.log(`   tabBar：${tabBarCount} 个`);
  console.log("   恢复完整版本：npm run pages:full");
}

function restoreFullPages() {
  if (!fs.existsSync(pagesFull)) {
    console.error("❌ pages.full.json 不存在。");
    console.error("   可能当前已经是完整模式，或备份文件已被删除。");
    process.exit(1);
  }

  backupCurrentPages("full");
  fs.copyFileSync(pagesFull, pagesJson);
  writePagesMode("full");
  writeCurrentClient("full");
  console.log("✅ 已恢复【完整 pages.json】");
  console.log("   包含 consumer + merchant + admin 全部页面。");
}

if (mode === "full") {
  restoreFullPages();
} else if (Object.prototype.hasOwnProperty.call(targetConfigs, mode)) {
  ensureFullBackup();
  backupCurrentPages(mode);

  if (targetConfigs[mode].standalone === true) {
    switchStandaloneConfig(mode);
    process.exit(0);
  }

  const fullConfig = readJson(pagesFull);
  const sourceCondition = fs.existsSync(pagesJson)
    ? (() => {
        try {
          return readJson(pagesJson).condition;
        } catch (error) {
          return null;
        }
      })()
    : null;

  const nextConfig = buildTargetConfig(fullConfig, mode, sourceCondition);
  writeTargetConfig(mode, nextConfig);
} else {
  console.log("用法：");
  console.log("  npm run pages:consumer   切换到消费者端专属编译模式");
  console.log("  npm run pages:delivery   切换到服务人员端专属编译模式");
  console.log("  npm run pages:merchant   切换到商家端专属编译模式");
  console.log("  npm run pages:admin      切换到管理后台专属编译模式");
  console.log("  npm run pages:full       恢复完整编译模式");
}
