// core/types/interfaces/testing.ts
// Utility types for testing purposes

import type { DeepPartial } from './base';
import type { IChainConfig } from './config';
import type { IReadyContext } from './pipeline';
import type { IAccountState, IAssetState, IDelegateState, IStakeState, ITokenState } from './state';
import type { IStateDB, ITxState } from './statedb';

// ============ Error Types ============

/**
 * Custom error interface with code property for pipeline errors
 * Compatible with @ocap/util CustomError
 */
export interface ITestError extends Error {
  code?: string;
}

/**
 * Next callback type for pipe functions
 */
export type PipeNextFn = (err?: ITestError) => void;

// ============ Context Types ============

/**
 * Partial transaction context for test setup
 * Allows creating context objects with only the fields needed for a specific test
 * Uses IReadyContext as the base which includes all phase fields
 */
export type PartialTransactionContext<TItx = unknown> = DeepPartial<IReadyContext<TItx>>;

/**
 * Mock StateDB type for testing
 * All methods are optional to allow partial mocking
 */
export type MockStateDB = Partial<IStateDB>;

/**
 * Mock ChainConfig for testing
 * All fields are optional
 */
export type MockChainConfig = DeepPartial<IChainConfig>;

// ============ State Types ============

/**
 * Mock account state for testing
 */
export type MockAccountState = DeepPartial<IAccountState>;

/**
 * Mock asset state for testing
 */
export type MockAssetState = DeepPartial<IAssetState>;

/**
 * Mock token state for testing
 */
export type MockTokenState = DeepPartial<ITokenState>;

/**
 * Mock stake state for testing
 */
export type MockStakeState = DeepPartial<IStakeState>;

/**
 * Mock delegate state for testing
 */
export type MockDelegateState = DeepPartial<IDelegateState>;

/**
 * Mock tx state for testing
 */
export type MockTxState = DeepPartial<ITxState>;

// ============ Full Test Context ============

/**
 * Create a type-safe partial context for testing
 * Usage: const ctx = createTestContext<MyItxType>({ senderState: mockState });
 */
export type TestContext<TItx = unknown> = PartialTransactionContext<TItx> & {
  // Ensure required base fields are present
  txBase64: string;
  statedb: MockStateDB;
  config: MockChainConfig;
};

// ============ Pipe Function Types ============

/**
 * Helper type for mocking pipe functions in tests
 */
export type MockPipeFunction<TContext = unknown> = (context: TContext, next: PipeNextFn) => void | Promise<void>;

/**
 * Helper type for mocking error pipe functions in tests
 */
export type MockErrorPipeFunction<TContext = unknown> = (
  err: ITestError,
  context: TContext,
  next: PipeNextFn
) => void | Promise<void>;

// ============ Test Result Types ============

/**
 * Result type for executeTx helper in protocol tests
 */
export interface IExecuteResult {
  err?: Error | null;
  txHash?: string;
}

/**
 * Pipe test result with optional error
 */
export interface IPipeTestResult {
  err?: ITestError;
}
