import ValuableReelSymbol from '../entities/ValuableReelSymbol';
import BasicStateMachine from '../states/BasicStateMachine';
import GridSystem from '../systems/GridSystem';
import IdleSystem from '../systems/IdleSystem';
import InitSystem from '../systems/InitSystem';
import InteractiveGridSystem from '../systems/InteractiveGridSystem';
import LayeringSystem from '../systems/LayeringSystem';
import GridUtils from '../utils/GridUtils';
import BaseMachine from './BaseMachine';
import SingleSlotReelsSpinSystem from '../systems/SingleSlotReelsSpinSystem';

/**
 * @class HoldAndWinMachine
 * @extends BaseMachine
 * @description Minimal Hold & Win machine scaffold extending BaseMachine.
 */
export default class HoldAndWinMachine extends BaseMachine {
    public stateMachine: BasicStateMachine;

    constructor(config: any) {
        super(config);
        this.initialize();
        this.stateMachine.init();
    }

    protected override createInputs(): void {
        this.inputs = {
            initMap: null,
            spin: false,
            screenMap: null,
            turbo: false,
            fastStop: false,
            turboForced: false,
        };
    }

    protected override createFlags(): void {
        this.flags = {
            init: false,
            isSpinning: false,
        };
    }

    protected override createSharedData(): void {
        this.sharedSystemData = {
            spinSystemState: 'stopped',
            currentStoppingReel: 0,
        };
    }

    protected override createMaps(): void {
        this.maps = {
            symbols: [],
            stickySymbols: [],
            preventReelStop: [],
            preventReelsSpin: [],
            slotMultipliers: [],
        };
    }

    protected override createUtils(): void {
        this.utils = {
            grid: new GridUtils(this.config),
        };
    }

    protected override createSystems(): void {
        this.systems = {
            init: new InitSystem(this),
            idle: new IdleSystem(this),
            grid: new GridSystem(this),
            spin: new SingleSlotReelsSpinSystem(this),
            layering: new LayeringSystem(this),
            interactive: new InteractiveGridSystem(this),
        };
    }

    protected createStateMachine(): void {
        this.stateMachine = new BasicStateMachine(this);
    }

    override update(dt: number): void {
        this.stateMachine.handleInput(this);
        this.stateMachine.update(dt);
        super.update(dt);
    }

    createSymbol(key: string): ValuableReelSymbol {
        return new ValuableReelSymbol(this.config.symbols[key]);
    }
}
