import * as React from "react";
import { useState, useRef, useEffect } from 'react';
import Modal from 'react-responsive-modal';
import 'react-responsive-modal/styles.css';
import LevelScene from "./LevelScene";
import Editor from "./Editor";
import { levels, LevelInitializer } from "../game/levels";
// import { Redirect } from "react-router-dom"
import { Route, Link, useParams } from "react-router-dom";
import { connect } from "react-redux";
import { AppState } from "../store";
import { bindActionCreators } from "redux";
import TalkyFace from './talkyFace'
import { openModal, closeModal } from "../store/gameScreenState/slice";
import game from "../game/game"
import { setLevel, nextLevel } from "../store/level/slice";
import { RESET_EXECUTION } from "../store/executionState/types";
import { LayoutGrid, ArrowRight } from "lucide-react";

const MODAL_STYLES = {
    'overlay': { background: '#11111166', zIndex: 99999 },
    'modal': {
        background: '#555',
        width: '40rem',
        height: '25rem',
        borderRadius: '1rem',
        zIndex: 99999
    },
    'closeButton': {},
    'closeIcon': {}
}

const SpeechBubble = ({ message }) => {
    return (
        <div style={{ display: "flex", flexDirection: "row" }}>
            <svg height="180px" width="50">
                <polygon points="0,100 50,100 50,150"
                    style={{ fill: "#ffe" }} />
            </svg>
            <div style={{
                height: "110px",
                minWidth: "200px",
                maxWidth: "300px",
                padding: "1.5rem",
                display: "flex",
                flexDirection: "column",
                justifyContent: "space-around",
                background: "#ffe",
                // textAlign: "center",
                fontSize: "2em",
                borderRadius: "0.3rem",
                fontFamily: 'iosevka'
            }}>
                <p>
                    {message}
                </p>
            </div>
        </div>)
}

const IntroMessage = ({ name, message }) => {
    return (
        <div>
            <div style={{ height: "22rem", display: "flex", flexDirection: "column", justifyContent: "space-around" }}>

                <div style={{ display: "flex", flexDirection: "row", justifyContent: "center" }}>
                    <TalkyFace />
                    <SpeechBubble message={message.message} />
                </div>
            </div>
        </div>
    )
}

const WonMessage = ({ nextRoute }) => {
    return (
        <div>
            <div style={{ height: "22rem", display: "flex", flexDirection: "column", justifyContent: "space-around" }}>
                <div style={{ display: "flex", flexDirection: "row", justifyContent: "center" }}>
                    <TalkyFace />
                    <SpeechBubble message={"Good Job!"} />
                </div>
            </div>
            <div style={{ display: "flex", justifyContent: "center", gap: "1rem", marginTop: "1rem" }}>
                <Link to={'/levels/'} className="modal-button levels">
                    <LayoutGrid size={18} />
                    <span>levels</span>
                </Link>
                <Link to={nextRoute} className="modal-button next">
                    <span>next</span>
                    <ArrowRight size={18} />
                </Link>
            </div>
        </div>
    )
}

const GameScreen = ({ nextLevel, won, open, openModal, closeModal, setLevel, resetState }) => {
    const modalContainerRef = useRef<HTMLDivElement>(null);
    // first set level to levelname in url params
    const { name } = useParams();
    let levelIdx = levels.findIndex((l) => name == l.name)
    levelIdx = levelIdx === -1 ? 0 : levelIdx; // first level when no name matches
    let level = levels[levelIdx]
    setLevel(level, levelIdx)
    // resetState() // introduces bug when called after won

    // when there is no next level route to WonScreen
    let nextRoute = levelIdx === levels.length - 1 ? '/won' : '/level/' + levels[levelIdx + 1].name;

    let [idxMsgs, setMsgIdx] = useState(level.introMessages && level.introMessages.length > 0 ? 0 : null);
    
    // Auto-open modal for intro messages when level starts or when won
    useEffect(() => {
      // Auto-open modal for intro messages when level starts
      if (level.introMessages && level.introMessages.length > 0 && idxMsgs !== null && !open && !won) {
        openModal();
      }
      
      // Auto-open modal when won
      if (won && !open) {
        openModal();
      }
    }, [idxMsgs, won, level.introMessages]); // Proper dependencies
    
    useEffect(() => {
        resetState();
        game.init(level);
        if (!level.introMessages || level.introMessages.length === 0) {
            closeModal();
        }
    }, [level]);

    return (
        <div className="game" ref={modalContainerRef}>
            <LevelScene level={level}></LevelScene>
            <Editor level={level}></Editor>
            <Modal
                open={open}
                onClose={() => closeModal()}
                styles={MODAL_STYLES}
                center
                container={modalContainerRef.current}>
                {won ? <WonMessage nextRoute={nextRoute} />
                    : (level.introMessages !== null) ? <IntroMessage name={level.name} message={level.introMessages[idxMsgs]} /> : ""
                }
            </Modal>
        </div >
    )
}


const mapStateToProps = (state: AppState, ownprops?) => {

    return {
        ...ownprops,
        won: state.executionState.won,
        open: state.gameScreenState.modalOpen
    }
}

const mapDispatchToProps = dispatch => {
    return {
        openModal: () => dispatch(openModal()),
        closeModal: () => dispatch(closeModal()),
        // nextLevel: game.nextLevel,
        setLevel: (level, idx) => dispatch(setLevel({ level, idx })),
        resetState: () => dispatch({ type: RESET_EXECUTION })
    }
}


export default connect(mapStateToProps, mapDispatchToProps)(GameScreen);
