
const DWTool = require('../utils/DWTool');
const { RoomState, GameNotificationKey, LevelHomeArtistItemStyle } = require("../utils/GameEnum");
const GameModule = require("../utils/GameModule");
const ThemeManager = require("../utils/ThemeManger");
const HomeApi = require("../net/HomeApi");
// const StateMachine = require('../lib/StateMachine');
// const StateMachineHistory = require('../lib/StateMachineHistory');

cc.Class({
    extends: cc.Component,

    properties: {

        // Public Properties

        /** 当前显示的图片 */
        buildSprite: cc.Sprite,

        // 两边的柱子
        pillars: [cc.Sprite],

        bottomBg: cc.Sprite,

        lockBottomBg: cc.Sprite,

        /** 升级按钮的两种状态图 */
        updateBtnFrames: [cc.SpriteFrame],

        /** 未解锁, 解锁的图片 */
        lockSpriteFrames: [cc.SpriteFrame],

        /** 未解锁状态的节点 */
        lockNode: cc.Node,

        /** 需要花费所有金币 */
        costLabel: cc.Label,

        /** 未解锁需要花费多少金币 */
        unlockLabel: cc.Label,

        /** 建筑昵称 */
        buildNameLabel: cc.Label,

        /** 这里当做升级建筑按钮 */
        updateBtn: cc.Sprite,

        /** 更新按钮的背景, 用来做呼吸灯效果 */
        // updateBtnBg: cc.Sprite,

        /** 解锁按钮 */
        lockBtn: cc.Sprite,

        /** 解锁按钮背景图 */
        lockSprite: cc.Sprite,

        lockBottomNode: cc.Node,

        /** 等级节点 */
        levelProgressNode: cc.Node,

        /** 等级进度条 */
        levelProgressBar: cc.ProgressBar,

        /** 等级 */
        levelProgressLabel: cc.RichText,

        /** 生产金币节点 */
        rateProgressNode: cc.Node,

        /** 生产金币进度条 */
        rateProgressBar: cc.ProgressBar,

        /** 生产了多少金币 */
        rateProgressLabel: cc.Label,

        /** 倒计时 */
        countdownLabel: cc.Label,

        /** 金币满了提示 */
        coinFullTip: cc.Node,

        artistList: cc.Node,

        artistListItem: cc.Prefab,

        openDoorSkeletion: sp.Skeleton,

        updateSkeletion: sp.Skeleton,

        // 显示加成的节点
        additionNode: cc.Node,

        // 显示加成倍数
        additionLabel: cc.Label,

        // 满级提示
        maxNode: cc.Node,

        addition: {
            get: function () {
                if (!this._addition) {
                    this._addition = 0;
                }
                return this._addition;
            },
            set: function (value) {
                this._addition = value;
                if (this._addition === 0) {
                    this.additionNode.active = false;
                } else {
                    this.additionNode.active = true;
                    this.additionLabel.string = `X${this._addition}`;
                }
            }
        },

        coinArrayMax: {
            default: 3,
            type: cc.Integer,
            tooltip: "当前楼层最大存储金币数"
        },

        coinWrap: cc.Node,

        coinPrefab: cc.Prefab,

        countDown: {
            get: function () {
                if (!this._countDown) {
                    this._countDown = 0;
                }
                return this._countDown;
            },
            set: function (value) {
                this._countDown = value;
                this.countdownLabel.string = DWTool.calculateTime(this._countDown);
                this._preCountDown = this._countDown;
            }
        },

        rate: {
            get: function () {
                if (!this._rate) {
                    this._rate = 0;
                }
                return this._rate;
            },
            set: function (value) {
                this._rate = value;
                if (this.addition > 0) {
                    this._rate = this._rate * this.addition;
                }
                this.rateProgressLabel.string = DWTool.coinParse(this._rate);
            }
        },

        notPickupCount: {
            get: function () {
                if (!this._notPickupCount) {
                    this._notPickupCount = 0;
                }
                return this._notPickupCount;
            },
            set: function (value) {
                this._notPickupCount = value;
                this.buildingInfo.coinCount = value;
                this.isNeedToReport = true;
            }
        },
    },

    // LIFE-CYCLE CALLBACKS:
    onLoad() {

        this.isNeedToReport = false;
        this.coinArray = [];
        this._currentTime = 0;
        this.isFirstLoad = true;
        this.humanList = [];
        this.updateSkeletion.node.active = false;

        // 监听自定义事件
        this.setEventListener();

        // 解锁建筑事件
        this.lockBtn.node.on(cc.Node.EventType.TOUCH_END, () => {

            // 如果当前不够钱, 点击不生效
            if (GameModule.userInfo.grossIncome < this.buildingInfo.unlockScore) { return; }

            // 点完立刻隐藏
            this.lockBtn.node.active = false;

            this.openDoorSkeletion.setAnimation(1, "changjing_kaiqi2");

            this.lockBottomNode.runAction(cc.fadeOut(0.1));

            this.openDoorSkeletion.setCompleteListener(() => {
                this.openDoorSkeletion.setCompleteListener(null);
                // 升级建筑
                this.updateBuilding();
                GameEvent.fire(GameNotificationKey.PlaySuccessAnimation);
            });

        }, this);

        // 升级建筑事件
        this.updateBtn.node.on(cc.Node.EventType.TOUCH_END, () => {

            if (this.state === RoomState.Update) {

                // 清空当前用来存储金币节点
                this.currentCoin = null;
                for (let i = 0; i < this.coinArrayMax; i++) {
                    this.pickupCoin(this.coinArray[i], i);
                }

                this.updateBuilding(); 
                
                if (!this.updateSkeletion.node.active) {
                    this.updateSkeletion.node.active = true;
                    this.updateSkeletion.setAnimation(0, "changjing_sj");

                    this.updateSkeletion.setCompleteListener(() => {
                        this.updateSkeletion.node.active = false;
                    });
                }
            }
        }, this);

        this.schedule(() => {
            if (this.isNeedToReport) {
                this.isNeedToReport = false;
                GameModule.userInfo.updateRecordModify(this.buildingInfo);
            }
        }, 2.0); 

        // 配置界面上的金币
        this.configCoins();

    },

    onDestroy() {
        GameEvent.off(GameNotificationKey.ResidentArtist, this);
        GameEvent.off(GameNotificationKey.RefreshLevelHomeArtistList, this);
        GameEvent.off(GameNotificationKey.LevelHomeItemBuildingAllFull, this);
    },

    setEventListener() {

        // 这个是入驻艺人成功时调用的
        GameEvent.on(GameNotificationKey.ResidentArtist, this, (uid, buildingId) => {
            
            if (this.node.active && this.uid === uid && this.buildingInfo.buildingId === buildingId) {
                HomeApi.friendGetArtistsInBuilding(this.uid, this.buildingInfo.buildingId, (data) => {

                    // 为了不让当前的金币出现多种不同金额的币种, 当列表刷新时, 要收取一次
                    if (this.state === RoomState.Update || this.state === RoomState.Full) {
    
                        // 清空当前用来存储金币节点
                        this.currentCoin = null;
                        for (let i = 0; i < this.coinArrayMax; i++) {
                            this.pickupCoin(this.coinArray[i], i, false);
                        }
                    }
    
                    this.artists = data.list || [];
                    this.artistListLayout();
    
                }, (code, msg) => {
                    console.log(msg);
                })
            }
        });

        // 这个是召回驱赶艺人时调用的
        GameEvent.on(GameNotificationKey.RefreshLevelHomeArtistList, this, (uid, buildingId) => {

            if (this.node.active && this.uid === uid && this.buildingInfo.buildingId === buildingId) { 
                HomeApi.friendGetArtistsInBuilding(this.uid, this.buildingInfo.buildingId, (data) => {

                    this.artists = data.list || [];
                    this.artistListLayout();
    
                }, (code, msg) => {
                    console.log(msg);
                })
             }
        });

        // 所有建筑满级之后调用
        GameEvent.on(GameNotificationKey.LevelHomeItemBuildingAllFull, this, () => {

            if (this.isFirstLoad) { // 代表游戏一打开, 就是满级的
                this.currentCoin = null;
                this.coinWrap.active = false;
                this.artistList.active = false;
                this.coinFullTip.active = false;
            } else {
                GameModule.userInfo.updateRecordModify(this.buildingInfo);
                this.currentCoin = null;
                for (let i = 0; i < this.coinArrayMax; i++) {
                    this.pickupCoin(this.coinArray[i], i);
                }
                // 需要把艺人也都清空了
                for (let child of this.humanList) { child.destroy(); }
                this.coinWrap.active = false;
                this.artistList.active = false;
                this.coinFullTip.active = false;
            }
        })  
    },

    configCoins() {

        for (let i = 0; i < this.coinArrayMax; i++) {

            // 初始化
            let coinNode = cc.instantiate(this.coinPrefab)
            this.coinWrap.addChild(coinNode);
            coinNode = coinNode.getComponent("LevelHomeCoin");

            this.coinHide(coinNode, i)
            this.coinArray[i] = coinNode; 

            coinNode.node.on(cc.Node.EventType.TOUCH_END, (event) => { 
                this.pickupCoin(coinNode, i);
            }, this);
        }
    },

    /**
     * Public Method, 用来设置建筑背景图
     * @param {*} index 
     */
    init(cityId, index) {
        if (arguments.length < 1) {
            throw new Error("init Missing parameter...");
        }

        this.cityId = cityId;
        this.index = index;
        this.isFirstLoad = true;
        
        ThemeManager.setItemBuildSpriteFrame(this.cityId, this.buildSprite, index);
        ThemeManager.setItemPillarSpriteFrame(this.cityId, this.pillars);
        ThemeManager.setItemDownSpriteFrame(this.cityId, this.bottomBg);
        ThemeManager.setItemLockDownSpriteFrame(this.cityId, this.lockBottomBg);
    },

    /**
     * Public Method, 配置建筑的内部样式
     * @param {*} buildingInfo 建筑信息
     * @param {*} uid 当前用户的uid
     */
    config(buildingInfo, uid) {

        if (arguments.length < 2) {
            throw new Error("Config Missing parameter...");
        }

        this.buildingInfo = buildingInfo;
        this.uid = uid;

        this.artists = this.buildingInfo.artists;

        // 这里设置一些只需要设置一次的数据
        this.countDown = buildingInfo.rateUnit;

        this.buildNameLabel.string = buildingInfo.name;
        this._notPickupCount = buildingInfo.coinCount;

        if (buildingInfo.coinCount === this.coinArrayMax * 10) {
            this.rateProgressBar.progress = 1;
            this.countdownLabel.string = DWTool.calculateTime(0);
        }
        this.levelProgressBar.progress = buildingInfo.level / Global.BuildingManager.getLevelCount(buildingInfo.buildingId);

        this.levelProgressLabel.string = `<outline color=#ffffff width=2><b><color= #0e689c>LV.${buildingInfo.level}</c></b></outline>`

        if (this.isFirstLoad) {
            this.isFirstLoad = false;
            this.artistListLayout();
        }

        //城市开发完毕的时候不显示艺人入驻按钮
        if (GameModule.userInfo.levelHomeItemFullCount != 5 && this.cityId === Global.cityId) {
            this.artistList.active = true;
        } else {
            this.artistList.active = false;
        }

        this.initializeCoinPosition();

        this.layout(buildingInfo);
    },

    /** 初始化金币的位置 */
    initializeCoinPosition() {

        // 2018年08月18日15:25, 子奇要求我去好友家园时, 不显示未收取金币
        // 城市已经开发完毕不显示金币
        if (this.cityId === Global.cityId && GameModule.userInfo.levelHomeItemFullCount != 5) {
            this.coinWrap.active = true;
        } else {
            this.coinWrap.active = false;
            return;
        }

        if (!this.buildingInfo.coinCount) {
            for (let i = 0; i < this.coinArrayMax; i++) {
                let coin = this.coinArray[i];
                this.coinHide(coin, i);
            }
            return;
        }

        for (let i = 0; i < this.coinArrayMax; i++) {
            let coin = this.coinArray[i];
            while (this.buildingInfo.coinCount != 0 && coin.coinCount != 10) {
                coin.coinCount += 1;
                this.buildingInfo.coinCount -= 1;
            }

            if (coin.coinCount != 0) {

                let x = -140 + (85 * i);

                coin.isPlay = true;
                coin.node.position = cc.v2(x, -28);
                coin.node.active = true;
                if (this.addition > 0) {
                    let rate = this.buildingInfo.rate * this.addition;
                    coin.totalRate = rate * coin.coinCount;
                } else {
                    coin.totalRate = this.buildingInfo.rate * coin.coinCount;
                }

                coin.initStatic(i);
            }
        }
    },

    artistListLayout() {

        for (let child of this.artistList.children) { child.destroy(); }
        for (let child of this.humanList) { child.destroy(); }

        let self = this;

        let addAddItemToList = function () {
            let addArtistItem = cc.instantiate(self.artistListItem);
            self.artistList.addChild(addArtistItem);
            let addArtistScript = addArtistItem.getComponent('LevelHomeArtistItem');
            addArtistScript.initWithBuildingInfo(self.buildingInfo, self.uid, true);
        }

        let addArtistItemToList = function (artist) {
            let artistItem = cc.instantiate(self.artistListItem);
            self.artistList.addChild(artistItem);
            let artistScript = artistItem.getComponent('LevelHomeArtistItem');
            artistScript.initWithArtistData(self.buildingInfo, self.uid, true, artist);
        }

        let addHuman = function (artist, index) {
            DWTool.loadResPrefab("./prefabs/artist_man")
                .then((prefab) => {
                    let human = cc.instantiate(prefab);
                    human.getComponent('ArtistMan').init(artist);
                    human.getComponent('ArtistMan').direction = (index > 0) ? 1 : -1;
                    self.node.addChild(human);
                    self.humanList.push(human);
                });
        }

        // 当没有自己艺人, 也没有好友艺人入驻时, 这里还得区分主态和客态
        if (this.artists.length === 0) {
            addAddItemToList();
            // 没有艺人不显示倍数
            this.addition = 0;
        } else {

            // 有艺人入驻要显示倍数
            this.additionNode.active = true;

            if (this.artists.length === 1) {

                let artist = this.artists[0];
                console.log(JSON.stringify(artist));
                this.addition += artist.stationJobLevel + 1;
                // 这里要区分主态和客态, 去别人家园时, 如果有一个是客态自己的艺人, 那么另一个就是可以入驻的按钮
                if (artist.role === 2) {

                    addArtistItemToList(artist);
                    addHuman(artist, (Math.random() - 0.5) * 2);

                } else {
                    addAddItemToList();
                    addArtistItemToList(artist);
                    addHuman(artist, (Math.random() - 0.5) * 2);
                }

            } else {
                for (let i = 0; i < this.artists.length; i++) {
                    let artist = this.artists[i];
                    this.addition += artist.stationJobLevel + 1;
                    addArtistItemToList(artist);
                    addHuman(artist, i);
                }
            }
        }
    },

    layout(buildingInfo) {

        // 判断是否有下一级, 没有的话就是满级
        if (buildingInfo.hasNext === 1 && buildingInfo.level <= Global.BuildingManager.getLevelCount(buildingInfo.buildingId)) {

            // 判断是否已经解锁
            if (buildingInfo.isUnlocked) {

                this.lockNode.active = false;
                this.costLabel.string = DWTool.coinParse(buildingInfo.nextUpScore);
                this.rate = buildingInfo.rate;
                // 判断是否有足够的金额解锁
                if (GameModule.userInfo.grossIncome >= buildingInfo.nextUpScore) {
                    this.setState(RoomState.Update);
                } else {
                    this.setState(RoomState.Lock);
                }

            } else {

                this.countDown = 0;
                this._currentTime = 0;
                this.rateProgressBar.progress = 0;
                this.totalRate = 0;
                this.lockNode.active = true;
                this.costLabel.string = 0;
                this.unlockLabel.string = DWTool.coinParse(buildingInfo.unlockScore);

                // 判断是否有足够的金额解锁
                if (GameModule.userInfo.grossIncome >= buildingInfo.unlockScore) {
                    this.lockSprite.spriteFrame = this.lockSpriteFrames[1];
                    this.lockBtn.spriteFrame = this.updateBtnFrames[1];
                    this.lockBtn.node.getComponent(cc.Button).interactable = true;
                } else {
                    this.lockSprite.spriteFrame = this.lockSpriteFrames[0];
                    this.lockBtn.spriteFrame = this.updateBtnFrames[0];
                    this.lockBtn.node.getComponent(cc.Button).interactable = false;
                }
                this.setState(RoomState.Lock);
            }

        } else {
            this.rate = buildingInfo.rate;
            this.setState(RoomState.Full);
        }
    },

    setState(state) {

        if (this.state === state) { return;}

        switch (state) {
            case RoomState.Lock:
                this.openDoorSkeletion.node.active = true;
                this.openDoorSkeletion.clearTracks();
                this.openDoorSkeletion.setToSetupPose();
                this.lockBtn.node.active = true;
                this.lockBottomNode.opacity = 255;
                this.lockBottomNode.active = true;
                this.lockNode.active = true;
                this.updateBtn.node.active = false;
                this.updateBtn.spriteFrame = this.updateBtnFrames[0];
                this.updateBtn.node.getComponent(cc.Button).interactable = false;
                this.maxNode.active = false;
                break;
            case RoomState.Update:
                this.openDoorSkeletion.node.active = false;
                this.lockBtn.node.active = false;
                this.lockBottomNode.opacity = 0;
                this.lockBottomNode.active = false;
                this.updateBtn.node.active = true;
                this.lockNode.active = false;
                this.updateBtn.spriteFrame = this.updateBtnFrames[1];
                this.updateBtn.node.getComponent(cc.Button).interactable = true;
                this.maxNode.active = false;
                break;
            case RoomState.Full:
                this.openDoorSkeletion.node.active = false;
                this.lockBtn.node.active = false;
                this.lockBottomNode.opacity = 0;
                this.lockBottomNode.active = false;
                this.lockNode.active = false;
                this.maxNode.active = true;
                this.updateBtn.node.active = false;
            default:
                break;
        }
        this.state = state;
    },

    // 升级建筑
    updateBuilding() {
        // 从配置文件里获取
        let buildModel = Global.BuildingManager.getBuildingInfo(this.cityId, this.buildingInfo.buildingId, this.buildingInfo.level + 1);
        
        // 将已有入驻的艺人赋值给新的model, 保持一个引用
        buildModel.artists = this.buildingInfo.artists;

        if (this.buildingInfo.isUnlocked) {
            GameModule.userInfo.grossIncome -= this.buildingInfo.nextUpScore;
            GameModule.userInfo.updateRecordModify(buildModel);
        } else {
            GameModule.userInfo.grossIncome -= this.buildingInfo.unlockScore;
            GameModule.userInfo.recordUnlockModify.push(buildModel);
        }

        GameModule.userInfo.stars += 1;

        this.config(buildModel, this.uid);

        // 如果满级了, 就发通知告诉userinfo
        if (buildModel.hasNext != 1) {
            GameEvent.fire(GameNotificationKey.LevelHomeItemBuildingFull);
        }
    },

    // 收取金币
    pickupCoin(coin, i, isShowAnimation = true) {

        if (this.currentCoin === coin) {
            this.currentCoin = null;
        }

        if (isShowAnimation) {
            let pos = coin.node.convertToWorldSpace(cc.v2(coin.node.width / 2, coin.node.height / 2));
            this.showCollectAnim(pos, coin.coinCount)
        }

        // 点击一次金币, 就将notPickupCount减去coinNode.coinCount
        this.notPickupCount -= coin.coinCount;

        // console.log(`收入: ${buildingInfo.rate * coin.coinCount}`);
        GameModule.userInfo.grossIncome += (this.buildingInfo.rate * coin.coinCount);

        this.coinHide(coin, i);
    },

    showCollectAnim(pos, colNums) {
        let canvasNode = cc.find("Canvas");
        let grossCoin = GameModule.userInfo.grossCoin;
        let grossCoinPos = grossCoin.node.convertToWorldSpace(cc.v2(grossCoin.node.width / 2, grossCoin.node.height / 2));

        // let colNums = 5
        let vSize = cc.view.getVisibleSize();
        let target = cc.v2(grossCoinPos.x - vSize.width / 2, grossCoinPos.y - vSize.height / 2)

        let i = 0;
        let runSt = setInterval(() => {
            if (i == colNums) {
                clearInterval(runSt)
            } else {
                let ran = (Math.random() - 0.5) * 2 * 3;

                let newCoin = cc.instantiate(this.coinPrefab);
                let posX = pos.x - vSize.width / 2;
                let posY = pos.y - vSize.height / 2;

                canvasNode.addChild(newCoin)

                newCoin.x = posX + ran * 15;
                newCoin.y = posY + 30 + ran * 15;
                newCoin.active = true;

                newCoin = newCoin.getComponent("LevelHomeCoin")
                newCoin.initAnim()

                let cbNotiStart = cc.callFunc(() => {
                    GameEvent.fire(GameNotificationKey.UserCollectCoin, true);
                })

                let cbDestroy = cc.callFunc(() => {
                    newCoin.node.destroy();
                })

                let act = cc.sequence(cc.moveTo(1, target), cbDestroy, cbNotiStart)

                newCoin.node.runAction(act.easing(cc.easeIn(2.1)));

                i++
            }
        }, 100);
    },

    coinHide(coin, i) {
        // 算出金币的x值, 70是金币宽度, -130是第一个金币的x值
        let x = -140 + (85 * i);

        // 重置金币状态
        coin.node.position = cc.v2(x, -108);
        coin.node.active = false;
        coin.isPlay = false;
        coin.isPlaying = false;
        coin.coinCount = 0;
        coin.totalRate = 0;
    },

    getFreeCoin() {
        for (let i = 0; i < this.coinArrayMax; i++) {
            let coinNode = this.coinArray[i];
            if (coinNode.coinCount != 10) {
                return coinNode;
            }
        }
        return null;
    },

    generateCoin() {

        if (this.currentCoin && this.currentCoin.coinCount < 10) {

            this.currentCoin.totalRate += this.rate;
            this.currentCoin.coinCount += 1;
            this.currentCoin.updateAnimation();

        } else {

            this.currentCoin = this.getFreeCoin();

            if (this.currentCoin) {
                this.currentCoin.totalRate += this.rate;
                this.currentCoin.coinCount += 1;

                if (!this.currentCoin.isPlay) {
                    this.currentCoin.showAnimation();
                } else {
                    this.currentCoin.updateAnimation();
                }
            }
        }
    },

    update(dt) {
        
        if (this.buildingInfo) {

            // 不断刷新界面
            this.layout(this.buildingInfo);

            // 只有已经解锁进度条才会走
            if (this.buildingInfo.isUnlocked) {

                // 进度条走完, 开始生产金币
                if (Math.floor(this.rateProgressBar.progress) === 1) {

                    if (GameModule.userInfo.levelHomeItemFullCount != 5 && // 是否满级
                        this.cityId === Global.cityId) { // 当前访问的是不是这个city

                        if (this.notPickupCount >= this.coinArrayMax * 10) {
                            
                            this.coinFullTip.active = true;

                        } else {

                            this.coinFullTip.active = false;

                            this.notPickupCount += 1;
                            this.generateCoin();
                            this.rateProgressBar.progress = 0;
                            this._currentTime = 0;
                        }

                    } else { // 满级后的状态
                        this.rateProgressBar.progress = 0;
                        this._currentTime = 0;
                        this.coinFullTip.active = false;
                    }

                } else {

                    this._currentTime += dt;
                    this.rateProgressBar.progress = this._currentTime / this.countDown;

                    let resultCountDown = this.countDown - Math.floor(this._currentTime);
                    if (this._preCountDown !== resultCountDown) {

                        this.countdownLabel.string = DWTool.calculateTime(resultCountDown);
                        this._preCountDown = resultCountDown;
                    }
                }
            }
        }
    },
});
