#!/usr/bin/env node
/* eslint-disable no-console */

const crypto = require('crypto');
const web3 = require('@solana/web3.js');

const RPC = process.env.SOLANA_RPC || 'https://api.devnet.solana.com';
const LOGIN_GUARD_PROGRAM_ID = '3xkopA7cXagxzMFrKdv3NCBfV6BKiRJCk69kr27M2sRo';
const SIM_PAYER = 'FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P';
const login = String(process.argv[2] || '').trim().toLowerCase();

if (!login) {
  console.error('Usage: node scripts/devnet/test_login_guard_precheck.js <login>');
  process.exit(1);
}

function discriminator(name) {
  return crypto.createHash('sha256').update(`global:${name}`).digest().subarray(0, 8);
}

function encodeClassifyLoginData(loginValue) {
  const disc = discriminator('classify_login');
  const str = Buffer.from(loginValue, 'utf8');
  const len = Buffer.alloc(4);
  len.writeUInt32LE(str.length, 0);
  return Buffer.concat([disc, len, str]);
}

function decodeU32FromBase64(b64) {
  const bytes = Buffer.from(b64, 'base64');
  if (bytes.length < 4) throw new Error('bad returnData');
  return bytes.readUInt32LE(0);
}

async function main() {
  const connection = new web3.Connection(RPC, 'confirmed');
  const programId = new web3.PublicKey(LOGIN_GUARD_PROGRAM_ID);
  const payer = new web3.PublicKey(SIM_PAYER);

  const ix = new web3.TransactionInstruction({
    programId,
    keys: [{ pubkey: payer, isSigner: true, isWritable: false }],
    data: encodeClassifyLoginData(login),
  });

  const { blockhash } = await connection.getLatestBlockhash('confirmed');
  const v0 = new web3.TransactionMessage({
    payerKey: payer,
    recentBlockhash: blockhash,
    instructions: [ix],
  }).compileToV0Message();
  const tx = new web3.VersionedTransaction(v0);

  const sim = await connection.simulateTransaction(tx, {
    commitment: 'confirmed',
    sigVerify: false,
    replaceRecentBlockhash: true,
  });

  if (sim?.value?.err) {
    console.error('Simulation error:', sim.value.err);
    console.error('Logs:', sim?.value?.logs || []);
    process.exit(2);
  }

  const returnData = sim?.value?.returnData;
  if (!returnData || returnData.programId !== LOGIN_GUARD_PROGRAM_ID) {
    console.error('No returnData from login_guard');
    console.error(JSON.stringify(sim, null, 2));
    process.exit(3);
  }

  const cls = decodeU32FromBase64(returnData.data[0]);
  const className = cls === 0 ? 'free' : cls === 1 ? 'premium' : cls === 2 ? 'company' : `unknown(${cls})`;
  console.log(JSON.stringify({
    login,
    classCode: cls,
    className,
    logs: sim?.value?.logs || [],
  }, null, 2));
}

main().catch((e) => {
  console.error(e?.stack || e?.message || String(e));
  process.exit(10);
});

