import * as anchor from "@coral-xyz/anchor";
import { Keypair, SystemProgram, Transaction } from "@solana/web3.js";
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
import { expect } from "chai";
import fetch from "node-fetch";
import { getTestContext, setTestContext } from "../setup";

describe("Initialize Registry", () => {
  it("Initialize Global Registry", async () => {
    const ctx = getTestContext();
    const { connection, program, globalAdmin, registryPda, axumBaseUrl, db } = ctx;

    // ============================================================
    // STEP 1: Check DB State Before (should have no data)
    // ============================================================
    console.log("Checking database state before initialization...");

    const localAdminCountBefore = await db.getLocalAdminCount();
    const companyCountBefore = await db.getCompanyCount();

    expect(localAdminCountBefore).to.equal(0);
    expect(companyCountBefore).to.equal(0);
    console.log("✓ Database is clean before initialization");

    // ============================================================
    // STEP 2: Initialize Registry via API
    // ============================================================
    const euaMintKeypair = Keypair.generate();
    const ghgMintKeypair = Keypair.generate();

    const initRegistryRequest = {
      registry: registryPda.toBase58(),
      eua_mint: euaMintKeypair.publicKey.toBase58(),
      ghg_mint: ghgMintKeypair.publicKey.toBase58(),
      global_admin: globalAdmin.publicKey.toBase58(),
    };

    const createTxResponse = await fetch(
      `${axumBaseUrl}/api/registry/initialize-registry`,
      {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(initRegistryRequest),
      }
    );

    if (!createTxResponse.ok) {
      const error = await createTxResponse.text();
      throw new Error(`Failed to create transaction: ${error}`);
    }

    const { transaction_base64 } = await createTxResponse.json();

    const txBuffer = Buffer.from(transaction_base64, "base64");
    const transaction = Transaction.from(txBuffer);

    transaction.sign(globalAdmin, euaMintKeypair, ghgMintKeypair);

    const signedTxBase64 = transaction.serialize().toString("base64");

    const submitTxResponse = await fetch(`${axumBaseUrl}/api/submit-tx`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ transaction_base64: signedTxBase64 }),
    });

    if (!submitTxResponse.ok) {
      const error = await submitTxResponse.text();
      throw new Error(`Failed to submit transaction: ${error}`);
    }

    const { signature } = await submitTxResponse.json();
    console.log(`✓ Transaction signature: ${signature}`);

    // ============================================================
    // STEP 3: Store mints in context
    // ============================================================
    setTestContext({
      euaMint: euaMintKeypair.publicKey,
      ghgMint: ghgMintKeypair.publicKey,
    });

    // ============================================================
    // STEP 4: Verify On-Chain State
    // ============================================================
    const registry = await program.account.registry.fetch(registryPda);
    expect(registry.globalAdmin.equals(globalAdmin.publicKey)).to.be.true;
    expect(registry.companyCount).to.equal(0);
    expect(registry.localAdminCount).to.equal(0);

    console.log("✓ On-chain registry state verified");

    // ============================================================
    // STEP 5: Verify DB State After (should still be empty)
    // ============================================================
    console.log("Verifying database state after initialization...");

    // Registry initialization doesn't create DB records, so counts should still be 0
    const localAdminCountAfter = await db.getLocalAdminCount();
    const companyCountAfter = await db.getCompanyCount();

    expect(localAdminCountAfter).to.equal(0);
    expect(companyCountAfter).to.equal(0);
    console.log("✓ Database state correct (no records expected for registry init)");

    console.log("✓ Registry initialized successfully via API");
  });
});
