import Phaser from 'phaser';
import { signal, useSignal, useSignalEffect, type Signal } from '@preact/signals';
import { createContext, h } from 'preact';
import { useContext } from 'preact/hooks';
import {ReadonlySignal} from "@preact/signals-core";

export const phaserContext = createContext<ReadonlySignal<Phaser.Game | undefined>>(signal(undefined));

export const defaultPhaserConfig: Phaser.Types.Core.GameConfig = {
    type: Phaser.AUTO,
    width: 560,
    height: 560,
    parent: 'phaser-container',
    backgroundColor: '#f9fafb',
    scene: [],
};

export interface PhaserGameProps {
    config?: Partial<Phaser.Types.Core.GameConfig>;
    children?: any;
}

export function PhaserGame(props: PhaserGameProps) {
    const gameSignal = useSignal<Phaser.Game>();

    useSignalEffect(() => {
        const config: Phaser.Types.Core.GameConfig = {
            ...defaultPhaserConfig,
            ...props.config,
        };
        const phaserGame = new Phaser.Game(config);
        gameSignal.value = phaserGame;

        return () => {
            gameSignal.value = undefined;
            phaserGame.destroy(true);
        };
    });

    return (
        <div id="phaser-container" className="w-full h-full">
            <phaserContext.Provider value={gameSignal}>
                {props.children}
            </phaserContext.Provider>
        </div>
    );
}

export interface PhaserSceneProps {
    sceneKey: string;
    scene: Phaser.Scene;
    autoStart: boolean;
    data?: object;
    children?: any;
}

export const phaserSceneContext = createContext<ReadonlySignal<Phaser.Scene | undefined>>(signal(undefined));
export function PhaserScene(props: PhaserSceneProps) {
    const context = useContext(phaserContext);
    const sceneSignal = useSignal<Phaser.Scene>();

    useSignalEffect(() => {
        const game = context.value;
        if (!game) return;

        game.scene.add(props.sceneKey, props.scene, props.autoStart, props.data);
        sceneSignal.value = game.scene.getScene(props.sceneKey);
        return () => {
            sceneSignal.value = undefined;
            game.scene.remove(props.sceneKey);
        };
    });

    return <phaserSceneContext.Provider value={sceneSignal}>{props.children}</phaserSceneContext.Provider>;
}
