import GameDataCenter from "../../GameDataCenter";
import { GridMapModelData } from "./GridMapModelData";
import { ReqHcMerge } from "../../../shared/hc/PtlHcMerge";
import EventMng from "../../../manager/EventMng";
import { GridEvent } from "../../../logic/gridMap/GridEvent";
import { HcType, HcUnlock, ReqHcInfo } from "../../../shared/hc/PtlHcInfo";
import Gamecfg from "../../../common/gameCfg";
import UECell from "../../../logic/gridMap/UECell";
import UEGridMap from "../../../logic/gridMap/UEGridMap";
import { gameMethod } from "../../../common/gameMethod";
import UECube from "../../../logic/gridMap/UECube";
import { ReqHcEmit } from "../../../shared/hc/PtlHcEmit";
import { GridConstant } from "../../../logic/gridMap/GridConstant";
import Config from "../../../Config";

/** 合成物品数据 */
export interface MergeItem {
    type: number,
    id: number,
    rate: number
}

export default class GridMapModel extends GridMapModelData {
    /** 配方可合成的物品 */
    public formulaMap: { [key: string]: MergeItem[] } = {};
    /** 可合成物品的配方 */
    public itemFormula: { [key: string]: string[] } = {};
    private ueGridMap: UEGridMap;
    constructor() {
        super('gridMap');
    }

    protected onRegister(): void {


    }

    Init(ueGridMap: UEGridMap) {
        this.ueGridMap = ueGridMap;
        this.FilterMergeChain();

    }

    /** 过滤合成链 */
    FilterMergeChain() {
        this.formulaMap = {};
        this.itemFormula = {};
        for (let key in Gamecfg.mergeInfo.pool) {
            let item = Gamecfg.mergeInfo.pool[key];
            let formulaKey1 = `${item.formula[0]}_${item.formula[1]}_${item.formula[2]}_${item.formula[3]}`;
            let formulaKey2 = `${item.formula[2]}_${item.formula[3]}_${item.formula[0]}_${item.formula[1]}`;

            this.formulaMap[formulaKey1] = [];
            this.formulaMap[formulaKey2] = [];
            for (let idx = 1; idx <= 4; idx++) {
                let mergeItem = item[`item${idx}`];
                let mergeItemRate = item[`rate${idx}`];
                if (mergeItem) {
                    this.formulaMap[formulaKey1].push({ type: mergeItem[0], id: mergeItem[1], rate: mergeItemRate });
                    this.formulaMap[formulaKey2].push({ type: mergeItem[0], id: mergeItem[1], rate: mergeItemRate });
                    if (!this.itemFormula[`${mergeItem[0]}_${mergeItem[1]}`]) {
                        this.itemFormula[`${mergeItem[0]}_${mergeItem[1]}`] = [];
                    }
                    this.itemFormula[`${mergeItem[0]}_${mergeItem[1]}`].push(formulaKey1);
                }
            }
        }
    }


    /** 请求棋盘信息 */
    async sendHcInfo(param: ReqHcInfo) {
        let ret = await GameDataCenter.gameServer.ReqApi("hc/HcInfo", param);
        if (ret?.res) {
            this.hcInfo = ret.res;
            EventMng.emit(GridEvent.HC_INFO_RSP, ret.res);
            EventMng.emit(GridEvent.HC_SP_UP);
        }
    }


    // 请求合成
    async sendHcMerge(param: ReqHcMerge) {
        let ret = await GameDataCenter.gameServer.ReqApi("hc/HcMerge", param);
        return ret;
    }

    async sendEmitter(gzid: number) {
        let ret = await GameDataCenter.gameServer.ReqApi("hc/HcEmit", { gzid: gzid.toString() });
        if (ret?.res) {
            for (let key in ret.res) {
                EventMng.emit(GridEvent.TRIGGER_EMITTER, { idx: gzid, targetIdx: Number(key), item: ret.res[key] });
            }
        }

    }

    /** 请求格子战斗 */
    async sendFightHc(gzid: number) {
        let ret = await GameDataCenter.gameServer.ReqApi("fight/FightHc", { gzid: gzid.toString() });
        if (ret?.res) {
            GameDataCenter.battle.startFight(ret.res, () => {
                if (ret.res.win) {
                    EventMng.emit(GridEvent.HC_FIGHT_OVER, { gzid: gzid, list: ret.res.list });
                }
            });
        }
    }
    /** 请求格子战斗 */
    async sendHcSell(gzid: number) {
        let ret = await GameDataCenter.gameServer.ReqApi("hc/HcSell", { gzid: gzid.toString() });
        if (ret?.res) {
            for (let key in ret.res.list) {
                EventMng.emit(GridEvent.HC_CELL_CHANGE, { idx: Number(key), item: ret.res.list[key] });
            }
            EventMng.emit(GridEvent.HC_MERGE_SELL, { isShow: false });
            EventMng.emit(GridEvent.HC_CELL_SELECT, 0);
        }
    }

    /** 尝试合成 */
    public async TryMergeItems(fromCell: UECell, toCell: UECell) {
        //检测目标格子物品是否可以拖动
        if (toCell.IsEmpty() || toCell.GetCube().CanDrag()) {
            let ret = await this.sendHcMerge({ gzid1: fromCell.GetZIndex().toString(), gzid2: toCell.GetZIndex().toString() })
            if (ret && ret.res) {
                let fCube = ret.res?.list[fromCell.GetZIndex()];
                let tCube = ret.res.list[toCell.GetZIndex()];
                if (toCell.IsEmpty()) {
                    //格子上没有物品
                    fromCell.MoveCubeToCell(toCell);
                    toCell.SetCube(fromCell.GetCube());
                    fromCell.SetCube(null);
                } else if (this.CanMergeItems(fromCell, toCell)) {
                    toCell.GetCube().PlayMergeAnim();
                    fromCell.ClearCube();
                    toCell.ClearCube();
                    EventMng.emit(GridEvent.HC_MERGE_RSP, { cell: toCell, cube: tCube });
                } else {
                    this.SwitchCell(fromCell, toCell);
                }
            }

        } else {
            //回到原来位置
            fromCell.GetCube().BackToOriginalPos(true);
        }

    }

    /** 交换格子 */
    private SwitchCell(fromCell: UECell, toCell: UECell): void {
        let fromCube = fromCell.GetCube();
        let toCube = toCell.GetCube();
        fromCell.SetCube(toCube);
        toCell.SetCube(fromCube);
        toCube.MoveToNewPos(cc.v3(fromCell.node.x, fromCell.node.y));
        fromCube.MoveToNewPos(cc.v3(toCell.node.x, toCell.node.y), 0.05);
    }


    /** 将索引转换为位置 */
    public TranIdxToPos(idx: number): cc.Vec2 {
        let row = idx % 10;
        let col = Math.floor(idx / 10);
        return cc.v2(row - 1, col - 1);
    }

    /** 根据索引获取实际像素坐标 */
    public GetPosByIdx(idx: number): cc.Vec3 {
        let vec = this.TranIdxToPos(idx);
        const startX = -(GridConstant.ROW * GridConstant.CELL_WIDTH) / 2;
        const startY = (GridConstant.COL * GridConstant.CELL_WIDTH) / 2;
        return cc.v3(
            startX + vec.x * GridConstant.CELL_WIDTH + GridConstant.CELL_WIDTH / 2,
            startY - vec.y * GridConstant.CELL_WIDTH - GridConstant.CELL_WIDTH / 2
        )
    }

    /** 根据xy获取实际像素坐标 */
    public GetPosByVec(i: number, j: number): cc.Vec3 {
        const startX = -(GridConstant.ROW * GridConstant.CELL_WIDTH) / 2;
        const startY = (GridConstant.COL * GridConstant.CELL_WIDTH) / 2;
        return cc.v3(
            startX + j * GridConstant.CELL_WIDTH + GridConstant.CELL_WIDTH / 2,
            startY - i * GridConstant.CELL_WIDTH - GridConstant.CELL_WIDTH / 2
        )
    }


    /** 检测目标格子是否可以放置&合成&交换物品 */
    public CellCanPut(fromCell: UECell, toCell: UECell): boolean {
        //目标格子是空格子
        if (toCell.IsEmpty()) {
            return true;
        }
        //检测目标格子物品是否可以拖动
        if (toCell.GetCube().CanDrag()) {
            return true;
        }

        //目标位置是物品，但是可以合成
        if (this.CanMergeItems(fromCell, toCell)) {
            return true;
        }

        return false;
    }

    /** 是否可以合成 */
    private CanMergeItems(fromCell: UECell, toCell: UECell): boolean {
        let formulaKey = `${fromCell.GetCube().GetCubeData().type}_${fromCell.GetCube().GetCubeData().id}_${toCell.GetCube().GetCubeData().type}_${toCell.GetCube().GetCubeData().id}`;
        let mergeArr = this.formulaMap[formulaKey];
        if (gameMethod.isEmpty(mergeArr)) {
            return false;
        }
        return true;
    }

    /** 获取可合成的物品集 */
    public GetMergeItems(cube1: UECube, cube2: UECube) {
        let formulaKey = `${cube1.GetCubeData().type}_${cube1.GetCubeData().id}_${cube2.GetCubeData().type}_${cube2.GetCubeData().id}`;
        let mergeArr = this.formulaMap[formulaKey];
        return mergeArr || [];
    }


}