import BaseMachine from '../slotMachines/BaseMachine';
import { State, StateMachine } from '@popiplay/state-machine';

const SPEED_MODES = {
    NORMAL: 0,
    TURBO: 1
};

export type SpeedModesInput = {
    turbo: boolean,
    fastStop: boolean
    turboForced: boolean;
};

export default class SpeedModes extends StateMachine<BaseMachine>
{
    constructor(slotMachine: BaseMachine)
    {
        super(slotMachine);
        this.provideStates([
            new NormalMode(this),
            new TurboMode(this),
        ]);
        this.checkDependencies(slotMachine);
        this.setState(SPEED_MODES.NORMAL);
    }

    applyNormalModeSettings()
    {
    // add settings logic in an extended class
    }

    applyTurboModeSettings()
    {
    // add settings logic in an extended class
    }

    private checkDependencies(slotMachine: BaseMachine): void
    {
        if (!slotMachine.inputs.hasOwnProperty('turbo'))
        {
            throw new Error('\'turbo\' property is required in the inputs');
        }
        if (!slotMachine.inputs.hasOwnProperty('fastStop'))
        {
            throw new Error('\'fastStop\' property is required in the inputs');
        }
        if (!slotMachine.inputs.hasOwnProperty('turboForced'))
        {
            throw new Error('\'fastStop\' property is required in the inputs');
        }
    }
}

class NormalMode extends State
{
    machine: SpeedModes;
    constructor(machine: SpeedModes)
    {
        super('NormalSpeedMode');
        this.machine = machine;
    }

    override enter()
    {
        this.machine.applyNormalModeSettings();
    }

    override handleInput(input: SpeedModesInput)
    {
        if (input.turbo)
        {
            this.machine.setState(SPEED_MODES.TURBO);
        }
        else if (input.fastStop)
        {
            this.machine.setState(SPEED_MODES.TURBO);
        }
        else if (input.turboForced)
        {
            this.machine.setState(SPEED_MODES.TURBO);
        }
    }
}

class TurboMode extends State
{
    machine: SpeedModes;
    constructor(machine: SpeedModes)
    {
        super('TurboSpeedMode');
        this.machine = machine;
    }

    override enter()
    {
        this.machine.applyTurboModeSettings();
    }

    override handleInput(input: SpeedModesInput)
    {
        if (!input.turbo && !input.fastStop && !input.turboForced)
        {
            this.machine.setState(SPEED_MODES.NORMAL);
        }
    }
}
