/** Canonical public data model for the additive Vaultfire V3 namespace. */
export type Address = `0x${string}`;
export type Bytes32 = `0x${string}`;
export type Hex = `0x${string}`;
export type Uint = bigint;

export const V3_PROTOCOL_VERSION = '3.0.0' as const;

export enum BondLifecycle {
  Uninitialized = 0,
  Proposed = 1,
  Accepted = 2,
  Funded = 3,
  Active = 4,
  SettlementRequested = 5,
  Finalizable = 6,
  Challenged = 7,
  SettlementFrozen = 8,
  Settled = 9,
  Cancelled = 10,
  Expired = 11,
  ForceExited = 12,
}

export enum ObjectiveRuleClass {
  MissedCanonicalDeadline = 1,
}

export interface EnforcementConfig {
  canonicalSource: Address;
  canonicalSourceCodehash: Bytes32;
  canonicalSourceId: Bytes32;
  obligationId: Bytes32;
  requiredBy: bigint;
  responseWindow: bigint;
  challengeWindow: bigint;
  decisionWindow: bigint;
  maximumSlash: bigint;
  evidenceSchemaHash: Bytes32;
  privacyExclusionsHash: Bytes32;
  attesterSetHash: Bytes32;
  adjudicatorSetHash: Bytes32;
  attesterThreshold: number;
  adjudicatorThreshold: number;
}

export interface SignerConfig {
  /** Must be empty for the current closed-rule AccountabilityBondV3Safe deployment. */
  attesters: readonly Address[];
  /** Must be empty for the current closed-rule AccountabilityBondV3Safe deployment. */
  adjudicators: readonly Address[];
}

/** Retained typed context for schema compatibility; current signer sets must be empty. */
export interface SignerIndependenceContext {
  aiCompany: Address;
  counterparty: Address;
  owner: Address;
  consensus: Address;
  disputeRegistry: Address;
  canonicalSource: Address;
  pilotController: Address;
}

/** Objective, closed-rule terms. Compatibility-only on-chain slots are fixed internally. */
export interface AccountabilityBondTerms {
  bondId: bigint;
  aiCompany: Address;
  counterparty: Address;
  companyStake: bigint;
  stakeAsset: Address;
  objectiveRuleHash: Bytes32;
  objectiveRuleClass: ObjectiveRuleClass.MissedCanonicalDeadline;
  objectiveRuleSchemaVersion: 1;
  activePeriodStart: bigint;
  activePeriodEnd: bigint;
  challengeWindow: bigint;
  nonce: bigint;
  chainId: V3ChainId;
  protocolVersion: typeof V3_PROTOCOL_VERSION;
}

export interface ObjectiveEvidence {
  bond: Address;
  chainId: V3ChainId;
  bondId: bigint;
  termsHash: Bytes32;
  ruleHash: Bytes32;
  canonicalSource: Address;
  canonicalSourceId: Bytes32;
  obligationId: Bytes32;
  requiredBy: bigint;
  recordedAt: bigint;
  observedAt: bigint;
  nonce: bigint;
  signatureDeadline: bigint;
}

export interface TypedResolution {
  bond: Address;
  chainId: V3ChainId;
  bondId: bigint;
  termsHash: Bytes32;
  ruleHash: Bytes32;
  evidenceHash: Bytes32;
  challengeHash: Bytes32;
  evidenceValid: boolean;
  nonce: bigint;
  deadline: bigint;
}

export interface EnforcementState {
  evidenceHash: Bytes32;
  challengeHash: Bytes32;
  requestedAt: bigint;
  responseDeadline: bigint;
  respondedAt: bigint;
  challengeDeadline: bigint;
  challengedAt: bigint;
  decisionDeadline: bigint;
  resolved: boolean;
}

/** Principal-only bilateral partnership terms. Compatibility-only slots are fixed internally. */
export interface PartnershipBondTerms {
  bondId: bigint;
  partyA: Address;
  partyB: Address;
  partyAStake: bigint;
  partyBStake: bigint;
  stakeAsset: Address;
  partnershipType: Bytes32;
  objectiveRuleClass: 0;
  objectiveRuleSchemaVersion: 0;
  proposalDeadline: bigint;
  activePeriodStart: bigint;
  activePeriodEnd: bigint;
  challengeWindow: bigint;
  nonce: bigint;
  chainId: V3ChainId;
  protocolVersion: typeof V3_PROTOCOL_VERSION;
}

export interface PartnershipMutualSettlement {
  bond: Address;
  chainId: V3ChainId;
  bondId: bigint;
  termsHash: Bytes32;
  partyAAmount: bigint;
  partyBAmount: bigint;
  nonce: bigint;
  deadline: bigint;
}

export interface AccountabilityBondReadModel {
  kind: 'accountability';
  address: Address;
  terms: AccountabilityBondTerms;
  termsHash: Bytes32;
  state: BondLifecycle;
  fundedAt: bigint;
  settlementRequestedAt: bigint;
  fundedAmount: bigint;
  upheldBreachRecorded: boolean;
  slashedAmount: bigint;
  settlementSnapshot: Bytes32;
  challengeDisputeId: bigint;
  challengeChallenger: Address;
  challengeSettlementSnapshot: Bytes32;
  challengeSettlementRequestedAt: bigint;
  challengeFiledAt: bigint;
  enforcement: EnforcementConfig;
  enforcementState: EnforcementState;
}

export interface PartnershipBondReadModel {
  kind: 'partnership';
  address: Address;
  terms: PartnershipBondTerms;
  termsHash: Bytes32;
  state: BondLifecycle;
  fundedAt: bigint;
  settlementRequestedAt: bigint;
  partyAFunded: bigint;
  partyBFunded: bigint;
  settlementHumanBps: number;
  settlementAiBps: number;
  settlementPartnershipBps: number;
  settlementSnapshot: Bytes32;
  challengeDisputeId: bigint;
  challengeChallenger: Address;
  challengeSettlementSnapshot: Bytes32;
  challengeSettlementRequestedAt: bigint;
  challengeFiledAt: bigint;
}

export type BondReadModel = AccountabilityBondReadModel | PartnershipBondReadModel;

export interface PullCreditReadModel {
  contract: Address;
  asset: Address;
  holder: Address;
  amount: bigint;
  liability: bigint;
}

export interface SolvencyReadModel {
  contract: Address;
  asset: Address;
  assets: bigint;
  creditLiability: bigint;
  lockedPrincipalLiability: bigint;
  totalLiability: bigint;
  solvent: boolean;
  observedAt: bigint;
}

export interface MandateReadModel {
  contract: Address;
  mandateHash: Bytes32;
  registered: boolean;
  revoked: boolean;
  registeredAt: bigint;
  notBefore: bigint;
  notAfter: bigint;
  nonce: bigint;
  spentSoFar: bigint;
  chainId: bigint;
  identityRegistryChainId: bigint;
  principalAgentId: bigint;
  operatorAgentId: bigint;
  principal: Address;
  operator: Address;
  beneficiary: Address;
  identityRegistry: Address;
  identityRegistryCodehash: Bytes32;
  protocolVersionHash: Bytes32;
}

export interface CapabilityReadModel {
  subject: Address;
  target: Address;
  capability: Bytes32;
  allowed: boolean;
  mandateId: Bytes32 | null;
  validUntil: bigint | null;
  evidenceHash: Bytes32 | null;
}

export interface GovernanceReadModel {
  governance: Address;
  signers: readonly Address[];
  threshold: number;
  proposalCount: bigint;
  timelockSeconds: bigint;
  minimumTimelockSeconds: bigint;
  proposalLifetime: bigint;
  governanceConfigVersion: bigint;
  canonicalPolicySha256: Bytes32;
  governancePolicyCommitment: Bytes32;
  guardianRotationDelay: bigint;
  pendingGuardian: Address;
  pendingGuardianAcceptAfter: bigint;
  guardianPauseTargetCount: bigint;
  policyVersion: bigint;
  policyCommitment: Bytes32;
  proposalPolicyCommitment: Bytes32 | null;
  callPolicy: Readonly<{
    target: Address;
    selector: Hex;
    allowed: boolean;
    maxValue: bigint;
  }> | null;
  guardian: Address;
}

export type X402Lifecycle = 'unknown' | 'discovered' | 'challenged' | 'settled' | 'rejected' | 'expired';

export interface X402StatusReadModel {
  paymentId: Bytes32;
  state: X402Lifecycle;
  chainId: V3ChainId;
  asset: Address;
  amount: bigint;
  payer: Address | null;
  payee: Address | null;
  updatedAt: bigint;
}

export interface X402DiscoveryReadModel {
  resource: string;
  chainId: V3ChainId;
  endpoint: string;
  methods: readonly string[];
  capabilities: readonly Bytes32[];
  expiresAt: bigint | null;
}

export interface X402ChallengeReadModel {
  challengeId: Bytes32;
  paymentId: Bytes32;
  commitment: Bytes32;
  openedAt: bigint;
  deadline: bigint;
  resolved: boolean;
}

export interface X402ReceiptReadModel {
  receiptId: Bytes32;
  paymentId: Bytes32;
  chainId: V3ChainId;
  asset: Address;
  amount: bigint;
  payer: Address;
  payee: Address;
  settledAt: bigint;
  transactionHash: Bytes32;
}

export type V3ChainId = 8453 | 84532;
export type V3DeploymentName =
  | 'accountabilityBond'
  | 'partnershipBond'
  | 'governance'
  | 'mandateRegistry';

export interface V3Deployment {
  address: Address | null;
  abiIdentity: Bytes32 | null;
  /** Exact keccak256 of independently observed deployed runtime bytecode. */
  runtimeCodeHash: Bytes32 | null;
}

export interface V3NetworkProfile {
  chainId: V3ChainId;
  name: 'Base' | 'Base Sepolia';
  status: 'unconfigured' | 'degraded' | 'configured';
  deployments: Readonly<Record<V3DeploymentName, Readonly<V3Deployment>>>;
}

export type RouteDisposition = 'adapter-required' | 'degraded' | 'unavailable' | 'retired';

export interface RouteMetadata {
  route: V3ReadRoute;
  disposition: RouteDisposition;
  retirement: Readonly<{
    retiredAt: string;
    replacement: V3ReadRoute | null;
    reason: string;
  }> | null;
}

export interface RetiredRouteMetadata {
  route: 'latest' | 'v2-fallback';
  disposition: 'retired';
  retirement: Readonly<{
    retiredAt: string;
    replacement: V3ReadRoute | null;
    reason: string;
  }>;
}

export type V3ReadRoute =
  | 'bonds'
  | 'pullCredits'
  | 'solvency'
  | 'mandates'
  | 'capabilities'
  | 'taskEscrow'
  | 'governance'
  | 'x402.status'
  | 'x402.discovery'
  | 'x402.challenge'
  | 'x402.receipt';
