import { Address } from "viem/accounts";
import { RelayerResponse } from "./interfaces/relayer/request.js";
import { QuoteResponse } from "./interfaces/relayer/quote.js";

export abstract class RelayerMarshall {
  abstract toJSON(): object;
}

export class DetailsMarshall extends RelayerMarshall {
  constructor(private details: {
    feeBPS: bigint,
    feeReceiverAddress: Address,
    chainId?: number,
    assetAddress?: Address,
    minWithdrawAmount?: bigint,
    maxGasPrice?: bigint,
  }) {
    super();
  }
  override toJSON(): object {

    let maxGasPrice: string | null;
    if (this.details.maxGasPrice !== undefined) {
      maxGasPrice = this.details.maxGasPrice.toString(10);
    }
    else {
      maxGasPrice = null;
    }

    return {
      feeBPS: this.details.feeBPS.toString(),
      feeReceiverAddress: this.details.feeReceiverAddress.toString(),
      chainId: this.details.chainId,
      assetAddress: this.details.assetAddress?.toString(),
      minWithdrawAmount: this.details.minWithdrawAmount?.toString(),
      maxGasPrice
    };
  }
}

export class RequestMashall extends RelayerMarshall {
  constructor(readonly response: RelayerResponse) {
    super();
  }
  override toJSON(): object {
    return this.response;
  }
}

export class QuoteMarshall extends RelayerMarshall {
  constructor(readonly response: QuoteResponse) {
    super();
  }

  addFeeCommitment(feeCommitment: {
    expiration: number
    withdrawalData: `0x${string}`,
    signedRelayerCommitment: `0x${string}`
  }) {
    this.response.feeCommitment = feeCommitment;
  }

  override toJSON(): object {
    return {
      baseFeeBPS: this.response.baseFeeBPS.toString(),
      feeBPS: this.response.feeBPS.toString(),
      feeCommitment: this.response.feeCommitment
    }
  }
}
