import { TransactionData } from '../value-objects/transaction-data';
import { TransactionMethod } from '../value-objects/transaction-method';
import { TransactionStatus } from '../value-objects/transaction-status';

export class Transaction {
  constructor(
    public readonly id: string,
    public readonly hash: string,
    public readonly status: TransactionStatus,
    public readonly block: number | null,
    public readonly networkId: string,
    public readonly timestamp: Date,
    public readonly from: string | null,
    public readonly to: string | null,
    public readonly interactedWith: string | null,
    public readonly value: string,
    public readonly fee: string | null,
    public readonly gasPrice: string | null,
    public readonly gasLimit: number | null,
    public readonly method: TransactionMethod,
    public readonly data: TransactionData[],
    public readonly createdAt: Date,
    public readonly updatedAt: Date,
    public readonly fromAddress: string | null = null,
    public readonly toAddress: string | null = null,
  ) {}

  public static create(
    id: string,
    hash: string,
    status: TransactionStatus,
    block: number | null,
    networkId: string,
    timestamp: Date,
    from: string | null,
    to: string | null,
    interactedWith: string | null,
    value: string,
    fee: string | null,
    gasPrice: string | null,
    gasLimit: number | null,
    method: TransactionMethod,
    data: TransactionData[],
  ): Transaction {
    const now = new Date();
    return new Transaction(
      id,
      hash,
      status,
      block,
      networkId,
      timestamp,
      from,
      to,
      interactedWith,
      value,
      fee,
      gasPrice,
      gasLimit,
      method,
      data,
      now,
      now,
    );
  }

  public updateStatus(status: TransactionStatus, block?: number): Transaction {
    return new Transaction(
      this.id,
      this.hash,
      status,
      block ?? this.block,
      this.networkId,
      this.timestamp,
      this.from,
      this.to,
      this.interactedWith,
      this.value,
      this.fee,
      this.gasPrice,
      this.gasLimit,
      this.method,
      this.data,
      this.createdAt,
      new Date(),
    );
  }
}
