import BaseMachine from '../slotMachines/BaseMachine';
import BaseSystem from '../systems/BaseSystem';

/**
 * @class WinningLinesIncrementSystem
 * @description
 * System responsible for managing the index of the currently processed winning line.
 *
 * This system:
 * - Stores the `currentWinIndex` in `sharedSystemData` to track the current win.
 * - Increments the index when exiting (`onLeave()`).
 * - Resets `currentWinIndex` to `0` when the last win is processed.
 *
 * The system does **not** trigger any animations or visual effects; it only updates the win index.
 * @extends BaseSystem
 * @property {string} state - Current system state (always "stopped").
 * @property {number} sharedSystemData.currentWinIndex - Tracks the index of the active win line.
 */
export default class WinningLinesIncrementSystem extends BaseSystem
{
    /** System state, always "stopped". */
    public state = 'stopped';

    /** Shared system data: keeps track of the current win index. */
    static override sharedSystemData: string[] = ['currentWinIndex'];

    /** Required input: `wins`, which contains the list of winning lines. */
    static override requiredInputs: string[] = ['wins'];

    /**
     * Creates an instance of WinningLinesIncrementSystem.
     * Initializes `currentWinIndex` to `0`.
     * @param {BaseMachine} machine - Reference to the slot machine instance.
     */
    constructor(machine: BaseMachine)
    {
        super(machine);
        this.machine.sharedSystemData.currentWinIndex = 0;
    }

    /** Called when the system becomes active. Logs the current win index for debugging. */
    override onEnter()
    {
        // Do nothing
    }

    /**
     * Called when the system exits.
     * - Increments the `currentWinIndex`.
     * - Resets to `0` if the last win has been processed.
     */
    override onLeave()
    {
        this.increaseWinIndex();
        if (this.isLastIndex())
        {
            this.resetWinIndex();
        }
    }

    /**
     * Increases `currentWinIndex` by `1`.
     * @private
     */
    private increaseWinIndex()
    {
        this.machine.sharedSystemData.currentWinIndex++;
    }

    /**
     * Resets `currentWinIndex` to `0` when the last win has been processed.
     * @private
     */
    private resetWinIndex()
    {
        this.machine.sharedSystemData.currentWinIndex = 0;
    }

    /**
     * Checks if the current win index is the last one in the `wins` list.
     * @returns {boolean} - `true` if the last index is reached, otherwise `false`.
     * @private
     */
    private isLastIndex()
    {
        return this.machine.sharedSystemData.currentWinIndex >= this.machine.inputs.wins.wins.length;
    }

    /**
     * This system does not update per frame.
     * @param {number} _dt - Delta time since the last update (not used).
     */
    update(_dt: number)
    {
        // Do nothing
    }
}
