import { BigNumber, ethers } from "ethers";
import { ClaimedEvent, DepositEvent, DepositResult, SharesBurnedEvent, ValidatorDepositedEvent } from "../types";
import { EthereumContractService } from "../contract";
import { formatContractErrors } from "../utils";

export class ValidatorClient {

    private readonly contractService: EthereumContractService;
    
    get contract() { return this.contractService.contract; }

    constructor(contract: EthereumContractService) {
        this.contractService = contract;
    }


    /**
     * 
     * @param amountWei an amount of liqETH (in WEI) to stake to the Outpost
     * @returns txHash (hash of the transaction), receipt, Staked event
     */
    async validatorDepositAndLockBond(): Promise<any> {
        const amountWei: BigNumber = ethers.utils.parseEther("32");

        // simulate call first
        try {
            await this.contract.DepositManager.callStatic.validatorDepositAndLockBond({ value: amountWei });
        } catch (err: any) {
            let errorObj = formatContractErrors(err);
            throw new Error(errorObj.name ?? errorObj.raw)
        }


        // send the tx to stake liqeth
        const tx = await this.contract.DepositManager.validatorDepositAndLockBond({ value: amountWei });

        // Wait for 1 confirmation 
        const receipt = await tx.wait(1);

        // Parse ValidatorDeposited event if present
        let staked: ValidatorDepositedEvent | undefined;
        const ev = receipt.events?.find((e) => e.event === 'Staked');

        if (ev && ev.args) {
            const { sender, amount, shares } = ev.args;
            staked = {
                sender,
                amount: BigNumber.from(amount),
                shares: BigNumber.from(shares),
            };
        }

        return {
            txHash: tx.hash,
            receipt,
            staked,
        };
    }


}