#!/usr/bin/env node
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { loadH5Environment } from './load-env.mjs';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
loadH5Environment(__dirname);

const DEFAULT_TOKEN_URL = 'https://api.weixin.qq.com/cgi-bin/stable_token';
const DEFAULT_MENU_CREATE_URL = 'https://api.weixin.qq.com/cgi-bin/menu/create';
const DEFAULT_MENU_GET_URL = 'https://api.weixin.qq.com/cgi-bin/menu/get';

const MENU = {
  button: [
    {
      type: 'view',
      name: 'MeMind',
      url: 'https://m.tkmind.cn',
    },
    {
      type: 'view',
      name: 'M空间',
      url: 'https://m.tkmind.cn/space',
    },
    {
      type: 'view',
      name: 'M广场',
      url: 'https://plaza.tkmind.cn',
    },
  ],
};

function endpointFromTokenUrl(pathname, fallback) {
  const tokenUrl = process.env.H5_WECHAT_MP_TOKEN_URL?.trim() || DEFAULT_TOKEN_URL;
  try {
    const url = new URL(tokenUrl);
    url.pathname = pathname;
    url.search = '';
    return url.toString();
  } catch {
    return fallback;
  }
}

async function readJson(response) {
  const text = await response.text();
  if (!response.ok) {
    throw new Error(text || `HTTP ${response.status}`);
  }
  return text ? JSON.parse(text) : null;
}

async function getAccessToken() {
  const appid =
    process.env.H5_WECHAT_MP_APP_ID?.trim() ?? process.env.H5_WECHAT_APP_ID?.trim() ?? '';
  const secret =
    process.env.H5_WECHAT_MP_APP_SECRET?.trim() ?? process.env.H5_WECHAT_APP_SECRET?.trim() ?? '';
  if (!appid || !secret) {
    throw new Error(
      '缺少 H5_WECHAT_MP_APP_ID / H5_WECHAT_MP_APP_SECRET（或 H5_WECHAT_APP_ID / H5_WECHAT_APP_SECRET）',
    );
  }

  const tokenUrl = process.env.H5_WECHAT_MP_TOKEN_URL?.trim() || DEFAULT_TOKEN_URL;
  const payload = await readJson(
    await fetch(tokenUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        grant_type: 'client_credential',
        appid,
        secret,
        force_refresh: false,
      }),
    }),
  );
  if (!payload?.access_token) {
    throw new Error(payload?.errmsg || `获取 access_token 失败 (${payload?.errcode ?? 'unknown'})`);
  }
  return payload.access_token;
}

async function createMenu(accessToken) {
  const baseUrl =
    process.env.H5_WECHAT_MP_MENU_CREATE_URL?.trim() ||
    endpointFromTokenUrl('/cgi-bin/menu/create', DEFAULT_MENU_CREATE_URL);
  const url = `${baseUrl}?access_token=${encodeURIComponent(accessToken)}`;
  const payload = await readJson(
    await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(MENU),
    }),
  );
  if (Number(payload?.errcode ?? 0) !== 0) {
    throw new Error(payload?.errmsg || `创建菜单失败 (${payload?.errcode})`);
  }
  return payload;
}

async function getMenu(accessToken) {
  const baseUrl =
    process.env.H5_WECHAT_MP_MENU_GET_URL?.trim() ||
    endpointFromTokenUrl('/cgi-bin/menu/get', DEFAULT_MENU_GET_URL);
  const url = `${baseUrl}?access_token=${encodeURIComponent(accessToken)}`;
  return readJson(await fetch(url, { method: 'GET' }));
}

const dryRun = process.argv.includes('--dry-run');
if (dryRun) {
  console.log(JSON.stringify(MENU, null, 2));
  process.exit(0);
}

const accessToken = await getAccessToken();
const created = await createMenu(accessToken);
const current = await getMenu(accessToken).catch((err) => ({ warning: err.message }));

console.log(
  JSON.stringify(
    {
      ok: true,
      created,
      menu: MENU,
      current,
    },
    null,
    2,
  ),
);
