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

describe("Initialize Market (API)", () => {
  it("Initialize Secondary Market via API", async () => {
    const ctx = getTestContext();
    const { connection, program, axumBaseUrl, marketPda, registryPda, globalAdmin } = ctx;

    const lotSize = 1; // Minimum trade size: 1 EUA
    const tickSize = 1000000; // Price increments: 1 USDC (6 decimals)

    // Step 1: Create API request payload
    const request = {
      market: marketPda.toBase58(),
      registry: registryPda.toBase58(),
      global_admin: globalAdmin.publicKey.toBase58(),
      system_program: SystemProgram.programId.toBase58(),
      lot_size: lotSize,
      tick_size: tickSize,
    };

    console.log("Calling API to create initialize market transaction...");

    // Step 2: Call Axum API to get unsigned transaction
    const createTxResponse = await fetch(
      `${axumBaseUrl}/api/secondary-market/initialize-market`,
      {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(request),
      }
    );

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

    const { transaction_base64, message } = await createTxResponse.json();
    console.log(`API Response: ${message}`);

    // Step 3: Deserialize and sign transaction
    const txBuffer = Buffer.from(transaction_base64, "base64");
    const transaction = Transaction.from(txBuffer);

    // Sign with globalAdmin (the only required signer - it's the payer and authority)
    transaction.sign(globalAdmin);

    console.log("Transaction signed locally");

    // Step 4: Submit signed transaction to backend
    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 5: Verify on-chain state
    const market = await program.account.marketConfig.fetch(marketPda);

    expect(market.admin.equals(globalAdmin.publicKey)).to.be.true;
    expect(market.registry.equals(registryPda)).to.be.true;
    expect(market.lotSize.toNumber()).to.equal(lotSize);
    expect(market.tickSize.toNumber()).to.equal(tickSize);
    expect(market.paused).to.be.false;
    // REMOVED: expect(market.nextOrderId.toNumber()).to.equal(1);
    expect(market.totalVolume.toNumber()).to.equal(0);
    expect(market.totalTrades.toNumber()).to.equal(0);

    console.log("✓ Market account state verified");
    console.log(`  - Admin: ${market.admin.toBase58()}`);
    console.log(`  - Registry: ${market.registry.toBase58()}`);
    console.log(`  - Lot Size: ${market.lotSize.toNumber()}`);
    console.log(`  - Tick Size: ${market.tickSize.toNumber()}`);
    console.log(`  - Paused: ${market.paused}`);
    // REMOVED: console.log(`  - Next Order ID: ${market.nextOrderId.toNumber()}`);

    // Step 6: Verify events/logs
    const txDetails = await connection.getTransaction(signature, {
      commitment: "confirmed",
      maxSupportedTransactionVersion: 0,
    });

    if (txDetails?.meta?.logMessages) {
      const logs = txDetails.meta.logMessages;

      // Check for market initialized message
      const hasMarketInitLog = logs.some((log) =>
        log.includes("Market initialized") &&
        log.includes(`lot_size: ${lotSize}`) &&
        log.includes(`tick_size: ${tickSize}`)
      );
      expect(hasMarketInitLog).to.be.true;
      console.log("✓ Market initialized log message found");

      // Check for MarketInitialized event (Anchor emits events as logs)
      const hasEventLog = logs.some((log) => log.includes("MarketInitialized"));
      if (hasEventLog) {
        console.log("✓ MarketInitialized event emitted");
      }
    }

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