const fs = require("fs");
const path = require("path");

const mode = process.argv[2];
if (!mode || !["local", "prod"].includes(mode)) {
  console.error("Usage: node scripts/verify-weapp-env.js <local|prod>");
  process.exit(1);
}

const distFile = path.resolve(__dirname, "..", "dist", "common.js");
if (!fs.existsSync(distFile)) {
  console.error("dist/common.js not found. Please run build first.");
  process.exit(1);
}

const skillConfigFile = path.resolve(__dirname, "..", "dist", "skills", "activity-skill", "utils", "config.js");
if (!fs.existsSync(skillConfigFile)) {
  console.error("dist/skills/activity-skill/utils/config.js not found. Please run build first.");
  process.exit(1);
}

const requiredSkillFiles = [
  path.resolve(__dirname, "..", "dist", "skills", "activity-skill", "mcp.json"),
  path.resolve(__dirname, "..", "dist", "skills", "activity-skill", "index.js"),
  path.resolve(__dirname, "..", "dist", "skills", "activity-skill", "SKILL.md"),
  path.resolve(__dirname, "..", "dist", "page-meta.json")
];

for (const file of requiredSkillFiles) {
  if (!fs.existsSync(file)) {
    console.error(`Required WeChat AI skill file missing: ${path.relative(path.resolve(__dirname, ".."), file)}`);
    process.exit(1);
  }
}

const appJsonFile = path.resolve(__dirname, "..", "dist", "app.json");
if (!fs.existsSync(appJsonFile)) {
  console.error("dist/app.json not found. Please run build first.");
  process.exit(1);
}

const appJson = JSON.parse(fs.readFileSync(appJsonFile, "utf8"));
const skillSubPackages = []
  .concat(appJson.subPackages || [])
  .concat(appJson.subpackages || [])
  .filter((item) => item && item.root === "skills");

if (skillSubPackages.length !== 1 || skillSubPackages[0].independent !== true || !Array.isArray(skillSubPackages[0].pages)) {
  console.error("Invalid app.json: skills must be configured as one independent subpackage for WeChat Agent MCP discovery.");
  process.exit(1);
}

const agentSkills = appJson.agent && Array.isArray(appJson.agent.skills) ? appJson.agent.skills : [];
const hasActivitySkill = agentSkills.some((item) => item && item.path === "skills/activity-skill");
if (!hasActivitySkill || appJson.agent.pageMetadata !== "page-meta.json") {
  console.error("Invalid app.json: missing activity Agent skill or page metadata.");
  process.exit(1);
}

const pageMetaFile = path.resolve(__dirname, "..", "dist", "page-meta.json");
const pageMeta = JSON.parse(fs.readFileSync(pageMetaFile, "utf8"));
const appPages = new Set((appJson.pages || []).map((item) => String(item).replace(/^\/+/, "")));
for (const subPackage of []
  .concat(appJson.subPackages || [])
  .concat(appJson.subpackages || [])) {
  const root = subPackage && typeof subPackage.root === "string" ? subPackage.root.replace(/^\/+|\/+$/g, "") : "";
  const pages = subPackage && Array.isArray(subPackage.pages) ? subPackage.pages : [];
  for (const page of pages) {
    appPages.add(`${root}/${String(page).replace(/^\/+/, "")}`);
  }
}
if (!Array.isArray(pageMeta.pages) || pageMeta.pages.length === 0) {
  console.error("Invalid page-meta.json: pages must be a non-empty array.");
  process.exit(1);
}

for (let index = 0; index < pageMeta.pages.length; index += 1) {
  const item = pageMeta.pages[index];
  const pagePath = item && typeof item.path === "string" ? item.path.replace(/^\/+/, "").split("?")[0] : "";
  const name = item && typeof item.name === "string" ? item.name.trim() : "";
  const description = item && typeof item.description === "string" ? item.description.trim() : "";
  if (!pagePath || !name || !description) {
    console.error(`Invalid page-meta.json: pages[${index}] must include path, name and description.`);
    process.exit(1);
  }
  if (!appPages.has(pagePath)) {
    console.error(`Invalid page-meta.json: pages[${index}].path does not exist in app.json pages: ${pagePath}`);
    process.exit(1);
  }
}

const distRoot = path.resolve(__dirname, "..", "dist");
const subPackageRoots = []
  .concat(appJson.subPackages || [])
  .concat(appJson.subpackages || [])
  .map((item) => (item && typeof item.root === "string" ? item.root.replace(/^\/+|\/+$/g, "") : ""))
  .filter(Boolean);

function collectFiles(dir, result = []) {
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
    const file = path.join(dir, entry.name);
    if (entry.isDirectory()) {
      collectFiles(file, result);
    } else if (entry.isFile()) {
      result.push(file);
    }
  }
  return result;
}

const mainPackageBytes = collectFiles(distRoot).reduce((total, file) => {
  const relative = path.relative(distRoot, file).replace(/\\/g, "/");
  const inSubPackage = subPackageRoots.some((root) => relative === root || relative.startsWith(`${root}/`));
  return inSubPackage ? total : total + fs.statSync(file).size;
}, 0);
const maxMainPackageBytes = 1400 * 1024;
if (mainPackageBytes > maxMainPackageBytes) {
  console.error(`Main package is too large before WeChat preview transform: ${(mainPackageBytes / 1024).toFixed(1)}KB > 1400KB. Move more non-tab pages/assets into subpackages.`);
  process.exit(1);
}
console.log(`Main package raw size verified: ${(mainPackageBytes / 1024).toFixed(1)}KB`);

const content = fs.readFileSync(distFile, "utf8");
const skillContent = fs.readFileSync(skillConfigFile, "utf8");
const hasLocal = content.includes("http://localhost:8082");
const skillHasLocal = skillContent.includes("http://localhost:8082");
const hasLegacyLocal = content.includes("http://localhost:8080") || content.includes("http://127.0.0.1:8080");
const skillHasLegacyLocal = skillContent.includes("http://localhost:8080") || skillContent.includes("http://127.0.0.1:8080");
const hasLoopback = hasLocal || hasLegacyLocal || content.includes("http://127.0.0.1:8082");
const skillHasLoopback = skillHasLocal || skillHasLegacyLocal || skillContent.includes("http://127.0.0.1:8082");
const hasProd = content.includes("https://dlxlh.dtacloud.cn");
const skillHasProd = skillContent.includes("https://dlxlh.dtacloud.cn");

if (mode === "local") {
  if (!hasLocal || !skillHasLocal || hasProd || skillHasProd || hasLegacyLocal || skillHasLegacyLocal) {
    console.error("Build env mismatch: expected LOCAL (localhost:8082) in main bundle and activity skill, but detected PROD or mixed.");
    process.exit(1);
  }
  console.log("Build env verified: LOCAL -> http://localhost:8082");
  process.exit(0);
}

if (!hasProd || !skillHasProd || hasLoopback || skillHasLoopback) {
  console.error("Build env mismatch: expected PROD only (dlxlh.dtacloud.cn) in main bundle and activity skill, but detected missing PROD or mixed local URLs.");
  process.exit(1);
}
console.log("Build env verified: PROD -> https://dlxlh.dtacloud.cn");
