// src/staker/staker.ts

import { ChainID, EvmChainID, SolChainID } from '@wireio/core';
import { IStakingClient, StakerConfig } from './types';
import { SolanaStakingClient } from './networks/solana/solana';
import { EthereumStakingClient } from './networks/ethereum/ethereum';

export class Staker {
    public selectedChainID?: ChainID;
    private clients: Map<ChainID, IStakingClient> = new Map();

    /**
     * Get the staking client for the currently selected chain.
     * @returns The staking client instance.
     */
    get client(): IStakingClient | undefined {
        return this.selectedChainID && this.isConfigured(this.selectedChainID)
            ? this.clients.get(this.selectedChainID) : undefined;
    }

    /** Is there a client configured for this chain? */
    isConfigured(chainId: ChainID): boolean {
        return this.clients.has(chainId);
    }

    /** List of configured chains */
    listConfigured(): ChainID[] {
        return [...this.clients.keys()];
    }

    constructor(config: StakerConfig | StakerConfig[], selectedChainID?: ChainID) {
        if (!config) throw new Error('StakerConfig is required');
        if (!Array.isArray(config)) config = [config];

        // console.log('STAKER INIT', config);

        config.forEach((cfg) => {
            switch (cfg.network.chainId) {
                case SolChainID.Mainnet:
                case SolChainID.Devnet:
                    this.clients.set(cfg.network.chainId, new SolanaStakingClient(cfg));
                    break;

                case EvmChainID.Ethereum:
                case EvmChainID.Hoodi:
                    this.clients.set(cfg.network.chainId, new EthereumStakingClient(cfg));
                    break;

                default:
                    console.log(`No staking client available for chain ${cfg.network.chainId}`);
                    throw new Error(`Unsupported network curve: ${cfg.network.name}`);
            }
        });

        this.selectedChainID = selectedChainID;
    }

    /**
     * Select a chain. Returns true if a client exists for it, false otherwise.
     * (We still record the selectedChainID so the UI can reflect the chosen chain.)
     */
    setChain(chainID: ChainID): boolean {
        const hasClient = this.clients.has(chainID);

        if (!hasClient) {
            console.warn(`[Staker] setChain: no client configured for chain ${chainID}`);
            return false;
        }

        this.selectedChainID = chainID;
        return true;
    }
}