/**
 * Interactive script for testing shipment tracker contract
 * Usage: npx hardhat run scripts/interact.js --network <network>
 */

const { ethers } = require("hardhat");
const fs = require("fs");
const path = require("path");

async function main() {
  console.log("=== Optovia Blockchain Interaction Script ===\n");

  const [signer] = await ethers.getSigners();
  const network = await ethers.provider.getNetwork();

  console.log("Network:", network.name);
  console.log("Chain ID:", network.chainId.toString());
  console.log("Signer address:", signer.address);
  console.log("Balance:", ethers.formatEther(await ethers.provider.getBalance(signer.address)), "ETH\n");

  // Load deployment
  const deploymentFile = network.name === "localhost"
    ? "localhost.json"
    : network.chainId === 1337n
      ? "optovia-private.json"
      : `${network.name}.json`;

  const deploymentPath = path.join(__dirname, "..", "deployments", deploymentFile);

  if (!fs.existsSync(deploymentPath)) {
    console.error(`Deployment file not found: ${deploymentPath}`);
    console.error("Please deploy contracts first using: npm run deploy:private --network optovia");
    process.exit(1);
  }

  const deployment = JSON.parse(fs.readFileSync(deploymentPath));
  console.log("Contract addresses:");
  console.log("  ShipmentTracker:", deployment.contracts.ShipmentTracker.address);
  console.log("  ShipmentNFT:", deployment.contracts.ShipmentNFT.address);
  console.log();

  // Get contract instances
  const shipmentTracker = await ethers.getContractAt(
    "ShipmentTracker",
    deployment.contracts.ShipmentTracker.address,
    signer
  );

  // Check total shipments
  const totalShipments = await shipmentTracker.getTotalShipments();
  console.log("Total shipments:", totalShipments.toString(), "\n");

  // Create a test shipment
  const timestamp = Date.now();
  const externalId = `TEST-${timestamp}`;
  const testData = {
    productId: "PROD-001",
    quantity: 100,
    weight: "500kg",
    timestamp: timestamp
  };

  console.log("Creating test shipment:", externalId);
  const dataHash = ethers.keccak256(ethers.toUtf8Bytes(JSON.stringify(testData)));

  try {
    const tx = await shipmentTracker.createShipment(
      externalId,
      signer.address,
      "Test Manufacturer Inc.",
      "MFG-12345",
      signer.address,
      "Test Buyer Corp.",
      "BYR-67890",
      dataHash
    );

    console.log("Transaction sent:", tx.hash);
    console.log("Waiting for confirmation...");

    const receipt = await tx.wait();
    console.log("Transaction confirmed in block:", receipt.blockNumber);
    console.log("Gas used:", receipt.gasUsed.toString(), "\n");

    // Get shipment ID
    const shipmentId = await shipmentTracker.getShipmentByExternalId(externalId);
    console.log("Shipment ID:", shipmentId.toString());

    // Get shipment details
    console.log("\nFetching shipment details...");
    const shipment = await shipmentTracker.getShipment(shipmentId);

    console.log("\n=== Shipment Details ===");
    console.log("ID:", shipment[0].toString());
    console.log("External ID:", shipment[1]);
    console.log("Status:", getStatusName(shipment[2]));
    console.log("\nManufacturer:");
    console.log("  Address:", shipment[3][0]);
    console.log("  Name:", shipment[3][1]);
    console.log("  Company ID:", shipment[3][2]);
    console.log("\nBuyer:");
    console.log("  Address:", shipment[4][0]);
    console.log("  Name:", shipment[4][1]);
    console.log("  Company ID:", shipment[4][2]);
    console.log("\nTimestamps:");
    console.log("  Created:", new Date(Number(shipment[6]) * 1000).toISOString());
    console.log("  Updated:", new Date(Number(shipment[7]) * 1000).toISOString());

    // Test status update
    console.log("\n=== Testing Status Update ===");
    const statusTx = await shipmentTracker.updateShipmentStatus(shipmentId, 1); // ManufacturerConfirmed
    await statusTx.wait();
    console.log("Status updated to: ManufacturerConfirmed");

    // Test adding document
    console.log("\n=== Testing Document Addition ===");
    const docHash = "QmTestHash123456789abcdef";
    const docTx = await shipmentTracker.addDocument(shipmentId, docHash);
    await docTx.wait();
    console.log("Document added:", docHash);

    const documents = await shipmentTracker.getShipmentDocuments(shipmentId);
    console.log("Total documents:", documents.length);

    console.log("\n=== Test Complete ===");
    console.log("Shipment created and tested successfully!");
    console.log("View in Block Explorer: http://localhost:4000/tx/" + tx.hash);

  } catch (error) {
    console.error("\nError:", error.message);
    if (error.data) {
      console.error("Error data:", error.data);
    }
    process.exit(1);
  }
}

function getStatusName(status) {
  const statuses = [
    "Created",
    "ManufacturerConfirmed",
    "InTransit",
    "Delivered",
    "Cancelled"
  ];
  return statuses[status] || "Unknown";
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });
