import { Entity } from '../types/Entity';
import BaseSystem from './BaseSystem';


export default class AnticipationTintingSystem extends BaseSystem
{
    static override requiredFlags: string[] = [];
    static override requiredMaps: string[] = ['anticipatingReels', 'tinting', 'symbols'];
    static override requiredInputs: string[] = [];
    static override requiredMethods: string[] = [];
    static override requiredUtils: string[] = [];
    static override sharedSystemData: string[] = ['spinSystemState', 'currentStoppingReel', 'anticipatingSymbolsTests'];

    public state: 'active' | 'anticipating' | 'stopped' = 'stopped';

    override onEnter()
    {
        this.state = 'active';
    }

    override onLeave() {}

    update(_dt: number): void
    {
        if (this.state === 'active')
        {
            if (this.isAnticipatingReel())
            {
                this.state = 'anticipating';
            }
        }
        if (this.state === 'anticipating')
        {
            this.tintSymbols();
        }
        if (this.isStopConditionMet())
        {
            this.state = 'stopped';
            this.machine.maps.tinting.fill(false);
        }
        if (this.machine.sharedSystemData.spinSystemState === 'stopped')
        {
            this.state = 'stopped';
            this.machine.maps.tinting.fill(false);
        }
    }

    private isStopConditionMet()
    {
        return this.state === 'anticipating'
      && this.machine.sharedSystemData.currentStoppingReel === this.machine.config.reels
      && !this.machine.maps.anticipatingReels[this.machine.config.reels - 1];
    }

    private tintSymbols()
    {
        this.machine.maps.symbols.forEach((id: string, i: number) =>
        {
            if (!id) return;
            const entity: Entity = this.machine.getChildByName(id);

            if (!entity) return;
            this.machine.maps.tinting[i] = !this.machine.sharedSystemData.anticipatingSymbolsTests.some((t: RegExp) => t.test(entity.key));
        });
    }

    private isAnticipatingReel()
    {
        return this.machine.maps.anticipatingReels.some((v: boolean) => v);
    }
}
