import { _decorator, Component, Node, Prefab, director, find } from 'cc';
import { EventDispatcher } from '../../engines/events/EventDispatcher';
import { DataModel } from '../../engines/models/DataModel';
import { DataModelEventType } from '../../engines/models/DataModelEventType';
import { NoticeManager } from '../../engines/notices/NoticeManager';
import GameConfigManager from './GameConfigManager';
import { GamePropertys } from './GamePropertys';
import { WeaponCell } from './weapons/WeaponCell';
const { ccclass, property } = _decorator;

export class GameModel extends DataModel{

    /**
     * 武器格子列表
     */
    private __weaponCells:WeaponCell[]=[];

    /**
     * 购买记录
     */
    private __buyHistory:Map<number,number>=new Map<number,number>();
    
    /**
     * 当前武器格子
     */
    private __currentWeaponCell:WeaponCell;

    constructor(){
        super();
    }

        /**
     * 设置默认属性
     */
    SetDefaultPropertys():void{
        //默认武器
        this.__currentWeaponCell=new WeaponCell();
        this.__currentWeaponCell.cellId=-1;
        this.__currentWeaponCell.lastOutputTime=director.getCurrentTime();
        this.__currentWeaponCell.weaponId=10101;

        //默认关卡
        this.currentLevel=1;
        //默认栅栏
        this.currentFenceId=30001;

        //默认最大已合成枪ID
        this.synthesisMaxWeaponId=10101;

        this.gold=0;
        this.diamond=0;
        //12个默认格子
        let weaponCell:WeaponCell;
        for (let index = 0; index < 12; index++) {
            weaponCell=new WeaponCell();
            weaponCell.cellId=index;
            weaponCell.weaponId=index==0?10101:-1;
            weaponCell.lastOutputTime=0;
            this.__weaponCells.push(weaponCell);
        }
        
        //保存到本地
        this.SaveToLoacl();
    }

    private lastTime:number=0;

    /**
     * 每秒总收益
     */
    public fullEarnings:number=0;

    /**
     * 收益计算间隔
     */
    get earningsInterval():number{
        return GameConfigManager.getGlobalValue("earningsInterval");
    }

    /**
     * 计算收益
     */
    CheckEarnings():void{
        let currentTime:number=director.getCurrentTime();
        if(currentTime-this.lastTime<1000){
            return;
        }
        this.lastTime=currentTime;
        
        let fullEarnings:number=0;
        this.__weaponCells.forEach(weaponCell => {
            if(weaponCell.weaponId>=0){
                // weaponConfig=GameConfigManager.GetWeaponConfig(weaponCell.weaponId);
                // if(currentTime-weaponCell.lastOutputTime>this.earningsInterval){
                    // weaponCell.lastOutputTime=currentTime;
                    fullEarnings+=weaponCell.weaponConfig.earnings;
                // }
            }
        });
        if(this.__currentWeaponCell.weaponId>=0){
            // weaponConfig=GameConfigManager.GetWeaponConfig(this.__currentWeaponCell.weaponId);
            // if(currentTime-this.__currentWeaponCell.lastOutputTime>this.earningsInterval){
                // this.__currentWeaponCell.lastOutputTime=currentTime;
                fullEarnings+=this.__currentWeaponCell.weaponConfig.earnings;
            // }
        }
        if(fullEarnings>0){
            console.log("产出金币:"+fullEarnings);
            this.gold+=fullEarnings;
        }
        this.fullEarnings=fullEarnings;

        if(this.DataChanged){
            this.SaveToLoacl();
        }
    }

    private DataChanged:boolean;
    DispatchEvent(key: string, data?: any):void{
        super.DispatchEvent(key,data);
        this.DataChanged=true;
    }

    /**
     * 设置当前武器ID
     */
    set currentWeaponId(value:number){
        this.__currentWeaponCell.weaponId=value;
        this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED,GamePropertys.currentWeaponId);
    }

    get currentWeaponId():number{
        return this.__currentWeaponCell.weaponId;
    }

    /**
     * 合成武器
     * @param sourceCellId 
     * @param targetCellId 
     */
    public SynthesisWeapon(sourceCellId:number,targetCellId:number):void{
        let sourceCell:WeaponCell=this.FindCell(sourceCellId);
        let targetCell:WeaponCell=this.FindCell(targetCellId);
        if(sourceCell.weaponId!=targetCell.weaponId){
            console.error("要合成的武器ID不同！");
            return;
        }
        if(GameConfigManager.WeaponIsMaxLevel(sourceCell.weaponId)){
            console.error("武器已到达最高等级！");
        }
        let newWeaponId:number=GameConfigManager.GetNextLevelWeaponId(sourceCell.weaponId);
        //删除
        sourceCell.weaponId=-1;
        targetCell.weaponId=newWeaponId;
        targetCell.lastOutputTime=director.getCurrentTime();

        //对比新枪和老记录的合成枪
        let newWeaponConfig=GameConfigManager.GetWeaponConfig(newWeaponId);
        let synthesisMaxWeaponConfig=GameConfigManager.GetWeaponConfig(this.synthesisMaxWeaponId);
        //新记录
        if(newWeaponConfig.level>synthesisMaxWeaponConfig.level){
            this.synthesisMaxWeaponId=newWeaponId;
        }
        //如果比手上的好
        if(this.__currentWeaponCell.weaponConfig&&newWeaponConfig.level>this.__currentWeaponCell.weaponConfig.level){
            this.EquipWeapon(targetCellId);
            return;
        }
        this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED,GamePropertys.WeaponCell);
    }

    /**
     * 添加一个武器到武器格子
     * @param cellId 
     * @param weaponID
     */
    public AddWeapon(cellId:number,weaponID:number):void{
        for (let index = 0; index < this.__weaponCells.length; index++) {
            const element = this.__weaponCells[index];
            if(element.cellId==cellId){
                element.weaponId=weaponID;
                element.lastOutputTime=director.getCurrentTime();
                this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED,GamePropertys.WeaponCell);
                return;
            }
        }
    }

    /**
     * 删除武器
     * @param cellId 
     */
    public RemoveWeapon(cellId:number):void{
        for (let index = 0; index < this.__weaponCells.length; index++) {
            const element = this.__weaponCells[index];
            if(element.cellId==cellId){
                element.weaponId=-1;
                this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED,GamePropertys.WeaponCell);
                return;
            }
        }
    }

    /**
     * 卸下武器
     */
    public UnequipWeapon(cellId:number):void{
        let id:number=this.__currentWeaponCell.weaponId;
        this.currentWeaponId=-1;
        this.__currentWeaponCell.lastOutputTime=0;
        this.AddWeapon(cellId,id);
    }

    /**
     * 装配武器
     * @param weaponId 
     */
    public EquipWeapon(sourceCellId:number):void{
        let cell:WeaponCell=this.FindCell(sourceCellId);
        if(cell==null){
            throw new Error("找不到武器槽:"+sourceCellId);
        }
        let oldWeaponId=this.currentWeaponId;
        this.currentWeaponId=cell.weaponId;
        this.__currentWeaponCell.lastOutputTime=cell.lastOutputTime;
        cell.weaponId=oldWeaponId;
        cell.lastOutputTime=0;
        this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED,GamePropertys.WeaponCell);
    }

    /**
     * 武器空槽位置
     */
    public get WeaponEmptyCellCount():number{
        let count:number=0;
        this.__weaponCells.forEach(element => {
            if(element.weaponId<0){
                count++;
            }
        });
        return count;
    }

    /**
     * 寻找武器空槽位
     */
    public FindWeaponEmptyCell():WeaponCell{
        for (let index = 0; index < this.__weaponCells.length; index++) {
            const element = this.__weaponCells[index];
            if(element.weaponId<0){
                return element;
            }
        }
        return null;
    }

    /**
     * 当前快捷可购买的武器
     */
    public get CurrentQuickBuyWeaponId():number{
        return GameConfigManager.GetQuickBuyWeaponId(this.synthesisMaxWeaponId);
    }

    /**
     * 查询购买价格
     * @param weapon
     */
    public GetQuickBuyPrice():number{
        return this.GetWeaponBuyPrice(this.CurrentQuickBuyWeaponId);
    }

    /**
     * 查询购买价格
     * @param weaponId 
     */
    public GetWeaponBuyPrice(weaponId:number):number{
        //已购买的次数
        let buyCount:number=this.GetBuyCount(weaponId);
        let weaponConfig:any=GameConfigManager.GetWeaponConfig(weaponId);
        //价格
        let price:number=weaponConfig.consumeGold;
        //系数
        let coefficient:number=weaponConfig.coefficient;
        if(buyCount<0){
            buyCount=0;
        }
        return Math.floor(price*Math.pow(coefficient,buyCount));
    }

    /**
     * 已购买次数
     * @param weaponId 
     */
    public GetBuyCount(weaponId:number):number{
        let buyCount:number=0;
        if(this.__buyHistory.has(weaponId)){
            buyCount=this.__buyHistory.get(weaponId);
        }
        return buyCount;
    }

    /**
     * 购买武器
     * @param type 0 金币购买 1钻石购买 2视频购买 
     * @param weaponId 
     */
    public BuyWeapon(type:number,weaponId:number):boolean{
        let price:number;
        let weaponConfig:any

        //找到空槽位
        let weaponCell:WeaponCell=this.FindWeaponEmptyCell();
        if(weaponCell==null){
            NoticeManager.ShowPrompt("没有空槽位了！");
            return false;
        }

        if(type==0){
            price=this.GetWeaponBuyPrice(weaponId);
            if(this.gold<price){
                NoticeManager.ShowPrompt("金币不足，不能购买武器！");
                return false;
            }
            //扣钱
            let currentGold:number=this.gold;
            currentGold-=price;
            if(currentGold<0){
                currentGold=0;
            }
            this.gold=currentGold;
            //记录购买次数
            weaponConfig=GameConfigManager.GetWeaponConfig(weaponId);
            let buyCount:number=this.GetBuyCount(weaponId);
            buyCount++;
            if(buyCount>weaponConfig.frequencyLimit){
                buyCount=weaponConfig.frequencyLimit;
            }
            this.__buyHistory.set(weaponId,buyCount);
        }else if(type==1){
            let weaponConfig:any=GameConfigManager.GetWeaponConfig(weaponId);
            price=weaponConfig.consumeDiamond;
            if(this.diamond<price){
                NoticeManager.ShowPrompt("宝石不足，不能购买武器！");
                return false;
            }
            //扣钱
            let currentDiamond:number=this.gold;
            currentDiamond-=price;
            if(currentDiamond<0){
                currentDiamond=0;
            }
            this.diamond=currentDiamond;
        }
        //发货
        this.AddWeapon(weaponCell.cellId,weaponId);
        return true;
    }

    /**
     * 通过武器槽ID查找
     * @param id 
     */
    public FindCell(id:number):WeaponCell{
        for (let index = 0; index < this.__weaponCells.length; index++) {
            const element = this.__weaponCells[index];
            if(element.cellId==id){
                return element;
            }
        }
        return null;
    }

    /**
     * 武器格子列表
     */
    public get weaponCells():WeaponCell[]{
        return this.__weaponCells;
    }

    protected OnReadByLocal(data:any):void{
        let currentTime:number=director.getCurrentTime();
        //当前武器格
        this.__currentWeaponCell=new WeaponCell();
        for (const key in data.currentWeaponCell) {
            if (Object.prototype.hasOwnProperty.call(data.currentWeaponCell, key)&&Object.prototype.hasOwnProperty.call(this.__currentWeaponCell, key)) {
                const element = data.currentWeaponCell[key];
                this.__currentWeaponCell[key]=element;
            }
        }
        this.__currentWeaponCell.lastOutputTime=currentTime;
        //武器格子
        let weaponCells:any[]=data.weaponCells;
        this.__weaponCells=[];
        let weaponCell:WeaponCell;
        if(weaponCells!=null){
            weaponCells.forEach(element => {
                weaponCell=new WeaponCell();
                for (const key in element) {
                    if (Object.prototype.hasOwnProperty.call(element, key)&&Object.prototype.hasOwnProperty.call(weaponCell, key)) {
                        const item = element[key];
                        weaponCell[key]=item;
                    }
                }
                weaponCell.lastOutputTime=currentTime;
                this.__weaponCells.push(weaponCell);
            });
        }
    }

    protected OnSaveToLocal(data:any):void{
        data.weaponCells=this.__weaponCells;
        data.currentWeaponCell=this.__currentWeaponCell;
    }
    
    private static instance:GameModel;
    public static get single():GameModel{
        if(this.instance==null){
            this.instance=new GameModel();
        }
        return this.instance;
    }


    /**
     * 当前关卡
     */
    get currentLevel():number{
        return this.GetProperty(GamePropertys.currentLevel);
    }

    set currentLevel(value:number){
        this.SetProperty(GamePropertys.currentLevel,value);
    }

    /**
     * 当前栅栏ID
     */
    get currentFenceId():number{
        return this.GetProperty(GamePropertys.currentFenceId);
    }

    set currentFenceId(value:number){
        this.SetProperty(GamePropertys.currentFenceId,value);
    }

    /**
     * 金币
     */
    get gold():number{
        return this.GetProperty(GamePropertys.gold);
    }

    set gold(value:number){
        this.SetProperty(GamePropertys.gold,value);
    }


     /**
     * 积分
     */
    get integral():number{
        return this._interal
    }
    private _interal:number;
    set integral(value:number){
        this._interal=value;
        this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED,GamePropertys.integral);
    }

    /**
     * 钻石
     */
    get diamond():number{
        return this.GetProperty(GamePropertys.diamond);
    }

    set diamond(value:number){
        this.SetProperty(GamePropertys.diamond,value);
    }

    /**
     * 击杀数量
     */
    get killCount():number{
        return this.GetProperty(GamePropertys.killCount);
    }

    set killCount(value:number){
        this.SetProperty(GamePropertys.killCount,value);
    }
    
    /**
     * 怒气值
     */
    get angerCount():number{
        return this.GetProperty(GamePropertys.angerCount);
    }

    set angerCount(value:number){
        this.SetProperty(GamePropertys.angerCount,value);
    }

    /**
     * 当前最大合成等级
     */
    get synthesisMaxWeaponId():number{
        return this.GetProperty(GamePropertys.synthesisMaxWeaponId);
    }

    set synthesisMaxWeaponId(value:number){
        this.SetProperty(GamePropertys.synthesisMaxWeaponId,value);
    }

    /**
     * 上一次领取金币的时间
     */
    get lastGetGoldTime():number{
        return this.GetProperty(GamePropertys.synthesisMaxWeaponId);
    }

    set lastGetGoldTime(value:number){
        this.SetProperty(GamePropertys.synthesisMaxWeaponId,value);
    }
}