// core/types/interfaces/config.ts
// Chain configuration types, aligned with Proto types from type_pb.d.ts

import type {
  TAccountConfig,
  TCurveConfig,
  TDelegateConfig,
  TForeignToken,
  TForgeToken,
  TTransactionConfig,
  TTxFeeConfig,
  TTxGasConfig,
  TTxStakeConfig,
  TVaultConfig,
} from '../lib/type_pb';
import type { DeepPartial } from './base';

// ============ Direct Re-exports (Proto compatible) ============

export type { TDelegateConfig, TForeignToken, TTxFeeConfig, TCurveConfig };

// ============ Config-specific Types ============

/** Transaction type URL pattern like 'fg:t:transfer' */
export type TxTypeUrl = `fg:t:${string}`;

/** Map of transaction type URL to number value (size, fee, etc.) */
export type TxTypeMap = { default: number } & Partial<Record<TxTypeUrl, number>>;

// ============ Extended Types (with differences noted) ============

/**
 * Account configuration
 * Diff from TAccountConfig: pk is string (not Uint8Array), added moniker
 */
export interface IAccountConfig extends Omit<TAccountConfig, 'pk' | 'balance'> {
  pk: string;
  balance?: number;
  moniker?: string;
}

/**
 * Transaction gas configuration
 * Diff from TTxGasConfig: minStake/maxStake are number (Proto uses string)
 */
export interface ITxGasConfig extends Omit<TTxGasConfig, 'minStake' | 'maxStake'> {
  minStake: number;
  maxStake: number;
}

/**
 * Transaction stake configuration
 * Diff from TTxStakeConfig: added createCreditToken field
 */
export interface ITxStakeConfig extends TTxStakeConfig {
  createCreditToken: number;
}

/**
 * Transaction configuration
 * Diff from TTransactionConfig:
 * - txFee: TxTypeMap (Proto uses TTxFeeConfig[])
 * - txGas: ITxGasConfig (Proto uses TTxGasConfig)
 * - txStake: ITxStakeConfig (Proto uses TTxStakeConfig)
 * - added: maxTxSize, supportedTxs, multiSignV2Txs
 */
export interface ITransactionConfig extends Omit<TTransactionConfig, 'txFee' | 'txGas' | 'txStake' | 'delegate'> {
  maxTxSize: TxTypeMap;
  txFee: TxTypeMap;
  txGas: ITxGasConfig;
  txStake: ITxStakeConfig;
  delegate: TDelegateConfig;
  supportedTxs: string[];
  multiSignV2Txs: string[];
}

/**
 * Token configuration
 * Diff from TForgeToken:
 * - icon: string (Proto uses Uint8Array | string)
 * - initialSupply/totalSupply: number (Proto uses string)
 * - added: website, metadata, foreignToken
 */
export interface ITokenConfig extends Omit<TForgeToken, 'icon' | 'initialSupply' | 'totalSupply'> {
  icon: string;
  initialSupply: number;
  totalSupply: number;
  website?: string | null;
  /** Token metadata - format varies by token type (JSON structure kept flexible) */
  metadata?: unknown;
  foreignToken?: TForeignToken | null;
}

/**
 * Vault addresses configuration
 * Diff from TVaultConfig: all fields optional, added txFees array
 */
export interface IVaultsConfig extends Partial<TVaultConfig> {
  txFees?: string[];
}

/**
 * Consensus configuration (no Proto equivalent)
 * Index signature allows for chain-specific extensions
 */
export interface IConsensusConfig {
  maxValidators?: number;
  minValidatorStake?: string;
  blockTime?: number;
  maxBlockSize?: number;
  /** Extension point for chain-specific consensus config */
  [key: string]: unknown;
}

// ============ Composite Config Types ============

/** Default configuration (without required fields like address) */
export interface IDefaultConfig {
  transaction: ITransactionConfig;
  vaults: IVaultsConfig;
  accounts: IAccountConfig[];
  reservedSymbols: string[];
  token: Omit<ITokenConfig, 'description' | 'address'> & { description?: string; address?: string };
}

/** Full chain configuration */
export interface IChainConfig {
  chainId: string;
  chainName?: string;
  version: string;
  transaction: ITransactionConfig;
  moderator: IAccountConfig;
  accounts: IAccountConfig[];
  vaults: IVaultsConfig;
  token: ITokenConfig;
  consensus?: IConsensusConfig;
  reservedSymbols?: string[];
}

/** Partial chain configuration for create() input - uses DeepPartial since create() merges with defaults */
export type IChainConfigInput = DeepPartial<IChainConfig> & {
  chainId: string;
  version: string;
  moderator: IAccountConfig;
};

/**
 * Token ITX (inner transaction) for token creation
 * Similar to TTokenInfo but with string amounts
 */
export interface ITokenItx {
  name: string;
  description: string;
  symbol: string;
  unit: string;
  decimal: number;
  totalSupply: string;
  initialSupply: string;
  issuer: string;
  address: string;
  foreignToken?: TForeignToken | null;
  /** Token metadata - format varies by token type (JSON structure kept flexible) */
  metadata?: unknown;
  website?: string | null;
  icon: string;
}
