import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent";
// @ts-ignore 
import { assign, createMachine, interpret, actions, forwardTo, matchesState } from "../script/xstate";
const { pure, send, raise, sendParent } = actions;


const { ccclass, property } = cc._decorator;

@ccclass
export default class SceneComponent extends MyCocosSceneComponent {
    @property(cc.PageView)
    submarineView: cc.PageView = null;
    @property(cc.Node)
    submarineViewBackground: cc.Node = null;
    @property(cc.Node)
    loading: cc.Node = null;
    @property(cc.Node)
    LetterView: cc.Node = null;
    @property(cc.Node)
    StoryView: cc.Node = null;
    @property(cc.Node)
    ReviewView: cc.Node = null;
    @property(cc.Node)
    SubmarineView: cc.Node = null;
    @property(cc.AudioClip)
    bgMusic1: cc.AudioClip = null;
    @property(cc.AudioClip)
    bgMusic2: cc.AudioClip = null;

    @property([cc.Node])
    BackViewButtons: cc.Node[] = [];


    @property([cc.Node])
    SpaceViewButtons: cc.Node[] = [];

    @property([cc.Node])
    SubmarineViewButtons: cc.Node[] = [];

    @property([cc.Node])
    LetterViewButtons: cc.Node[] = [];

    @property(cc.Label)
    LetterViewLabel: cc.Label = null;

    @property([cc.Node])
    ReviewViewButtons: cc.Node[] = [];

    @property([cc.Node])
    StoryViewButtons: cc.Node[] = [];

    @property([cc.Node])
    FullPageNode: cc.Node[] = [];

    @property(cc.Node)
    BackDoorNode: cc.Node = null;


    tws: any[] = [];
    gameMachineService: any = null;
    LoadingCount: number = 1;
	_mapScaleMin: number = 1;
	_mapScaleMax: number = 1;
	_cocosScale: number = 1;
    BASE_URL: string = null;
    MACHINE_INITED: boolean = false;

    onLoad(){
        this.tws = [];
        this.LoadingCount = 0;
        this.initSize();


        
    }
    initialized() {
        if(this.BASE_URL && this.gameMachineService) {
            this.gameMachineService.start();
            this.restore();
        }
    }
    initSize() {
		// 注意cc.winSize只有在适配后(修改fitHeight/fitWidth后)才能获取到正确的值,因此使用cc.getFrameSize()来获取初始的屏幕大小
		let screen_size = cc.view.getFrameSize().width / cc.view.getFrameSize().height
		let design_size = cc.Canvas.instance.designResolution.width / cc.Canvas.instance.designResolution.height
		let f = screen_size >= design_size
		cc.Canvas.instance.fitHeight = f
		cc.Canvas.instance.fitWidth = !f

		const frameSize = cc.view.getFrameSize();
		this._frameSize = frameSize;

		this._designSize = cc.view.getDesignResolutionSize();

		let sx = cc.winSize.width / frameSize.width;
		let sy = cc.winSize.height / frameSize.height;
		this._cocosScale = Math.min(sx, sy);

		sx = frameSize.width / this._designSize.width;
		sy = frameSize.height / this._designSize.height;
		this._mapScaleMin = Math.min(sx, sy) * this._cocosScale;
		this._mapScaleMax = Math.max(sx, sy) * this._cocosScale;
	}
    start() {
        
        this.showWaitingLetters();
        this.initBg();
        this.initSubmarineView();
        this.createFiniteStateMachines();
        this.BackViewButtons.forEach(b => {
            b.on(cc.Node.EventType.TOUCH_START, function () {
                this.gameMachineService.send('BACK');
                // this.node.emit('BACK');
            }, this, true);
        });

        for (let bs of [this.SpaceViewButtons, this.SubmarineViewButtons, this.LetterViewButtons, this.StoryViewButtons, this.ReviewViewButtons]) {
            bs.forEach(b => {
                // const env = this;
                b.on(cc.Node.EventType.TOUCH_START, function () {
                    // this.gameMachineService.send('BACK')
                    // env.node.emit('BACK');
                    const [buttonName, state, index] = b.name.split('@');


                    console.log(buttonName, state, index);
                    let stateName = b.parent.name;
                    if (stateName.includes('@')) {
                        let [_, sn] = stateName.split('@')
                        stateName = sn;
                    }
                    console.log(stateName);

                    const currentDataset = this.gameMachineService.machine.config.context[stateName + 'Data'];
                    if (!currentDataset || !currentDataset[index]) {
                        return;
                    }
                    const linkFlag = stateName === 'LetterView';
                    globalThis.PREV_STATE = globalThis.CURRENT_STATE ? JSON.parse(JSON.stringify(globalThis.CURRENT_STATE)) : null;
                    const param = JSON.parse(JSON.stringify(currentDataset[index]));
                    globalThis.CURRENT_STATE = {
                        state,
                        data: { ...param, buttonName, linkFlag }
                    }
                    console.log(globalThis.PREV_STATE, globalThis.CURRENT_STATE);
                    globalThis.CURRENT_PID = param.pid;
                    globalThis.CURRENT_ID = param.id;
                    this.gameMachineService.send(state, { ...param, buttonName, linkFlag });
                }, this, true);
            });
        }

        globalThis.aaa = this;
        this.BASE_URL = 'http://openapi.iteachabc.com';
        this.initialized();
        
    }
    initBg() {
        // const bgNode = cc.find('Canvas/MainScene/SpaceView/bg');
        this.FullPageNode.forEach(n => {
            n.scale = this._mapScaleMax;
        });



    }
    addPreloadImage() {
        // TODO 根据自己的配置预加载图片资源
        this._imageResList.push({ url: this.data.pic_url });
        this._imageResList.push({ url: this.data.pic_url_2 });
    }

    addPreloadAudio() {
        // TODO 根据自己的配置预加载音频资源
        this._audioResList.push({ url: this.data.audio_url });
    }

    addPreloadAnima() {

    }


    initSubmarineView() {
        this.submarineView.node.on('scrolling', this.moveSubmarineBackground, this);
        this.SubmarineView.active = false;
    }

    moveSubmarineBackground() {
        //获取滚动视图相对于左上角原点的当前滚动偏移
        let scrollOffset: cc.Vec2 = this.submarineView.getScrollOffset();
        // console.log(scrollOffset.x);
        this.submarineViewBackground.x = scrollOffset.x * 0.65;
    }
    createFiniteStateMachines() {


        const canvas = cc.find('Canvas');
        canvas.on('MIDDLE_LAYER_LOADED', ({ scene }) => {
            this.hideWaitingLetters();
        });
        const operationState = {
            id: 'operation',
            initial: 'SpaceView',
            context: {
                SpaceViewData: null,
                SubmarineViewData: null,
                LetterVewData: null,
                StoryViewData: null,
                ReviewViewData: null,
                currentDataset: null,
            },
            states: {

                SpaceView: {
                    entry: (ctx, event) => {
                        this.LetterView.active = false;
                        this.StoryView.active = false;
                        this.ReviewView.active = false;
                        this.SubmarineView.active = false;
                        cc.audioEngine.stopMusic();
                        cc.audioEngine.playMusic(this.bgMusic1, true);

                        // event.type !== 'BACK' 
                        this.callNetworkApiGet(this.BASE_URL + '/api/syllabus/v1/list?orgid=7', (resp: any) => {
                            resp = JSON.parse(resp);
                            if (resp.msg == 'success') {
                                let { rows } = resp
                                rows = rows.filter(r => !r.has_courseware);
                                console.log('SpaceView111', rows)
                                ctx.SpaceViewData = rows;
                                ctx.currentDataset = rows;
                            }
                        });


                    },
                    exit: () => {
                        console.log('exit SpaceView stage');
                        cc.audioEngine.stopMusic();
                        cc.audioEngine.playMusic(this.bgMusic2, true);
                    },
                    on: {
                        SUBMARINE: 'SubmarineView',
                        LETTER: 'LetterView',
                        STORY: 'StoryView',
                        REVIEW: 'ReviewView',
                    },

                },


                SubmarineView: {
                    entry: (ctx, event) => {
                        console.log('entry SubmarineView stage');
                        this.LetterView.active = false;
                        this.StoryView.active = false;
                        this.ReviewView.active = false;
                        this.SubmarineView.active = true;

                    },
                    exit: () => {
                        // console.log('exit SubmarineView stage');
                    },
                    invoke: {
                        src: (ctx, event) => {
                            console.log(111, event)



                            // this.submarineView.scrollToPage(0, 0)
                            this.callNetworkApiGet(this.BASE_URL + '/api/syllabus/v1/list?orgid=7&pid=' + globalThis.CURRENT_ID, (resp: any) => {
                                resp = JSON.parse(resp);
                                if (resp.msg == 'success') {
                                    let { rows } = resp;
                                    rows = rows.filter(r => !r.has_courseware)
                                    console.log('SubmarineView', rows);
                                    ctx.SubmarineViewData = rows;
                                    ctx.currentDataset = rows;
                                }
                            });

                        }
                    },
                    on: {
                        LOAD: {
                            target: 'SubmarineView',
                            actions: (ctx, event) => {
                                console.log('SubmarineView LOAD', ctx, event);
                            }
                        },
                        LETTER: 'LetterView',
                        STORY: 'StoryView',
                        REVIEW: 'ReviewView',
                        BACK: {
                            target: 'SpaceView',
                            actions: (ctx, event) => {
                                console.log('back', ctx, event);
                            }
                        }
                    },
                },
                LetterView: {

                    on: {
                        BACK: {
                            target: 'SubmarineView',
                            actions: () => {
                                globalThis.CURRENT_ID = globalThis.CURRENT_PID;
                            }
                        },
                        PLAY: {
                            target: 'PlayView',
                            actions: (ctx, event) => {
                                console.log('PLAY', ctx, event);
                            }
                        }
                    },
                    invoke: {
                        src: (ctx, event) => {
                            // console.log(222,event)
                            // if (event.id) {
                            //     globalThis.CURRENT_PID = globalThis.CURRENT_ID;
                            //     globalThis.CURRENT_ID = event.id;
                            // }

                            this.callNetworkApiGet(this.BASE_URL + '/api/syllabus/v1/list?orgid=7&pid=' + globalThis.CURRENT_ID, (resp: any) => {
                                resp = JSON.parse(resp);
                                if (resp.msg == 'success') {
                                    let { rows } = resp;
                                    rows = rows.filter(r => r.has_courseware);
                                    console.log('LetterView', rows);
                                    ctx.LetterViewData = rows;
                                    ctx.currentDataset = rows;
                                }
                            });

                        }
                    },
                    entry: (ctx, event) => {
                        console.log('entry LetterView stage',);
                        this.LetterView.active = true;
                        this.StoryView.active = false;
                        this.ReviewView.active = false;
                        this.SubmarineView.active = true;
                        this.LetterViewLabel.string = event.buttonName;

                    },
                    exit: () => {
                        console.log('exit LetterView stage');
                    }
                },
                StoryView: {
                    on: {

                        BACK: {
                            target: 'SubmarineView',
                            actions: (ctx) => {
                                globalThis.CURRENT_ID = globalThis.CURRENT_PID;
                            }
                        },
                        PLAY: {
                            target: 'PlayView',
                            actions: (ctx, event) => {
                                console.log('back', ctx, event);
                            }
                        },
                    },
                    invoke: {
                        src: (ctx, event) => {
                            return new Promise<void>((resolve, reject) => {
                                this.callNetworkApiGet(this.BASE_URL + '/api/syllabus/v1/list?orgid=7&pid=' + globalThis.CURRENT_ID, (resp: any) => {
                                    resp = JSON.parse(resp);
                                    if (resp.msg == 'success') {
                                        let { rows } = resp;
                                        rows = rows.filter(r => r.has_courseware);
                                        console.log('StoryView', rows);
                                        ctx.StoryViewData = rows;
                                        ctx.currentDataset = rows;
                                        rows.forEach((r, idx) => {
                                            const btn = this.StoryViewButtons[idx];
                                            btn.active = true;
                                            const cover = btn.getComponent('Cover')
                                            console.log(r.cover);
                                            cover.setUrl(r.cover);
                                        });
                                        resolve()
                                    }
                                });
                            });


                        }
                    },
                    entry: (ctx, event) => {
                        // console.log('entry StoryView stage');
                        this.LetterView.active = false;
                        this.StoryView.active = true;
                        this.ReviewView.active = false;
                        this.SubmarineView.active = true;


                        this.ReviewViewButtons
                    },
                    exit: () => {
                        // console.log('exit StoryView stage');
                    },
                },
                ReviewView: {
                    on: {
                        BACK: {
                            target: 'SubmarineView',
                            actions: (ctx) => {
                                globalThis.CURRENT_ID = globalThis.CURRENT_PID;
                            }
                        },
                        PLAY: {
                            target: 'PlayView',
                            actions: (ctx, event) => {
                                // console.log('back', ctx, event);
                            }
                        },
                    },
                    invoke: {
                        src: (ctx, event) => {

                            this.callNetworkApiGet(this.BASE_URL + '/api/syllabus/v1/list?orgid=7&pid=' + globalThis.CURRENT_ID, (resp: any) => {
                                resp = JSON.parse(resp);
                                if (resp.msg == 'success') {
                                    let { rows } = resp;
                                    rows = rows.filter(r => r.has_courseware);
                                    console.log('ReviewView', rows);
                                    ctx.ReviewViewData = rows;
                                    ctx.currentDataset = rows;
                                    rows.forEach((r, idx) => {
                                        const btn = this.ReviewViewButtons[idx];
                                        btn.active = true;
                                        const cover = btn.getComponent('Cover')
                                        cover.setUrl(r.cover);
                                    });
                                }
                            });

                        }
                    },
                    entry: (ctx, event) => {
                        // console.log('entry ReviewView stage');
                        this.LetterView.active = false;
                        this.StoryView.active = false;
                        this.ReviewView.active = true;
                        this.SubmarineView.active = true;

                    },
                    exit: () => {
                        // console.log('exit ReviewView stage');
                    },
                },
                PlayView: {
                    on: {

                    },
                    invoke: {
                        src: (ctx, event) => {
                            this.showWaitingLetters();
                        }
                    },
                    entry: (ctx, event) => {
                        console.log('entry PlayView stage');
                        this.showWaitingLetters();
                        cc.audioEngine.stopMusic();
                        const configData = globalThis.configData;
                        console.log(this);
                        let isDebug = false;
                        if (this.BackDoorNode) {
                            const bd = this.BackDoorNode.getComponent('BackDoor');
                            if (bd && bd.isDebug()) {
                                isDebug = true;
                            }
                        }
                        cc.assetManager.loadBundle(configData.bondleUrl, { version: configData.version }, async (err, bundle) => {
                            if (err) {
                                return console.log(err);
                            }
                            bundle.loadScene(configData.sceneName, null, null, (err, scene) => {
                                cc.director.runScene(scene, null, () => {
                                    try {
                                        const middleLayer = cc.find('middleLayer').getComponent('middleLayer');
                                        console.log(event.id, event.linkFlag);
                                       
                                        if (!isDebug) {
                                            middleLayer.loadOnlineCourseWare(event.id, event.linkFlag);
                                        }
                                        
                                    } catch (e) {
                                        console.error(e);
                                    }

                                });
                            });
                        });
                        // this.LetterView.active = false;
                        // this.StoryView.active = false;
                        // this.ReviewView.active = true;
                        // this.SubmarineView.active = false;
                    },
                    exit: () => {
                        this.hideWaitingLetters();
                        console.log('exit PlayView stage');
                    },
                },
            }
        };


        const operationMachine = createMachine(operationState);

        this.gameMachineService = interpret(operationMachine).onTransition((state) => {
            console.log(1, state);
        });
        
    }
    restore() {
        if (globalThis.PREV_STATE) {
            globalThis.CURRENT_ID = globalThis.PREV_STATE.data.id
            globalThis.CURRENT_PID = globalThis.PREV_STATE.data.pid
            this.gameMachineService.send('SpaceView', { ...globalThis.PREV_STATE.data, type: globalThis.PREV_STATE.state });
            globalThis.CURRENT_STATE = JSON.parse(JSON.stringify(globalThis.PREV_STATE));
            globalThis.PREV_STATE = null;
        }
    }
    setStateContextData({ rows, buttonsKey }) {
        const buttons = buttonsKey;
        buttons.forEach((b: any) => {
            b.getComponent(cc.Button).interactable = false;
        });
        rows.forEach((item, idx) => {
            if (!buttons[idx]) {
                return;
            }
            (buttons[idx] as any).getComponent(cc.Button).interactable = true;
            (buttons[idx] as any).getComponent(cc.Button).dataIndex = idx;
            (buttons[idx] as any).getComponent(cc.Button).dataMeta = item;
            const [_, action, index] = (buttons[idx] as any).name.split('@');
            (buttons[idx] as any).off(cc.Node.EventType.TOUCH_START);
            (buttons[idx] as any).on(cc.Node.EventType.TOUCH_START, function () {
                this.gameMachineService.send(action, item)
            }, this, true)
        });
    }
    callNetworkApiGet(uri, successCallBack: (resp: string) => void, errorCallback?: (any) => void) {
        this.showWaitingLetters()

        const xhr = new XMLHttpRequest();
        xhr.onreadystatechange = () => {
            if (xhr.readyState == 4) {
                this.hideWaitingLetters()
                if ((xhr.status >= 200 && xhr.status < 400)) {
                    successCallBack && successCallBack(xhr.responseText);
                } else {
                    errorCallback && errorCallback(xhr)
                }
            }

        };
        console.log('url = ' + uri);
        xhr.open('GET', uri, true);
        xhr.send();
    }
    hideWaitingLetters() {
        this.LoadingCount--;
        if (this.LoadingCount <= 0) {
            this.LoadingCount = 0;
            setTimeout(() => {
                if (this.tws){
                    for (const tw of this.tws) {
                        tw.node.y = 0;
                        tw.tw.stop();
                    }
                } 
                this.loading.active = false;
            });
        }
    }
    showWaitingLetters() {
        this.LoadingCount += 1;
        if (this.loading.active) {
            return;
        }
        const colorList = this.getRainbowColorList();
        const text = this.loading.getChildByName('text')
        text.children.forEach((node, idx) => {
            node.color = colorList[idx];
            const tw = cc.tween(node)
            .delay(idx / 4)
            .to(0.3, { y: 50 }, { easing: 'sineOut' })
            .to(0.3, { y: -50 }, { easing: 'sineIn' })
            .delay((text.children.length - idx) / 4)
            .union()
            .repeatForever()
            .start();
            this.tws.push({
                tw,
                node
            });
        });
        this.loading.active = true;
    }
    getRainbowColorList() {
        return [
            cc.color(255, 255, 0),
            cc.color(128, 255, 0),
            cc.color(0, 255, 0),

            cc.color(0, 255, 128),
            cc.color(0, 255, 255),

            cc.color(0, 128, 255),
            cc.color(0, 0, 255),
            cc.color(128, 0, 255),
            cc.color(255, 0, 255),
            cc.color(255, 0, 128),

            cc.color(255, 0, 0),
            cc.color(255, 128, 0),
            cc.color(255, 255, 0),
        ];
    }

}
