import { IRefPhaserGame, PhaserGame } from './game/PhaserGame';
import "./styles.css";
import styles from './App.module.css';
import { useCallback, useEffect, useRef, useState } from 'react';
import { EventBus } from './game/EventBus';
import { raftDisconnectedSubscriptionHelper } from './utils/raft-subscription-helpers';
import RAFT from '@robotical/webapp-types/dist-types/src/application/RAFTs/RAFT';
import { RaftTypeE } from '@robotical/webapp-types/dist-types/src/types/raft';
import WonOverlay from './WonOverlay';
import { PosterItem } from './types';

import { ReactComponent as OnTiltLeft } from "./assets/blocks/ontiltleft.svg";
import { ReactComponent as OnTiltRight } from "./assets/blocks/ontiltright.svg";

import { ReactComponent as ForwardIcon } from "./assets/blocks/forward.svg";
import { ReactComponent as BackwardIcon } from "./assets/blocks/backward.svg";

import { ReactComponent as ShootIcon } from "./assets/blocks/shoot.svg";

import { ReactComponent as NowhereIcon } from "./assets/blocks/nowhere.svg";

import { ReactComponent as OnTouchCogIcon } from "./assets/blocks/ontouchcog.svg";

import BlockSelector2 from "./block-selector";
import { selectedBlockFromTutorialForLeft, selectedBlockFromTutorialForRight } from './utils/selected-blocks-from-tutorial';
import ShouldIStayOrShouldIGo from './ShouldIStayOrShouldIGo';
import { GameScene } from './game/scenes/GameScene';
import OverlayingTutorial from './overlaying-tutorial';

const staticBlockItemUp: PosterItem = { icon: OnTiltLeft, block: "ontiltleft", execute: async () => true };

const staticBlockItemDown: PosterItem = { icon: OnTiltRight, block: "ontiltright", execute: async () => true };

const staticBlockItemButton: PosterItem = { icon: OnTouchCogIcon, block: "ontouchcog", execute: async () => true };


const repeat = (n: number, array: PosterItem[]) => {
    /* Repeats every element in the array until the array length = n */
    return Array(n).fill(array).flat().slice(0, n);
}

const posterItemsForRight: PosterItem[] = repeat(12, [
    { icon: ForwardIcon, block: "moveright", execute: async () => true },
    { icon: BackwardIcon, block: "moveleft", execute: async () => true },
]);

const posterItemsForLeft: PosterItem[] = repeat(12, [
    { icon: ForwardIcon, block: "moveright", execute: async () => true },
    { icon: BackwardIcon, block: "moveleft", execute: async () => true },
]);

const posterItemsForShoot: PosterItem[] = repeat(12, [
    { icon: ShootIcon, block: "fire", execute: async () => true },
    { icon: NowhereIcon, block: "nowhere", execute: async () => true },
]);

// const staticBlockItemsUp: PosterItem[] = repeat(12, [
//     { icon: OnTiltLeft, block: "ontiltleft", execute: async () => true },
// ]);

// const staticBlockItemsDown: PosterItem[] = repeat(12, [
//     { icon: OnTiltRight, block: "ontiltright", execute: async () => true },
// ]);

function Skiing() {
    // const [gameContainerDimensions, setGameContainerDimensions] = useState({ width: "70vw", height: "80vh" });
    const [gameContainerDimensions, setGameContainerDimensions] = useState({ width: "720px", height: "640px" });
    const [collectedFlags, setCollectedFlags] = useState(0);
    const [collectedFlagsText, setCollectedFlagsText] = useState("");
    const [isZooming, setIsZooming] = useState(false);
    const [isZoomingCenteredScore, setIsZoomingCenteredScore] = useState(false);
    const phaserGameRef = useRef<IRefPhaserGame>(null);
    const [connectedCog, setConnectedCog] = useState<RAFT | null>(null);
    const [isWinningFlagVisible, setIsWinningFlagVisible] = useState(false);
    const [isSceneReady, setIsSceneReady] = useState(false);
    const [posterItemsLeftState, setPosterItemsLeftState] = useState<PosterItem[]>([...posterItemsForLeft]);
    const [posterItemsRightState, setPosterItemsRightState] = useState<PosterItem[]>([...posterItemsForRight]);
    const [posterItemsShootState, setPosterItemsShootState] = useState<PosterItem[]>([...posterItemsForShoot]);
    const [tutorialPhase, setTutorialPhase] = useState<undefined | number>(1);
    const [shouldIStayOrShouldIGoVisible, setShouldIStayOrShouldIGoVisible] = useState(false);
    const [selectedTiltBlocks, setSelectedTiltBlocks] = useState<{ left: PosterItem | null, right: PosterItem | null, shoot: PosterItem | null }>({
        left: null,
        right: null,
        shoot: null,
    });
    const [showBlockReminder, setShowBlockReminder] = useState(false);
    const [blockReminderDismissed, setBlockReminderDismissed] = useState(false);
    const reminderTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

    const subHelper = useRef<ReturnType<typeof raftDisconnectedSubscriptionHelper> | null>(null);
    const isTiltMappingCorrect = selectedTiltBlocks.left?.block === "moveleft" && selectedTiltBlocks.right?.block === "moveright";

    const handleBlockSelectionChange = useCallback((staticBlock: "left" | "right" | "shoot", item: PosterItem) => {
        setSelectedTiltBlocks((prev) => ({
            ...prev,
            [staticBlock]: item,
        }));
        // Reset dismissal when user makes a new choice so we can remind again if needed.
        setBlockReminderDismissed(false);
    }, []);

    useEffect(() => {
        /* Checks if we are already connected to a cog */
        const selectedCog = window.applicationManager?.getTheCurrentlySelectedDeviceOrFirstOfItsKind(RaftTypeE.COG);
        if (selectedCog) {
            setConnectedCog(selectedCog);
            subHelper.current = raftDisconnectedSubscriptionHelper(selectedCog);
            subHelper.current.subscribe(() => {
                setConnectedCog(null);
                subHelper.current?.unsubscribe();
            });
        }

        return () => {
            subHelper.current?.unsubscribe();
        }
    }, []);

    const handleConnect = () => {
        window.applicationManager?.connectGenericCog((raft) => {
            setConnectedCog(raft);
            subHelper.current = raftDisconnectedSubscriptionHelper(raft);
            subHelper.current.subscribe(() => {
                setConnectedCog(null);
                subHelper.current?.unsubscribe();
            });
        });
    };

    const handleDisconnect = () => {
        if (connectedCog) {
            window.applicationManager?.disconnectGeneric(connectedCog);
        }
    };

    useEffect(() => {
        EventBus.on('scene-ready', (space: GameScene) => {
            const spaceHeightScaled = space.scale.height;
            const spaceWidthScaled = space.scale.width;
            setGameContainerDimensions({
                width: spaceWidthScaled + "px",
                height: spaceHeightScaled + "px"
            });
            setIsSceneReady(true);
        });


        // EventBus.on('flags-lost', (scene_instance: GameScene) => {
        //     setCollectedFlags(scene_instance.collectedFlags);
        //     setCollectedFlagsText(`-1=${scene_instance.collectedFlags}`);
        // });

        EventBus.on('target-achieved', () => {
            if (!phaserGameRef.current) return;
            if (!phaserGameRef.current.scene) return;
            setIsWinningFlagVisible(true);
            setTimeout(() => {
                setIsWinningFlagVisible(false);
                setShouldIStayOrShouldIGoVisible(true);
                // window.applicationManager.carouselNavigatorManager.getNavigator("games")?.setIsVisible(true);
                // window.applicationManager.carouselNavigatorManager.getNavigator("games")?.setHighlightedItem("/maze");
            }, 2000);
        });

        EventBus.on('die', () => {
            setCollectedFlags(0);
            setTutorialPhase(3);
            setPosterItemsLeftState([]);
            setPosterItemsRightState([]);
        });

        return () => {
            EventBus.removeListener('scene-ready');
            EventBus.removeListener('die');
            EventBus.removeListener('flags-lost');
            EventBus.removeListener('target-achieved');
        }
    }, []);

    useEffect(() => {
        if (reminderTimeoutRef.current) {
            clearTimeout(reminderTimeoutRef.current);
            reminderTimeoutRef.current = null;
        }

        if (!isSceneReady) {
            setShowBlockReminder(false);
            return;
        }

        if (tutorialPhase !== undefined) {
            setShowBlockReminder(false);
            return;
        }

        if (isTiltMappingCorrect) {
            setShowBlockReminder(false);
            setBlockReminderDismissed(false);
            return;
        }

        if (blockReminderDismissed) {
            setShowBlockReminder(false);
            return;
        }

        reminderTimeoutRef.current = setTimeout(() => {
            setShowBlockReminder(true);
        }, 10000);

        return () => {
            if (reminderTimeoutRef.current) {
                clearTimeout(reminderTimeoutRef.current);
                reminderTimeoutRef.current = null;
            }
        };
    }, [isSceneReady, tutorialPhase, isTiltMappingCorrect, blockReminderDismissed]);

    useEffect(() => {
        if (collectedFlags > 0) {
            setIsZooming(true);
            setTimeout(() => {
                setIsZooming(false);
            }, 300);
        }
    }, [collectedFlags]);

    useEffect(() => {
        if (collectedFlags > 0) {
            setIsZoomingCenteredScore(true);
            setTimeout(() => {
                setIsZoomingCenteredScore(false);
            }, 1500);
        }
    }, [collectedFlags]);

    const onPlayBtnClick = () => {
        // if cog is connected, start the game, otherwise connect a cog
        if (connectedCog) {
            // phaserGameRef.current?.scene?.handleGameStart();
        } else {
            handleConnect();
        }
    };

    const onTutorialFinished = () => {
        // when the tutorial is finished, we get the selected blocks from the programming phase
        // and we push them to the poster items

        // const selectedBlockLeft = selectedBlockFromTutorialForLeft;
        // const selectedBlockRight = selectedBlockFromTutorialForRight;
        // if (selectedBlockLeft) {
        //     setPosterItemsLeftState([selectedBlockLeft]);
        // }
        // if (selectedBlockRight) {
        //     setPosterItemsRightState([selectedBlockRight]);
        // }

        const selectedBlockLeft = selectedBlockFromTutorialForLeft;
        const selectedBlockRight = selectedBlockFromTutorialForRight;
        if (selectedBlockLeft) {
            const index = posterItemsForLeft.findIndex(item => item.block === selectedBlockLeft.block);
            if (index !== -1) {
                const selectedBlock = posterItemsForLeft[index];
                posterItemsForLeft.splice(index, 1);
                posterItemsForLeft.unshift(selectedBlock);
                setPosterItemsLeftState([...posterItemsForLeft]);
            }
        }
        if (selectedBlockRight) {
            const index = posterItemsForRight.findIndex(item => item.block === selectedBlockRight.block);
            if (index !== -1) {
                const selectedBlock = posterItemsForRight[index];
                posterItemsForRight.splice(index, 1);
                posterItemsForRight.unshift(selectedBlock);
                setPosterItemsRightState([...posterItemsForRight]);
            }
        }
        setTutorialPhase(undefined);
    };

    const onKeepPlaying = () => {
        setShouldIStayOrShouldIGoVisible(false);
        // setCollectedFlags(0);
        // setCollectedFlagsText("");
        // setTutorialPhase(3);
        // setPosterItemsLeftState([]);
        // setPosterItemsRightState([]);
    };

    const onGoNext = () => {
        window.applicationManager.carouselNavigatorManager.getNavigator("games")?.navigate("/maze");
    };

    return (
        <div className={styles.App}>
            {isWinningFlagVisible && <WonOverlay />}
            {shouldIStayOrShouldIGoVisible && <ShouldIStayOrShouldIGo keepPlaying={onKeepPlaying} goNext={onGoNext} />}
            <OverlayingTutorial tutorialPhase={tutorialPhase} setTutorialPhase={setTutorialPhase} onTutorialFinished={onTutorialFinished} />
            {/* <div className={styles.highScoreBoard}>
                <h1>HIGH SCORE</h1>
                <div className={styles.highScore}>{zeroPrepender(highScore, 4)}</div>
            </div> */}
            <div className={styles.gameContainer} style={gameContainerDimensions}>
                {showBlockReminder && isSceneReady && (
                    <div className={styles.blockReminder}>
                        <span className={styles.blockReminderText}><span style={{display:"block", textDecoration: "underline", width: "100%", textAlign: 'center'}}>Tip: fix steering</span><br />Tilt Left &nbsp;&nbsp;&nbsp;→&nbsp;&nbsp;  Move Left<br />Tilt Right &nbsp;→&nbsp;&nbsp; Move Right.</span>

                    </div>
                )}
                <div className={styles.blockSelectorContainer}>
                    <div className={styles.blockSelectorList}>
                        {isSceneReady && (
                            <>
                                {/* {!!posterItemsRightState.length && <BlockSelector2 gameRef={phaserGameRef} staticBlock="right" posterItems={posterItemsRightState} staticBlockItem={staticBlockItemDown} snapPointFactors={[.48,]} />} */}
                                {/* {!!posterItemsLeftState.length && <BlockSelector2 gameRef={phaserGameRef} staticBlock="left" posterItems={posterItemsLeftState} staticBlockItem={staticBlockItemUp} snapPointFactors={[.48,]} />} */}
                                {!!posterItemsRightState.length && <BlockSelector2 gameRef={phaserGameRef} staticBlock="right" posterItems={posterItemsRightState} staticBlockItems={[staticBlockItemDown]} onSelectionChange={handleBlockSelectionChange} />}
                                {!!posterItemsShootState.length && <BlockSelector2 gameRef={phaserGameRef} staticBlock="shoot" posterItems={posterItemsShootState} staticBlockItems={[staticBlockItemButton]} onSelectionChange={handleBlockSelectionChange} />}
                                {!!posterItemsLeftState.length && <BlockSelector2 gameRef={phaserGameRef} staticBlock="left" staticBlockItems={[staticBlockItemUp]} posterItems={posterItemsLeftState} onSelectionChange={handleBlockSelectionChange} />}
                            </>
                        )}
                    </div>
                </div>
                {/* <div className={styles.scoreBoard}>
                    <StarIcon className={styles.starIcon} />
                    <div className={`${styles.score} ${isZooming ? styles.zoom : ''}`}>{collectedFlags}</div>
                </div>
                <div className={`${styles.centeredScore} ${isZoomingCenteredScore ? styles.flashScore : ''}`}>
                    {collectedFlagsText}
                </div>
                <div className={styles.flagsTargetContainer}>
                    <FlagsTarget className={styles.flagsTargetIcon} />
                </div> */}
                <PhaserGame ref={phaserGameRef} />
            </div>
            {/* <div className={styles.playBtnContainer}>
                {
                    (!phaserGameRef.current?.scene?.isGameRunning && !phaserGameRef.current?.scene?.isGameOverVisible) ? <PlayIcon
                        className={styles.playBtn}
                        onClick={onPlayBtnClick}
                    />
                        : <div />
                }
            </div> */}
        </div>
    )
}

export default Skiing;
