/**
 * Versioned indexer read model.
 *
 * The V2 indexer keeps its schema. V3 events land in a distinct namespace with
 * an explicit protocolVersion column so aggregations, subgraph queries, and API
 * responses never silently mix V2 and V3.
 *
 * Design goals:
 *   - Idempotent writes (event UID = (chainId, txHash, logIndex))
 *   - Reorg-aware (blockHash tracking, safe/finalized labels)
 *   - Backfill-first, live-tail-second
 *   - Explicit protocolVersion column on every row
 *   - Deprecation flag copied from route/contract registry
 */

export interface EventUid {
  chainId: number;
  txHash: `0x${string}`;
  logIndex: number;
}

export interface VersionedEvent<TArgs = Record<string, unknown>> {
  uid: EventUid;
  blockNumber: bigint;
  blockHash: `0x${string}`;
  removed: boolean;
  protocolVersion: "v2" | "v3";
  contractStatus: "active" | "legacy" | "deprecated" | "paused" | "read-only";
  contract: string;
  address: `0x${string}`;
  eventSig: string;
  args: TArgs;
  observedAt: string;
  finality: "soft" | "safe" | "finalized";
}

export function eventKey(uid: EventUid): string {
  return `${uid.chainId}:${uid.txHash.toLowerCase()}:${uid.logIndex}`;
}

// Named V3 event tables — kept isolated from V2 tables so migrations stay reversible.
export type MandateRegisteredV3Row      = VersionedEvent<{ mandateHash: `0x${string}`; principal: `0x${string}`; operator: `0x${string}`; notBefore: string; notAfter: string; }>;
export type BondCreatedV3Row            = VersionedEvent<{ bondId: string; partyA: `0x${string}`; partyB: `0x${string}`; }>;
export type BondStateTransitionV3Row    = VersionedEvent<{ bondId: string; from: number; to: number; reason: string; }>;
export type RewardCommittedV3Row        = VersionedEvent<{ programId: string; bondId: string; amount: string; }>;
export type RewardIssuedV3Row           = VersionedEvent<{ programId: string; bondId: string; to: `0x${string}`; amount: string; }>;
export type PaymentCreditedV3Row        = VersionedEvent<{ recipient: `0x${string}`; asset: `0x${string}`; amount: string; }>;
export type PaymentWithdrawnV3Row       = VersionedEvent<{ recipient: `0x${string}`; asset: `0x${string}`; amount: string; }>;
export type TaskCreatedV3Row            = VersionedEvent<{ taskId: string; creator: `0x${string}`; amount: string; }>;
export type ValidatorSlashedV3Row       = VersionedEvent<{ validator: `0x${string}`; amount: string; treasury: `0x${string}`; reason: `0x${string}`; }>;
export type ScoreUpdatedV3Row           = VersionedEvent<{ subject: `0x${string}`; scoreBps: number; evidenceCount: number; evidenceRoot: `0x${string}`; }>;
export type MutualAidPaidV3Row          = VersionedEvent<{ to: `0x${string}`; amount: string; reasonHash: `0x${string}`; }>;

/**
 * Solvency delta view (Invariant #1): for every V3 contract of interest, live
 * assetsWei and liabilitiesWei snapshots at safe or finalized blocks. Rows are
 * NEVER written if either value could not be read — the row is skipped and an
 * error is emitted on the dataSourceErrors channel.
 */
export interface SolvencySnapshotRow {
  chainId: number;
  address: `0x${string}`;
  contract: string;
  protocolVersion: "v2" | "v3";
  blockNumber: string;
  blockHash: `0x${string}`;
  observedAt: string;
  finality: "safe" | "finalized";
  assetsWei: string;
  liabilitiesWei: string;
  deltaWei: string;                 // assetsWei - liabilitiesWei; must be >= 0
  schemaVersion: string;
}
