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

export interface SceneController {
    /** 启动场景（带淡入淡出过渡） */
    launch(sceneKey: string): 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>;
    /** 初始启动的场景 key */
    initialScene?: string;
    children?: any;
}

/** 存储待注册的场景配置 */
interface SceneRegistration<TData extends Record<string, unknown> = {}> {
    sceneKey: string;
    scene: ReactiveScene<TData>;
    initData?: TData;
}

export function PhaserGame(props: PhaserGameProps) {
    const gameSignal = useSignal<PhaserGameContext>({ game: undefined!, sceneController: undefined! });
    const scenesRef = useRef<Map<string, SceneRegistration>>(new Map());
    const initialSceneLaunched = useRef(false);

    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) {
                if (isTransitioning.value) {
                    console.warn('SceneController: 正在进行场景切换');
                    return;
                }

                // 验证场景是否已注册
                if (!phaserGame.scene.getScene(sceneKey) && !scenesRef.current.has(sceneKey)) {
                    console.error(`SceneController: 场景 "${sceneKey}" 未注册`);
                    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);
                }

                // 确保场景已注册后再启动
                if (!phaserGame.scene.getScene(sceneKey)) {
                    const registration = scenesRef.current.get(sceneKey);
                    if (registration) {
                        phaserGame.scene.add(
                            sceneKey,
                            registration.scene,
                            false,
                            {
                                ...registration.initData,
                                phaserGame: gameSignal,
                                sceneController,
                            }
                        );
                    }
                }

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

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

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

        return () => {
            gameSignal.value = { game: undefined!, sceneController: undefined! };
            scenesRef.current.clear();
            initialSceneLaunched.current = false;
            phaserGame.destroy(true);
        };
    });

    // 启动初始场景（仅一次）
    useEffect(() => {
        const ctx = gameSignal.value;
        if (!initialSceneLaunched.current && props.initialScene && ctx?.sceneController) {
            initialSceneLaunched.current = true;
            // 使用 microtask 确保所有子组件的场景注册已完成
            Promise.resolve().then(() => {
                ctx.sceneController.launch(props.initialScene!);
            });
        }
    }, [gameSignal.value, props.initialScene]);

    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>>();
    const registered = useRef(false);

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

        const game = ctx.game;

        // 注册场景到 Phaser（但不启动）
        if (!game.scene.getScene(props.sceneKey)) {
            const initData = {
                ...props.data,
                phaserGame: phaserGameSignal,
                sceneController: ctx.sceneController,
            };
            game.scene.add(props.sceneKey, props.scene, false, initData);
        }

        sceneSignal.value = props.scene;
        registered.current = true;

        return () => {
            sceneSignal.value = undefined;
            registered.current = false;
            // 不在这里移除场景，让 SceneController 管理生命周期
        };
    });

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