
const GameModule = require("./utils/GameModule");
const FriendSystemApi = require('./net/FriendSystemApi');
const ShareAction = require('./utils/ShareAction');
const DWTool = require('./utils/DWTool');
const DWAlert = require('./utils/DWAlert');
const HomeApi = require("./net/HomeApi");
const JobApi = require('./net/JobApi');
const { GameNotificationKey, SenceMap, JobPageType } = require('./utils/GameEnum');
const AlertManager = require('./utils/AlertManager');
const tutorial = require('./utils/Bundle').tutorial;
const StateMachine = require('./lib/StateMachine');
const StateMachineHistory = require('./lib/StateMachineHistory');
const WsManager = require('./net/Ws');

cc.Class({
    extends: cc.Component,

    properties: {

        levelHomePrefab: cc.Prefab,

        levelFriendHomePrefab: cc.Prefab,

        wechatFriendNode: cc.Node,

        //用户信息页
        userInfoPrefab: cc.Prefab,

        myInfoTop: cc.Node,

        myTabBottom: cc.Node,

        friendInfoTop: cc.Node,

        friendTabBottom: cc.Node,

        _otherActor: cc.Node,

        friendSystemPrefab: cc.Prefab,

        friendHeadSprite: cc.Sprite,

        talentPagePrefab: cc.Prefab,

        noticePoint: cc.Node,

        chooseJob: cc.Node,

        transition: cc.Node,

        mapIcon: cc.Node,

        homeGuide: cc.Node
    },


    onLoad() {
        GameModule.game = this.node;
        this.homeGuide.zIndex = 99;
        GameModule.homeGuide = this.homeGuide;

        // 创建一个事件监听实例, 用来实现跨节点监听事件
        GameEvent.init();

        //我的家园
        let levelHome = cc.instantiate(this.levelHomePrefab);
        levelHome = levelHome.getComponent('LevelHome');
        levelHome.init(Global.user.uid, Global.devCityId);
        this.levelHome = levelHome;

        //好友系统Tab面板
        let friendSystem = cc.instantiate(this.friendSystemPrefab);
        this.friendSystem = friendSystem.getComponent('FriendSystem');

        //好友家园
        let friendHome = cc.instantiate(this.levelFriendHomePrefab);
        friendHome = friendHome.getComponent('LevelFriendHome')
        this.friendHome = friendHome;

        //突破界面
        let breakOut = "";
        this.breakOut = breakOut;

        // //转职界面
        // this.jobChange = cc.instantiate(this.jobChangePrefab);
        // this.jobChange = this.jobChange.getComponent('ChangeJob');

        // 星探界面
        this.finder = cc.instantiate(this.talentPagePrefab);
        this.finder = this.finder.getComponent('TalentPage');

        // 引导界面
        this.homeGuide = this.homeGuide.getComponent('HomeGuide')
        this.homeGuide.init(this)

        // cc.loader.loadRes('prefabs/home_guide', cc.Prefab, (err, res) => {
        //     this.homeGuide = cc.instantiate(res)
        //     cc.find('Canvas').addChild(this.homeGuide);
        // })

        // 监听事件
        this._setEventListener();

        // 初始化场景管理状态机
        this._initFSM()

        // 初始化socket链接
        this._initSocketMng();

        if (Global.shareUid != -1) {
            console.log('shareUid: ' + Global.shareUid);
            this.processShareAction();
        }

        this.friendHeadSprite.node.on(cc.Node.EventType.TOUCH_END, () => {
            GameEvent.fire(GameNotificationKey.ShowUserInfomation, this.friendHome.uid);
        }, this);

        this.setMapIconVisible(true);


        // this.scheduleOnce(() => {
        //     Global.devCityId = 2;
        //     this.gameFSM.visitcitymap(true);
        // }, 2);
    },

    setMapIconVisible(visible) {
        if (Global.devCityId > 1) {
            this.mapIcon.active = visible;
        } else {
            this.mapIcon.active = false;
        }
    },

    updateUIState(state) {
        if (!!state['state6'].pass) {
            if (!this.myTabBottom.active) {
                this.myTabBottom.active = true
                let actionBottom = cc.moveBy(0.4, cc.v2(0, this.myTabBottom.height + 27));
                this.myTabBottom.runAction(actionBottom);
            }
        }
    },

    _initSocketMng() {
        let ja0ckUrl = `ws://172.16.15.170:8108/connect?uid=${Global.user.uid}&token=${Global.user.token}&channel=LuciferChannel&ver=1&os=1`
        let testUrl = `wss://test-message-allstar.duowan.com/connect?uid=${Global.user.uid}&token=${Global.user.token}&channel=LuciferChannel&ver=1&os=1`
        let saUrl = "ws://172.16.12.245:3000"
        let Message = tutorial.Message;

        let ws = new WsManager(testUrl, {
            binaryType: 'arraybuffer',
            autoConnect: true,          // 自动连接
            reconnection: true,         // 断开自动重连
            reconnectionDelay: 3000,    // 重连间隔时间，单位秒
            reconnectionAttempts: 5     // 最大重连尝试次数，默认为Infinity
        })

        let seq = 1;

        ws.on('open', (res) => {
            /**
             * targetUid : 目标用户uid
             * opt : 操作类型
             * {1: 赎身; 2: 抢夺; 3: 签约; 4: 解雇; 5: 入驻;6: 召回;7: 驱赶;8: 举报; 9:通过好友申请;10:成为好友}
             * exBossUid : 抢夺成功时，前任老板的uid
             */
            GameEvent.on(GameNotificationKey.NoticeRoleOpt, this, (targetUid, opt, exBossUid) => {
                let payload = {
                    roleOptMessage: {
                        targetUid: targetUid,
                        opt: opt
                    },
                    type: 3
                }

                //抢夺成功时，需要加上前任老板的uid
                if (opt == 2) {
                    payload.roleOptMessage['exBossUid'] = exBossUid
                }

                let msg = Message.create(payload);
                let buffer = Message.encode(msg).finish()

                console.log('[Send msg]: ', msg);
                ws.send(buffer);
            });


        })

        ws.on('message', (data) => {
            let u8Arr = new Uint8Array(data)
            let decodeMsg = Message.decode(u8Arr);

            console.log("[Response text msg]: ", decodeMsg);

            if (decodeMsg.notificationMessage) {
                switch (decodeMsg.notificationMessage.nType) {
                    case 1:
                        //有新的通知
                        this.toggleNoticePoint(true)
                        break;
                    case 2:
                        //刷新好友列表
                        GameEvent.fire(GameNotificationKey.RefreshFriendList)
                        // this.levelHome.init(Global.user.uid, Global.cityId);
                        break;
                    case 3:
                        //刷新我的艺人列表
                        GameEvent.fire(GameNotificationKey.RefreshArtistManagerList)
                        break;
                    case 4:
                        // 刷新首页数据
                        GameEvent.fire(GameNotificationKey.ReloadLevelHomeData)
                        break;
                    default:
                        break;
                }
            }

        })

        ws.on('close', () => {
            GameEvent.off(GameNotificationKey.NoticeRoleOpt, this);
        })

        ws.on('error', () => {
            GameEvent.off(GameNotificationKey.NoticeRoleOpt, this);
        })
    },

    _initFSM() {
        let self = this
        let gameFSM = StateMachine.factory({
            init: 'levelhome',
            transitions: [
                { name: 'visitfriend', from: ['levelhome', 'userinfo', 'friendhome'], to: 'friendhome' },
                { name: 'showuserinfo', from: ['levelhome', 'friendhome'], to: 'userinfo' },
                { name: 'visitcitymap', from: 'levelhome', to: 'citymap' },
                { name: 'visitcity', from: 'citymap', to: 'levelhome' },
                { name: 'changejob', from: '', to: '' }
            ],
            methods: {
                onBeforeVisitcity(lifecycle, cid) {
                    //新城市初始化所有状态
                    self.levelHome.init(Global.user.uid, cid);
                },
                onVisitfriend(lifecycle, uid) {
                    //如果是friendhome状态之间跳转，则不切换右下方操作区域UI
                    let toggleTop = true, toggleBottom = cc.Node;
                    if (lifecycle.from == "friendhome") {
                        self._onLeaveFriendhome(toggleTop, toggleBottom)
                        self._onEnterFriendhome(uid, toggleTop, toggleBottom)
                    }
                    self._closeFriendSystem();
                    self.setMapIconVisible(false);
                },
                onShowuserinfo() {
                },
                onVisitcitymap() {

                },
                onEnterFriendhome(lifecycle, uid) {
                    self._onEnterFriendhome(uid)
                },
                onLeaveFriendhome() {
                    self._onLeaveFriendhome()
                },
                onEnterLevelhome() {
                    self.setMapIconVisible(true);
                    self._onEnterLevelhome()
                },
                onLeaveLevelhome() {
                    self._onLeaveLevelhome()
                },
                onEnterUserinfo(lifecycle, uid) {
                    self._enterUserInfo(uid)
                    self._hideTabbar();
                },
                onLeaveUserinfo() {
                    self._showTabbar();
                },
                onEnterCitymap(lifecycle, showAnim) {
                    self._onEnterCitymap(showAnim);
                },
                onLeaveCitymap() {
                    self._onLeaveCitymap()
                }

            },
            plugins: [
                new StateMachineHistory()
            ]
        })
        this.gameFSM = new gameFSM('levelhome')
    },

    /**
     * 进入好友家园
     * @param {Number} uid 用户id
     * @param {Boolean} showTop 是否显示顶部信息
     * @param {Boolean} showBottom 是否显示底部操作栏
     */
    _onEnterFriendhome(uid, showTop = true, showBottom = true) {
        if (uid) {
            this.friendHome.initFriend(uid, res => {
                this._showFriendUI(showTop, showBottom)
                this.friendHome.node.active = true;
            })
        } else {
            this.friendHome.reInitFriend(() => {
                this._showFriendUI(showTop, showBottom)
                this.friendHome.node.active = true;
            });
        }
    },

    /**
     * 离开好友家园
     * @param {Boolean} hideTop 是否隐藏顶部信息
     * @param {Boolean} hideBottom 是否隐藏底部操作栏
     */
    _onLeaveFriendhome(hideTop = true, hideBottom = true) {
        this._hideFriendUI(hideTop, hideBottom)
        this.friendHome.node.active = false;
    },

    /**
     * 进入我的家园
     */
    _onEnterLevelhome() {
        this._showHomeUI()

        if (!this.isFirstLoad) {
            this.isFirstLoad = true;

            this.transition.active = true;
            let actionFade = cc.sequence(cc.fadeOut(2), cc.callFunc(() => {
                this.transition.active = false;
            }))
            this.transition.runAction(actionFade.easing(cc.easeIn(1.5)));
        } else {
            this.transition.active = true;
            this.transition.opacity = 200;
            let actionFade = cc.sequence(cc.fadeOut(1), cc.callFunc(() => {
                this.transition.active = false;
            }))
            this.transition.runAction(actionFade.easing(cc.easeIn(1.5)));
        }

        this.levelHome.node.active = true;

        this.refreshActorNoJob();
    },

    /**
     * 离开我的家园
     */
    _onLeaveLevelhome() {
        this._hideHomeUI()
    },

    /**
     * 显示我的家园界面所需UI
     * 恢复LevelHome的位置到Canvas场景内
     */
    _showHomeUI() {
        let actionTop = cc.moveBy(0.4, cc.v2(0, -this.myInfoTop.height));
        this.myInfoTop.runAction(actionTop);

        this.levelHome.node.x = 0;
    },

    /**
     * 隐藏我的家园界面所需UI
     * 把LevelHome移出Canvas场景外
     */
    _hideHomeUI() {
        let actionTop = cc.moveBy(0.4, cc.v2(0, this.myInfoTop.height));
        this.myInfoTop.runAction(actionTop);

        setTimeout(() => {
            this.levelHome.node.x = -800;
        }, 500)
    },

    /**
     * 显示好友家园界面所需UI
     * @param {Boolean} showTop 是否显示顶部信息
     * @param {Boolean} showBottom 是否显示底部操作栏
     */
    _showFriendUI(showTop = true, showBottom = true) {
        if (showTop) {
            let actionTop = cc.moveBy(0.4, cc.v2(0, -this.friendInfoTop.height));
            this.friendInfoTop.runAction(actionTop);
        }

        if (showBottom) {
            let actionRight = cc.moveBy(0.4, cc.v2(-270, 0));
            this.friendTabBottom.runAction(actionRight);
        }
    },

    /**
     * 隐藏好友家园界面所需UI
     * @param {Boolean} hideTop 是否隐藏顶部信息
     * @param {Boolean} hideBottom 是否隐藏底部操作栏
     */
    _hideFriendUI(hideTop = true, hideBottom = true) {
        if (hideTop) {
            let actionTop = cc.moveBy(0.3, cc.v2(0, this.friendInfoTop.height));
            this.friendInfoTop.runAction(actionTop);
        }

        if (hideBottom) {
            let actionRight = cc.moveBy(0.3, cc.v2(270, 0));
            this.friendTabBottom.runAction(actionRight);
        }
    },

    /**
     * 恢复Tab的位置到Canvas场景内
     */
    _showTabbar() {
        this.myTabBottom.x = 0;
    },

    /**
     * 把Tab移出Canvas场景外
     */
    _hideTabbar() {
        setTimeout(() => {
            this.myTabBottom.x = -800;
        }, 200)
    },

    /**
     * 进入个人信息页
     */
    _enterUserInfo(uid) {
        if (this.userInfo) {
            this.userInfo.init(this, uid);
        } else {
            DWTool.loadResPrefab('./prefabs/user_information')
                .then((result) => {
                    this.userInfo = cc.instantiate(result);
                    this.userInfo = this.userInfo.getComponent('UserInformation');
                    this.userInfo.init(this, uid);
                }).catch((err) => {
                    cc.error(err);
                });
        }
    },

    _showFriendSystem() {
        this.friendSystem.show(this.wechatFriendNode);
    },

    _closeFriendSystem() {
        this.friendSystem.close();
    },

    /**
     * 进入城市地图界面
     * @param {Boolean} showAnim 是否播放迁移到新城市的动画
     */
    _onEnterCitymap(showAnim) {
        let self = this;
        let devCityId = showAnim ? Global.devCityId - 1 : Global.devCityId;
        if (this.cityMap) {
            this.cityMap.show(showAnim, devCityId);
        } else {
            cc.loader.loadRes('/prefabs/map', cc.Prefab, (error, prefab) => {
                if (error === null) {
                    this.cityMap = cc.instantiate(prefab);
                    cc.find('Canvas').addChild(this.cityMap);
                    this.cityMap = this.cityMap.getComponent('CityMapCtrl');
                    this.cityMap.init(this);
                    this.cityMap.show(showAnim, devCityId);
                } else {
                    console.log(JSON.stringify(error));
                }
            });
        }
        // this._hideLevelHome();

        // this.hideLevelHome();
    },

    /**
     * 离开城市地图界面
     */
    _onLeaveCitymap() {
        if (this.cityMap) {
            this.cityMap.node.active = false;
        }
    },

    /**
     * 查看他人艺人列表
     */
    showOtherActors() {
        DWTool.loadResPrefab('./prefabs/other_artist_list')
            .then((result) => {
                this._otherActor = cc.instantiate(result);
                this._otherActor.getComponent("OtherArtistList").uid = this.friendHome.uid;
                this._otherActor.parent = cc.find("Canvas");
            }).catch((err) => {
                cc.error(err);
            });
    },

    /**
     * 关闭他人艺人列表
     */
    closeOtherActors() {
        this._otherActor.destroy();
    },

    showCompanyMax() {
        ///由于阿德的上报等级不够及时，所以满级等5秒再显示去下个城市的按钮
        this.scheduleOnce(() => {
            if (Global.devCityId === 1) {
                this.showCatFlyAnimation();
                this.mapIcon.active = true;
            } else {
                this.showCompanyMaxAlert();
            }
        }, 5);
    },

    showCompanyMaxAlert() {
        cc.loader.loadRes('/prefabs/current_company_max', cc.Prefab, (error, prefab) => {
            if (error === null) {
                let companyMaxAlert = cc.instantiate(prefab);
                cc.find('Canvas').addChild(companyMaxAlert);
            } else {
                console.log(JSON.stringify(error));
            }
        });
    },

    //转职
    //选择职业
    //职业突破页面
    showJobPage(type, userInfo, zIndex) {

        let self = this;

        cc.loader.loadRes('/prefabs/change_job', cc.Prefab, (error, prefab) => {
            if (error === null) {
                let jobChange = cc.instantiate(prefab);
                self.jobChange = jobChange.getComponent('ChangeJob');
                self.jobChange.show(type, userInfo, zIndex);
            } else {
                console.log(JSON.stringify(error));
            }
        });
    },

    showChooseJob() {
        let self = this;
        cc.loader.loadRes('/prefabs/change_job', cc.Prefab, (error, prefab) => {
            if (error === null) {
                let jobChange = cc.instantiate(prefab);
                this.jobChange = jobChange.getComponent('ChangeJob');
                this.jobChange.showFromTalent(JobPageType.ChooseJob, self.noJobActors);
            } else {
                console.log(JSON.stringify(error));
            }
        });
    },

    //关闭转职，选择职业，突破页面
    closeJobPage() {
        this.jobChange.close();
    },

    showTalentPage() {
        this.finder.show();
    },

    /**
     * 是否显示按钮提示
     * @param {Boolean} flag 
     */
    toggleNoticePoint(flag) {
        if (flag) {
            this.noticePoint.active = true
        } else {
            this.noticePoint.active = false
        }
    },

    showCatFlyAnimation() {
        GameEvent.fire(GameNotificationKey.showCatFlyAnimation, this.mapIcon.getPosition());
    },

    handleCityMap: _.debounce(() => {
        GameEvent.fire(GameNotificationKey.ShowCityMap, false);
        // GameEvent.fire(GameNotificationKey.showCatFlyAnimation, this.mapIcon.getPosition());
    }, 1000, true),

    handleNoticePopup: _.debounce((event) => {
        AlertManager.showNoticePopup();
        event.target.getChildByName("notice_point").active = false
    }, 1000, true),

    handleBack: _.debounce(() => {
        GameEvent.fire(GameNotificationKey.HistoryBack)
    }, 1000, true),

    // 监听事件
    _setEventListener() {

        GameEvent.on(GameNotificationKey.ShowCityMap, this, (showAnim) => {
            this.gameFSM.visitcitymap(showAnim);
            // this.showCatFlyAnimation();
        });

        GameEvent.on(GameNotificationKey.ShowFriendSystem, this, () => {
            this._showFriendSystem();
        });

        GameEvent.on(GameNotificationKey.VisitFriendHome, this, (uid) => {
            this.gameFSM.visitfriend(uid)
        });

        GameEvent.on(GameNotificationKey.HistoryBack, this, () => {
            this.gameFSM.historyBack()
        })

        GameEvent.on(GameNotificationKey.ShowUserInfomation, this, (uid) => {
            this.gameFSM.showuserinfo(uid)
        });

        GameEvent.on(GameNotificationKey.ProcessShareAction, this, this.processShareAction);

        GameEvent.on(GameNotificationKey.ShowJobPage, this, this.showJobPage);

        GameEvent.on(GameNotificationKey.ShowJobPageFromTalent, this, this.showChooseJob);

        GameEvent.on(GameNotificationKey.RefreshFriendList, this, this.refreshActorNoJob);

        GameEvent.on(GameNotificationKey.CurrentCompanyMax, this, this.showCompanyMax);

        GameEvent.on(GameNotificationKey.afterCatFly, this, this.showCompanyMaxAlert);
    },

    onDestroy() {

        GameEvent.off(GameNotificationKey.ShowFriendSystem, this);
        GameEvent.off(GameNotificationKey.VisitFriendHome, this);
        GameEvent.off(GameNotificationKey.HistoryBack, this);
        GameEvent.off(GameNotificationKey.ProcessShareAction, this);
        GameEvent.off(GameNotificationKey.ShowUserInfomation, this);
        GameEvent.off(GameNotificationKey.ShowJobChoose, this);
        GameEvent.off(GameNotificationKey.ShowJobPage, this);
        GameEvent.off(GameNotificationKey.RefreshFriendList, this);
        GameEvent.off(GameNotificationKey.ShowJobPageFromTalent, this);
        GameEvent.off(GameNotificationKey.ShowCityMap, this);
        GameEvent.off(GameNotificationKey.CurrentCompanyMax, this);
        GameEvent.off(GameNotificationKey.afterCatFly, this);
    },

    processShareAction() {
        console.log('processShareAction');
        if (Global.user != null) {
            if (Global.shareType == ShareAction.ADD_FRIEND) {
                let shareUid = Global.shareUid
                FriendSystemApi.addFriend(shareUid, () => {
                    GameEvent.fire('refresh_friend_list');

                    setTimeout(() => {
                        GameEvent.fire(GameNotificationKey.NoticeRoleOpt, shareUid, 10);
                    }, 2500)
                });
            } else if (Global.shareType == ShareAction.BECOME_ARTIST) {
                let shareUid = Global.shareUid
                FriendSystemApi.becomeArtist(shareUid, () => {
                    GameEvent.fire('refresh_friend_list');

                    setTimeout(() => {
                        GameEvent.fire(GameNotificationKey.NoticeRoleOpt, shareUid, 10);
                    }, 2500)
                });
            }
            Global.shareUid = -1;
            Global.shareType = ShareAction.None;
        }
    },

    refreshActorNoJob() {
        JobApi.actorsNoJob(
            (response) => {
                if (response.list && !_.isEmpty(response.list) && response.list.length > 0) {
                    this.chooseJob.active = true;
                    this.noJobActors = response.list;
                } else {
                    this.chooseJob.active = false;
                }
            },
            (code, msg) => {
                // this.chooseJob.active = false;
            }
        );
    }
});
