/**
 * SIMULATION DATA ONLY.
 *
 * This app is a static, read-only migration console. Nothing in this file is a
 * validated deployment address. The repository contains no validated V3
 * deployment addresses (see `pr8/migration/base-pilot-batch.example.json`,
 * where every target is still `REPLACE_WITH_*`), so every address below is a
 * deliberately fake, obviously-patterned placeholder and is labelled as such
 * everywhere it is rendered.
 *
 * Shapes follow `pr7/api/v3/protocol-solvency.ts` (`dataSourceErrors`,
 * `finality`, `blockNumber`, `contractStatus`) and the pilot caps in
 * `pr8/pilot/BASE_PILOT_CONFIG.md`.
 */

export const BASE_CHAIN_ID = 8453;

/** Domain values mirror `v3-src/contracts/signatures/EIP712BaseV3.sol`. */
export const EIP712_DOMAIN_NAME = "Vaultfire";
export const EIP712_DOMAIN_VERSION = "3.0.0";

/** Fake verifying contract — NOT a deployment. */
export const SIMULATED_VERIFYING_CONTRACT =
  "0x3333333333333333333333333333333333339999";

/** Fake position owner — NOT a real account. */
export const SIMULATED_OWNER = "0x000000000000000000000000000000000000a11c";

/** Deterministic (non-clock) intent parameters so payloads are reproducible. */
export const SIMULATED_NONCE = "7";
export const SIMULATED_DEADLINE = "1793491200"; // 2026-10-01T00:00:00Z, fixed constant

export type PositionKind =
  | "partnership-bond"
  | "accountability-bond"
  | "task-escrow"
  | "vault-shares"
  | "reputation"
  | "mutual-aid";

export type V3Target = {
  /** V3 contract name from `v3-src/contracts`. */
  contract: string;
  /** Fake target address, labelled as simulation data in the UI. */
  address: string;
  /** Pilot cap copy from `pr8/pilot/BASE_PILOT_CONFIG.md`. */
  capLabel: string;
  /** Cap in the position's base units (6-decimals USDC unless noted). */
  capBaseUnits: string;
  /** Irreversible steps must be flagged before signing. */
  reversible: boolean;
  /** How the move actually happens — two independent user-initiated steps. */
  mechanics: string;
};

export type V2Position = {
  id: string;
  /** bytes32 id used in the typed-data message; deterministic, not derived from a clock. */
  positionId: string;
  kind: PositionKind;
  label: string;
  v2Contract: string;
  v2Address: string;
  chainId: number;
  chainLabel: string;
  contractStatus: "active" | "legacy" | "deprecated" | "paused" | "read-only";
  assetSymbol: string;
  assetDecimals: number;
  amountBaseUnits: string;
  v2Note: string;
  /** `null` = no V3 equivalent in the pilot; the position stays in V2. */
  v3: V3Target | null;
};

export type SolvencySnapshot = {
  schemaVersion: string;
  protocolVersion: "v3";
  chainId: number;
  blockNumber: string | null;
  observedAt: string;
  finality: "soft" | "safe" | "finalized";
  /** Verbatim errors from `/api/v3/protocol/solvency`. Non-empty = migration blocked. */
  dataSourceErrors: string[];
};

export type Scenario = {
  id: "nominal" | "degraded";
  label: string;
  description: string;
  solvency: SolvencySnapshot;
};

export const POSITIONS: V2Position[] = [
  {
    id: "pb-1041",
    positionId:
      "0x0000000000000000000000000000000000000000000000000000000000000411",
    kind: "partnership-bond",
    label: "Partnership bond #1041",
    v2Contract: "AIPartnershipBondsV2",
    v2Address: "0x2222222222222222222222222222222222220001",
    chainId: BASE_CHAIN_ID,
    chainLabel: "Base",
    contractStatus: "active",
    assetSymbol: "USDC",
    assetDecimals: 6,
    amountBaseUnits: "100000000", // 100.000000 USDC
    v2Note: "Stays live on V2 whether or not you migrate. Nothing is paused.",
    v3: {
      contract: "PartnershipBondV3Safe",
      address: "0x3333333333333333333333333333333333330001",
      capLabel: "100 USDC per side (or 0.05 ETH per side)",
      capBaseUnits: "100000000",
      reversible: true,
      mechanics:
        "Two independent transactions you send yourself: withdraw the V2 stake to your wallet via the existing V2 path, then fund a fresh V3 bond. Either step can be abandoned.",
    },
  },
  {
    id: "ab-388",
    positionId:
      "0x0000000000000000000000000000000000000000000000000000000000000184",
    kind: "accountability-bond",
    label: "Accountability bond #388",
    v2Contract: "AIAccountabilityBondsV2",
    v2Address: "0x2222222222222222222222222222222222220002",
    chainId: BASE_CHAIN_ID,
    chainLabel: "Base",
    contractStatus: "active",
    assetSymbol: "USDC",
    assetDecimals: 6,
    amountBaseUnits: "500000000", // 500 USDC — exceeds the pilot cap
    v2Note:
      "Above the pilot cap. Only the capped amount is eligible; the remainder stays in V2.",
    v3: {
      contract: "AccountabilityBondV3Safe",
      address: "0x3333333333333333333333333333333333330002",
      capLabel: "250 USDC total",
      capBaseUnits: "250000000",
      reversible: true,
      mechanics:
        "You deactivate the V2 bond through the existing V2 path, then create a fresh V3 bond up to the cap. No automatic transfer at any point.",
    },
  },
  {
    id: "te-77",
    positionId:
      "0x000000000000000000000000000000000000000000000000000000000000004d",
    kind: "task-escrow",
    label: "Task escrow #77 (in flight)",
    v2Contract: "VaultfireTaskEscrow",
    v2Address: "0x2222222222222222222222222222222222220003",
    chainId: BASE_CHAIN_ID,
    chainLabel: "Base",
    contractStatus: "active",
    assetSymbol: "USDC",
    assetDecimals: 6,
    amountBaseUnits: "40000000",
    v2Note:
      "In-flight tasks complete on V2. This position has no V3 equivalent during the pilot.",
    v3: null,
  },
  {
    id: "vault-shares",
    positionId:
      "0x0000000000000000000000000000000000000000000000000000000000000009",
    kind: "vault-shares",
    label: "BIP vault shares",
    v2Contract: "VaultfireBIPVault",
    v2Address: "0x2222222222222222222222222222222222220004",
    chainId: BASE_CHAIN_ID,
    chainLabel: "Base",
    contractStatus: "active",
    assetSymbol: "USDC",
    assetDecimals: 6,
    amountBaseUnits: "1200000000",
    v2Note:
      "Shares are never migrated. You would withdraw V2 shares yourself, then deposit fresh into the V3 vault.",
    v3: {
      contract: "VaultfireBIPVaultV3",
      address: "0x3333333333333333333333333333333333330004",
      capLabel: "2,500 USDC total deposits (pool-wide)",
      capBaseUnits: "1200000000",
      reversible: false,
      mechanics:
        "Irreversible within the pilot window: a V3 deposit mints new shares at the V3 price. Your V2 shares are not burned by this app and V2 keeps redeeming them.",
    },
  },
  {
    id: "streetcred",
    positionId:
      "0x0000000000000000000000000000000000000000000000000000000000000002",
    kind: "reputation",
    label: "StreetCred trust profile",
    v2Contract: "VaultfireStreetCred",
    v2Address: "0x2222222222222222222222222222222222220005",
    chainId: BASE_CHAIN_ID,
    chainLabel: "Base",
    contractStatus: "active",
    assetSymbol: "SCORE",
    assetDecimals: 0,
    amountBaseUnits: "742",
    v2Note:
      "Your V2 badge is kept and stays labelled 'Legacy V2'. Nothing is revoked.",
    v3: {
      contract: "StreetCredV3",
      address: "0x3333333333333333333333333333333333330005",
      capLabel: "No value cap — reissue only, no funds move",
      capBaseUnits: "742",
      reversible: true,
      mechanics:
        "A new V3 attestation is issued under the same identity. No funds move. The V2 badge remains readable.",
    },
  },
  {
    id: "mutual-aid",
    positionId:
      "0x0000000000000000000000000000000000000000000000000000000000000001",
    kind: "mutual-aid",
    label: "Agent pool membership",
    v2Contract: "AgentInsurancePool",
    v2Address: "0x2222222222222222222222222222222222220006",
    chainId: BASE_CHAIN_ID,
    chainLabel: "Base",
    contractStatus: "legacy",
    assetSymbol: "USDC",
    assetDecimals: 6,
    amountBaseUnits: "75000000",
    v2Note:
      "V2 naming implied cover that never existed. V3 renames it and makes the discretionary nature explicit.",
    v3: {
      contract: "MutualAidPoolV3",
      address: "0x3333333333333333333333333333333333330006",
      capLabel: "250 USDC single payout · 5,000 USDC lifetime, pool-wide",
      capBaseUnits: "75000000",
      reversible: true,
      mechanics:
        "You contribute to the V3 pool yourself. Payouts are discretionary. Mutual aid is not insurance — there is no policy, no entitlement, and no guaranteed payout.",
    },
  },
];

export const SCENARIOS: Record<Scenario["id"], Scenario> = {
  nominal: {
    id: "nominal",
    label: "Solvency feed healthy",
    description:
      "Simulated `/api/v3/protocol/solvency` response with no dataSourceErrors.",
    solvency: {
      schemaVersion: "1.0.0",
      protocolVersion: "v3",
      chainId: BASE_CHAIN_ID,
      blockNumber: "24118032",
      observedAt: "2026-08-20T12:00:00.000Z",
      finality: "finalized",
      dataSourceErrors: [],
    },
  },
  degraded: {
    id: "degraded",
    label: "Solvency feed failing",
    description:
      "Simulated HTTP 503 from `/api/v3/protocol/solvency`. Selection and signing must be blocked.",
    solvency: {
      schemaVersion: "1.0.0",
      protocolVersion: "v3",
      chainId: BASE_CHAIN_ID,
      blockNumber: null,
      observedAt: "2026-08-20T12:00:00.000Z",
      finality: "soft",
      dataSourceErrors: [
        "liability-read-plan-unconfigured",
        "base:8453 eth_call reverted — solvency view unavailable (HTTP 503)",
      ],
    },
  },
};

export function formatAmount(baseUnits: string, decimals: number): string {
  if (decimals === 0) return BigInt(baseUnits).toLocaleString("en-US");
  const raw = BigInt(baseUnits);
  const div = BigInt(10) ** BigInt(decimals);
  const whole = raw / div;
  const frac = (raw % div).toString().padStart(decimals, "0").slice(0, 2);
  return `${whole.toLocaleString("en-US")}.${frac}`;
}

/** Eligible amount = min(position amount, pilot cap). */
export function eligibleBaseUnits(p: V2Position): string {
  if (!p.v3) return "0";
  const amount = BigInt(p.amountBaseUnits);
  const cap = BigInt(p.v3.capBaseUnits);
  return (amount < cap ? amount : cap).toString();
}
