import Phaser from 'phaser';
import { computed, signal, useSignal, useSignalEffect } from '@preact/signals';
import { createContext, h } from 'preact';
import { useContext } from 'preact/hooks';
import {ReadonlySignal} from "@preact/signals-core";
import type { ReactiveScene, ReactiveScenePhaserData } from '../scenes';
import { FadeScene as FadeSceneClass, FADE_SCENE_KEY } from '../scenes/FadeScene';

export interface SceneController {
    /** 启动场景（带淡入淡出过渡） */
    launch(sceneKey: string, data?: Record<string, unknown>): Promise<void>;
    /** 当前活跃场景 key */
    currentScene: ReadonlySignal<string | null>;
    /** 是否正在过渡 */
    isTransitioning: ReadonlySignal<boolean>;
}

export interface PhaserGameContext {
    game: Phaser.Game;
    sceneController: SceneController;
}

export const phaserContext = createContext<ReadonlySignal<PhaserGameContext> | null>(null);

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<PhaserGameContext>({ game: undefined!, sceneController: undefined! });
    const registeredScenes = useSignal<Map<string, ReactiveScene>>(new Map());

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

        // 添加 FadeScene
        const fadeScene = new FadeSceneClass();
        phaserGame.scene.add(FADE_SCENE_KEY, fadeScene, false);

        // 创建 SceneController
        const currentScene = signal<string | null>(null);
        const isTransitioning = signal(false);

        const sceneController: SceneController = {
            async launch(sceneKey: string, data?: Record<string, unknown>) {
                if (isTransitioning.value) {
                    console.warn('SceneController: 正在进行场景切换');
                    return;
                }

                isTransitioning.value = true;
                const fade = phaserGame.scene.getScene(FADE_SCENE_KEY) as FadeSceneClass;

                // 淡出到黑色
                await fade.fadeOut(300);

                // 停止当前场景
                if (currentScene.value) {
                    phaserGame.scene.stop(currentScene.value);
                }

                // 启动新场景
                phaserGame.scene.start(sceneKey, data);
                currentScene.value = sceneKey;

                // 淡入
                await fade.fadeIn(300);
                isTransitioning.value = false;
            },
            currentScene,
            isTransitioning,
        };

        gameSignal.value = { game: phaserGame, sceneController };

        return () => {
            gameSignal.value = { game: undefined!, sceneController: undefined! };
            registeredScenes.value.clear();
            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<TData extends Record<string, unknown> = {}> {
    sceneKey: string;
    scene: ReactiveScene<TData>;
    data?: TData;
    children?: any;
}

export const phaserSceneContext = createContext<ReadonlySignal<ReactiveScene> | null>(null);
export function PhaserScene<TData extends Record<string, unknown> = {}>(props: PhaserSceneProps<TData>) {
    const phaserGameSignal = useContext(phaserContext);
    const sceneSignal = useSignal<ReactiveScene<TData>>();

    useSignalEffect(() => {
        if (!phaserGameSignal) return;
        const ctx = phaserGameSignal.value;
        if (!ctx?.game) return;

        const game = ctx.game;
        const initData = {
            ...props.data,
            phaserGame: phaserGameSignal,
            sceneController: ctx.sceneController,
        };

        // 注册场景但不启动
        if (!game.scene.getScene(props.sceneKey)) {
            game.scene.add(props.sceneKey, props.scene, false, initData);
        }
        sceneSignal.value = props.scene;
        
        return () => {
            sceneSignal.value = undefined;
            // 不在这里移除场景，让 SceneController 管理生命周期
        };
    });

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