import { Assets, Ticker } from 'pixi.js';
import CascadeMachine from 'src/slotMachines/CascadeMachine';
import ReelsMachine from 'src/slotMachines/ReelsMachine';
import StaticReelsMachine from 'src/slotMachines/StaticReelsMachine';
import { STATES } from 'src/states/BasicStateMachine';
import { argTypes, getDefaultArgs } from 'src/stories/utils/argTypes';
import { createScreenInputMap } from 'src/stories/utils/createScreenInputMap';
import MachineContainer from 'src/stories/utils/MachineContainer';
import { centerView } from 'src/stories/utils/resize';
import StickySymbolsSystem from 'src/systems/StickySymbolsSystem';
import { SlotMachineConfig } from 'src/types/SlotMachineConfig';
import { Meta, PixiStory, StoryFn } from '@pixi/storybook-renderer';
import MockSystem from "src/systems/MockSystem";

const args = {
    zIndex: 5,
};

const meta: Meta<typeof StickySymbolsSystem> = {
    title: 'Systems/StickySpinSystem',
    tags: ['autodocs'],
    parameters: {
        docs: {
            story: {
                height: 600
            },
            description: {
                component: 'Controls the spinning behavior of slot machine reels, including acceleration, sustained spinning, and deceleration. This class manages reel state transitions, timing for each stage of the spin, and the display of symbols on each reel.'
            },
        }
    },
    argTypes: argTypes(args),
    args: getDefaultArgs(args),
};

export default meta;

export const ReelsMachineStory: StoryFn<typeof args> = (_params, context) => new PixiStory({
    context, init: async (view) =>
    {
        Assets.reset();
        await Assets.init({
            manifest: 'area69/manifest.json',
        });
        await Assets.loadBundle('configs');
        await Assets.loadBundle('symbols');
        const config: SlotMachineConfig = Assets.get('slot_machine_config');
        const machine = new ReelsMachine(config);
        const container = new MachineContainer(machine);

        view.addChild(container);
        context.machine = machine;
        machine.systems.stick = new StickySymbolsSystem(machine);
        machine.stateMachine.states[STATES.SPINNING].systems = ['spin', 'layering'];
        machine.stateMachine.states.forEach((state) => state.systems.push('stick'));
        machine.inputs.initMap = createScreenInputMap(config);
        machine.inputs.screenMap = machine.inputs.initMap;
        machine.maps.stickySymbols = machine.inputs.screenMap.map((s: any) => ['L', 'M', 'N'].includes(s.key));
        machine.systems.stick.setSettings(_params);
        machine.inputs.spin = true;
        machine.inputs.blockExitState = true;
        setTimeout(() => {
            machine.inputs.blockExitState = false;
        }, 250);
        centerView(view);
        centerView(view);
        centerView(view);
    },
    resize: centerView,
    update: () =>
    {
        context.machine && context.machine.update(Ticker.shared.deltaMS);
    }
});

export const CascadeMachineStory: StoryFn<typeof args> = (_params, context) => new PixiStory({
    context, init: async (view) =>
    {
        Assets.reset();
        await Assets.init({
            manifest: 'bubblex/manifest.json',
        });
        await Assets.loadBundle('configs');
        await Assets.loadBundle('symbols');
        const config: SlotMachineConfig = Assets.get('slot_machine_config');
        const machine = new CascadeMachine(config);
        const container = new MachineContainer(machine);

        view.addChild(container);
        context.machine = machine;
        machine.systems.stick = new StickySymbolsSystem(machine);
        machine.stateMachine.states[STATES.SPINNING].systems = ['stick', 'spin'];
        machine.inputs.initMap = createScreenInputMap(config);
        machine.inputs.screenMap = machine.inputs.initMap;
        machine.maps.stickySymbols = machine.inputs.screenMap.map((s: any) => ["RR"].includes(s.key));
        machine.systems.stick.setSettings(_params);
        machine.inputs.spin = true;
        centerView(view);
    },
    resize: centerView,
    update: () =>
    {
        context.machine && context.machine.update(Ticker.shared.deltaMS);
    }
});

export const StaticReelsMachineStory: StoryFn<typeof args> = (_params, context) => new PixiStory({
    context, init: async (view) =>
    {
        Assets.reset();
        await Assets.init({
            manifest: 'bubblex/manifest.json',
        });
        await Assets.loadBundle('configs');
        await Assets.loadBundle('symbols');
        const config: SlotMachineConfig = Assets.get('slot_machine_config');
        const machine = new StaticReelsMachine(config);
        const container = new MachineContainer(machine);

        view.addChild(container);
        context.machine = machine;
        machine.systems.blockExitState = new MockSystem(machine)
        machine.systems.stick = new StickySymbolsSystem(machine);
        machine.stateMachine.states[STATES.SPINNING].systems = ['stick', 'spin'];
        machine.inputs.initMap = createScreenInputMap(config);
        machine.inputs.screenMap = machine.inputs.initMap;
        machine.maps.stickySymbols = machine.inputs.screenMap.map((s: any) => ["RR"].includes(s.key));
        machine.systems.stick.setSettings(_params);
        machine.inputs.spin = true;
        centerView(view);
    },
    resize: centerView,
    update: () =>
    {
        context.machine && context.machine.update(Ticker.shared.deltaMS);
    }
});
