import { _decorator, Component, Node, Prefab, director, find } from 'cc';
import BufferManager from '../../engines/buffers/BufferManager';
import IBuffer from '../../engines/buffers/IBuffer';
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 { PlatformManager } from '../../Platform/PlatformManager';
import { branchIdType } from '../../Platform/WeChat/branchIdType';
import { WeChatPlatform } from '../../Platform/WeChat/WeChatPlatform';
import AccelerateBuffer from '../buffers/AccelerateBuffer';
import AutoSyntheticBuffer from '../buffers/AutoSyntheticBuffer';
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>();

    /**
     * 当前武器格子
     */
    currentWeaponCell: WeaponCell;

    constructor() {
        super();
    }

    /**
     * 设置默认属性
     */
    SetDefaultPropertys(): void {
        //7日登录
        this.signGetRecord=[0,0,0,0,0,0,0];

        //第一天
        this.signDay=1;
        //默认关卡
        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 < 2 ? 10101 : -1;
            weaponCell.lastOutputTime = 0;
            this.__weaponCells.push(weaponCell);
        }
        //默认武器
        this.currentWeaponCell=this.__weaponCells[0];

        //保存到本地
        this.SaveToLoacl();
    }

    private lastTime: number = 0;

    /**
     * 计算收益
     */
    CheckEarnings(): void {
        let currentTime: number = director.getCurrentTime();
        if (currentTime - this.lastTime < this.earningTime) {
            return;
        }
        this.lastTime = currentTime;
        let fullEarnings: number = this.fullEarnings;
        if (fullEarnings > 0) {
            console.log("产出金币:" + fullEarnings);
            this.gold += fullEarnings * (this.earningTime / 1000);
        }
        if (this.DataChanged) {
            this.SaveToLoacl();
        }
    }

    /**
     * 每秒总收益
     */
    get fullEarnings(): number {
        let result: number = 0;
        this.__weaponCells.forEach(weaponCell => {
            if (weaponCell.weaponId >= 0) {
                result += weaponCell.weaponConfig.earnings;
            }
        });
        return result;
    }

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

    /**
     * 收益间隔时间
     */
    get earningTime(): number {
        let bufferList: IBuffer[] = BufferManager.GetBufferGroup("Accelerate");
        if (bufferList == null || bufferList.length == 0) {
            return this.earningsInterval;
        }
        let buffer: AccelerateBuffer = bufferList[0] as AccelerateBuffer;
        return this.earningsInterval * buffer.rate;
    }

    /**
     * 自动合成武器
     */
    public AutoSynthetic(max: number = 1): void {
        let a: WeaponCell;
        let b: WeaponCell;
        let synIndex: number = 0;
        for (let aIndex = 0; aIndex < this.weaponCells.length; aIndex++) {
            a = this.weaponCells[aIndex];
            if (a.weaponId < 0 || GameConfigManager.WeaponIsMaxLevel(a.weaponId)) {
                continue;
            }
            for (let bIndex = aIndex + 1; bIndex < this.weaponCells.length; bIndex++) {
                b = this.weaponCells[bIndex];
                if (b.weaponId < 0 || GameConfigManager.WeaponIsMaxLevel(b.weaponId)) {
                    continue;
                }
                //可以合成
                if (a.weaponId == b.weaponId) {
                    this.SynthesisWeapon(a.cellId, b.cellId);
                    synIndex++;
                    //如果大于最大数
                    if (synIndex >= max) {
                        return;
                    }
                }
            }
        }
    }

    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 {
        if(this.currentWeaponCell==null){
            return -1;
        }
        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;
        }

        //打点合成最高等级的枪
        let weChat = PlatformManager.impl as WeChatPlatform;
        if (weChat instanceof WeChatPlatform) {
            let level = synthesisMaxWeaponConfig.level;
            if (newWeaponConfig.level > synthesisMaxWeaponConfig.level) {
                level = newWeaponConfig.level;
            }
            weChat.branchAnalytics(branchIdType.Synthetic, String(level))
        }

        if(this.currentWeaponCell!=null){
            if(this.currentWeaponCell==sourceCell){
                this.currentWeaponCell=null;
                this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED, GamePropertys.currentWeaponId);
            }else if(this.currentWeaponCell==targetCell){
                this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED, GamePropertys.currentWeaponId);
                //如果比手上的好
                if(this.currentWeaponCell.weaponConfig && newWeaponConfig.level > this.currentWeaponCell.weaponConfig.level){
                    this.EquipWeapon(targetCell);
                    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 {
        let cell:WeaponCell=this.FindCell(cellId);
        cell.weaponId=-1;
        if(cell==this.currentWeaponCell){
            this.currentWeaponCell=null;
            this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED, GamePropertys.currentWeaponId);
        }
        this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED, GamePropertys.WeaponCell);
    }

    // /**
    //  * 卸下武器
    //  */
    // 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(sourceCell:WeaponCell): void {
        this.currentWeaponCell=sourceCell;
        this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED, GamePropertys.WeaponCell);
        this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED, GamePropertys.currentWeaponId);
    }

    /**
     * 武器空槽位置
     */
    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 {
        //7日登录
        let date:Date=new Date();
        if(date.getTime()-this.lastSignTime>24*60*60*1000){
            this.signDay++;
            this.lastGetGoldTime=date.getTime();
        }

        let currentTime: number = director.getCurrentTime();
        //武器格子
        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);
            });
        }

        //当前武器格
        if(data.currentWeaponCellId>0){
            this.currentWeaponCell=this.FindCell(data.currentWeaponCellId);
            this.currentWeaponCell.lastOutputTime = currentTime;
        }

        //自动合成Buffer剩余时间
        if (data.autoSynthesisTime > 0) {
            let buffer: AutoSyntheticBuffer = new AutoSyntheticBuffer("AutoSynthesis", data.autoSynthesisTime);
            BufferManager.RunBuffer(buffer);
        }
        //加速Buffer
        if (data.accelerateTime > 0) {
            let buffer: AccelerateBuffer = new AccelerateBuffer("Accelerate", data.accelerateTime);
            BufferManager.RunBuffer(buffer);
        }
    }

    protected OnSaveToLocal(data: any): void {
        data.weaponCells = this.__weaponCells;
        if(this.currentWeaponCell!=null){
            data.currentWeaponCellId = this.currentWeaponCell.cellId;
        }else{
            data.currentWeaponCellId=-1;
        }
        //自动合成Buffer剩余时间
        let buffers: IBuffer[] = BufferManager.GetBufferGroup("AutoSynthesis");
        if (buffers != null && buffers.length > 0) {
            let buffer: IBuffer = buffers[0];
            data.autoSynthesisTime = buffer.GetTimeRemaining();
        } else {
            data.autoSynthesisTime = 0;
        }
        //加速Buffer
        buffers = BufferManager.GetBufferGroup("Accelerate");
        if (buffers != null && buffers.length > 0) {
            let accelerateBuffer: AccelerateBuffer = buffers[0] as AccelerateBuffer;
            data.accelerateTime = accelerateBuffer.GetTimeRemaining();
        } else {
            data.accelerateTime = 0;
        }
    }

    /**
     * 领取记录
     */
    get signGetRecord():number[]{
        return this.GetProperty(GamePropertys.signGetRecord);
    }

    set signGetRecord(value:number[]){
        this.SetProperty(GamePropertys.signGetRecord,value);
    }

    /**
     * 自动领取奖励
     */
    AutoSignAward():void{
        let index:number=this.GetSignAwardIndex();
        this.GetSignAward(index+1);
    }

    /**
     * 领取奖励
     * @param day 1-7
     */
    private GetSignAward(day:number):void{
        if(day<1||day>7){
            throw new Error("7日索引范围必须在1-7");
        }
        let state:number=this.GetSignAwardByDay(day);
        if(state>0){
            throw new Error("重复领取")
        }
        let list:number[]=this.signGetRecord;
        list[day-1]=1;
        this.DispatchEvent(DataModelEventType.PROPERTY_CHANGED,GamePropertys.signGetRecord);
        //发放奖励
        let config:any=GameConfigManager.GetSignConfig(day);
        //0.金币 1.钻石 2.枪 3.栅栏
        switch (config.type) {
            case 0:
                this.gold+=config.number;
                NoticeManager.ShowPrompt("金币+"+config.number);
                break;
            case 1:
                this.diamond+=config.number;
                NoticeManager.ShowPrompt("钻石+"+config.number);
                break;
            case 2:
                let cell:WeaponCell=this.FindWeaponEmptyCell();
                if(cell!=null){
                    this.AddWeapon(cell.cellId,config.number);
                }
                break;
            case 3:
                this.currentFenceId=config.number;
                break;
        }
    }

    /**
     * 获取7日登录领取状态
     * @param day  1-7
     */
    GetSignAwardByDay(day:number):number{
        if(day>7){
            throw new Error("超出7天")
        }
        return this.signGetRecord[day-1];
    }

    /**
     * 获取领取奖励的天数索引
     */
    GetSignAwardIndex():number{
        for (let index = 0; index < this.signDay; index++) {
            if(this.GetSignAwardByDay(index+1)==0){
                let config:any=GameConfigManager.GetSignConfig(index+1);
                //0.金币 1.钻石 2.枪 3.栅栏
                switch (config.type) {
                    case 2:
                        if(this.WeaponEmptyCellCount>0){
                            return index;
                        }else{
                            NoticeManager.ShowPrompt("武器槽没有空位了！");
                        }
                        break;
                    default:
                        return index;
                }
            }
        }
        return -1;
    }

    private static instance: GameModel;
    public static get single(): GameModel {
        if (this.instance == null) {
            this.instance = new GameModel();
        }
        return this.instance;
    }

    /**
     * 自动合成Buffer剩余时间
     */
    get autoSynthesisTime(): number {
        return this.GetProperty(GamePropertys.autoSynthesisTime);
    }

    /**
     * 加速Buffer剩余时间
     */
    get accelerateTime(): number {
        return this.GetProperty(GamePropertys.accelerateTime);
    }

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

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

    /**
     * 试用栅栏ID
     */
    trialFenceId: number = -1;

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

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

    /**
     * 栅栏ID （包括试用）
     */
    get fenceId(): number {
        if (this.trialFenceId > 0) {
            return this.trialFenceId;
        }
        return this.currentFenceId;
    }

    /**
     * 金币
     */
    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);
    }

    /**
     * 登录天数
     */
    get signDay():number{
        return this.GetProperty(GamePropertys.signDay);
    }

    /**
     * 登录天数
     */
    set signDay(value:number){
        this.SetProperty(GamePropertys.signDay,value);
    }

    /**
     * 上次登录日期
     */
    get lastSignTime():number{
        return this.GetProperty(GamePropertys.lastSignTime);
    }

    /**
     * 登录天数
     */
    set lastSignTime(value:number){
        this.SetProperty(GamePropertys.lastSignTime,value);
    }
}