import BackendError from '../../errors/BackendError';
import Locator from '../../services/Locator';
import CasinoRoundsMode from './CasinoRoundsMode';
import Mode, { ModeBetConfig } from './Mode';

import type { SpinResp } from '../../types/api';
import type BalanceModel from '../BalanceModel';
import type BaseGameData from '../BaseGameData';
import type Lines from '../Lines';
import type { LinesConfig } from '../Lines';

/** Transactional casino rounds mode that credits balance after each spin. */
export default class TransCasinoRoundsMode extends CasinoRoundsMode
{
    public constructor(betConfig: ModeBetConfig, gameData: BaseGameData, lines: Lines | LinesConfig)
    {
        super(betConfig, gameData, lines);
        this._name = 'transactionalCasinoRounds';
    }

    public override get translatedTotalWin(): number
    {
        return 0;
    }

    public override async startRound(balanceModel: BalanceModel): Promise<void>
    {
        if (this._isRoundStarted)
        {
            return;
        }

        this._isRoundStarted = true;
        this._gameData = null as unknown as BaseGameData;
        this.resetWin();
        this.lockAutoGame();
        this.casinoRoundsIndicatorData.left -= 1;
        this.autoGame?.startSpin();

        const rawData = await Locator.network.bet(this.bet, true) as SpinResp | undefined;

        if (!rawData)
        {
            throw new Error('network problems');
        }

        if (rawData.errors?.length)
        {
            throw new BackendError('backend errors', this.mapErrors(rawData.errors));
        }

        this._gameData = (this.constructor as typeof Mode).createGameData(rawData);
        balanceModel.setBalance(rawData.balance.wallet);
        this.saveResponseToStorage(rawData);
    }

    public override afterRoundEnding(balanceModel: BalanceModel): void
    {
        this.addWinToBalance(balanceModel);
        this.checkAutoGame(balanceModel);
        this.resetWin();
        this.unlockAutoGame();
    }

    public override addWinToBalance(balanceModel: BalanceModel): void
    {
        if (this.gameData.preventAddBalance)
        {
            return;
        }

        balanceModel.add(this._win);
    }

    public override beforeExit(balanceModel: BalanceModel): void
    {
        this.addWinToBalance(balanceModel);
    }
}
