const test = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');

const source = fs.readFileSync('background.js', 'utf8');

function extractFunction(name) {
  const markers = [`async function ${name}(`, `function ${name}(`];
  const start = markers
    .map((marker) => source.indexOf(marker))
    .find((index) => index >= 0);
  if (start < 0) {
    throw new Error(`missing function ${name}`);
  }

  let parenDepth = 0;
  let signatureEnded = false;
  let braceStart = -1;
  for (let i = start; i < source.length; i += 1) {
    const ch = source[i];
    if (ch === '(') parenDepth += 1;
    if (ch === ')') {
      parenDepth -= 1;
      if (parenDepth === 0) signatureEnded = true;
    }
    if (ch === '{' && signatureEnded) {
      braceStart = i;
      break;
    }
  }
  if (braceStart < 0) {
    throw new Error(`missing body for function ${name}`);
  }

  let depth = 0;
  let end = braceStart;
  for (; end < source.length; end += 1) {
    const ch = source[end];
    if (ch === '{') depth += 1;
    if (ch === '}') {
      depth -= 1;
      if (depth === 0) {
        end += 1;
        break;
      }
    }
  }
  return source.slice(start, end);
}

test('signup method resolution freezes per run and falls back when phone signup is unavailable', async () => {
  const api = new Function(`
const SIGNUP_METHOD_EMAIL = 'email';
const SIGNUP_METHOD_PHONE = 'phone';
const DEFAULT_SIGNUP_METHOD = SIGNUP_METHOD_EMAIL;
const logs = [];
let state = {
  signupMethod: 'phone',
  phoneVerificationEnabled: true,
  plusModeEnabled: false,
  contributionMode: false,
  resolvedSignupMethod: null,
};
async function getState() { return { ...state }; }
async function setState(updates) { state = { ...state, ...updates }; }
async function addLog(message, level = 'info') { logs.push({ message, level }); }
${extractFunction('normalizeSignupMethod')}
${extractFunction('canUsePhoneSignup')}
${extractFunction('resolveSignupMethod')}
${extractFunction('ensureResolvedSignupMethodForRun')}
return {
  logs,
  get state() { return state; },
  setState,
  resolveSignupMethod,
  ensureResolvedSignupMethodForRun,
};
`)();

  assert.equal(api.resolveSignupMethod({ signupMethod: 'phone', phoneVerificationEnabled: true }), 'phone');
  assert.equal(api.resolveSignupMethod({ signupMethod: 'phone', phoneVerificationEnabled: false }), 'email');
  assert.equal(api.resolveSignupMethod({ signupMethod: 'phone', phoneVerificationEnabled: true, plusModeEnabled: true }), 'email');
  assert.equal(api.resolveSignupMethod({ signupMethod: 'email', resolvedSignupMethod: 'phone', phoneVerificationEnabled: false }), 'phone');

  assert.equal(await api.ensureResolvedSignupMethodForRun(), 'phone');
  assert.equal(api.state.resolvedSignupMethod, 'phone');

  await api.setState({ signupMethod: 'email', phoneVerificationEnabled: false });
  assert.equal(await api.ensureResolvedSignupMethodForRun(), 'phone');
  assert.equal(api.state.resolvedSignupMethod, 'phone');

  await api.setState({ resolvedSignupMethod: null, signupMethod: 'phone', phoneVerificationEnabled: false });
  assert.equal(await api.ensureResolvedSignupMethodForRun({ force: true }), 'email');
  assert.equal(api.state.resolvedSignupMethod, 'email');
  assert.equal(api.logs.some((entry) => /固定为邮箱注册/.test(entry.message)), true);
});

test('background step definitions resolve titles from the frozen signup method', () => {
const api = new Function(`
const captured = [];
const PLUS_PAYMENT_METHOD_PAYPAL = 'paypal';
const PLUS_PAYMENT_METHOD_GOPAY = 'gopay';
const PLUS_PAYMENT_METHOD_GPC_HELPER = 'gpc-helper';
const self = {
  MultiPageStepDefinitions: {
    getSteps(options) {
      captured.push(options);
      return [{
        id: 2,
        key: 'submit-signup-email',
        title: options.signupMethod === 'phone' ? '注册并输入手机号' : '注册并输入邮箱',
      }];
    },
  },
};
${extractFunction('isPlusModeState')}
${extractFunction('normalizePlusPaymentMethod')}
${extractFunction('normalizeSignupMethod')}
${extractFunction('getSignupMethodForStepDefinitions')}
${extractFunction('getStepDefinitionsForState')}
return {
  getCaptured: () => captured.slice(),
  getStepDefinitionsForState,
};
`)();

  const steps = api.getStepDefinitionsForState({
    plusModeEnabled: true,
    plusPaymentMethod: 'gopay',
    signupMethod: 'email',
    resolvedSignupMethod: 'phone',
  });

  assert.deepEqual(api.getCaptured(), [{
    plusModeEnabled: true,
    plusPaymentMethod: 'gopay',
    signupMethod: 'phone',
  }]);
  assert.equal(steps[0].title, '注册并输入手机号');
});
