import { Application, BackendSession, ChannelService, HandlerService } from "pinus";
import { GVG_ACTIVE_TYPE, GVG_ITEM, GVG_ITEM_TYPE, GVG_PERIOD, GVG_RESOURCE_TYPE, ITEM_CHANGE_REASON, MAIL_TYPE, STATUS, TASK_TYPE } from "../../../consts";
import { GVGLeagueModel } from "../../../db/GVGLeague";
import { GVGLeagueFarmModel, GVGLeagueFarmType } from "../../../db/GVGLeagueFarm";
import { GVGLeagueFarmRecModel } from "../../../db/GVGLeagueFarmRec";
import { GVGLeaguePrepareModel } from "../../../db/GVGLeaguePrepare";
import { GVGUserItemModel } from "../../../db/GVGUserItem";
import { RoleModel } from "../../../db/Role";
import { LeagueFarmListInfo, LeagueFarmMember, LeagueField } from "../../../domain/gvgField/returnData";
import { gameData, getGVGResourceBasesByType } from "../../../pubUtils/data";
import { ItemInter, RewardInter } from "../../../pubUtils/interface";
import { nowSeconds } from "../../../pubUtils/timeUtil";
import { resResult } from "../../../pubUtils/util";
import { getGVGCities } from "../../../services/gvg/gvgBattleService";
import { addGVGReward, getProduceCoinCnt, handleGVGCost } from "../../../services/gvg/gvgItemService";
import { addGVGActive, addResource, getCostSeedReward, getItemIdOfSeedType, getLeagueFarmShowResult, getLockFieldCnt, getmyContributeRank, rollbackUnPlantFields, lockField, calFarmOutput, sumOutputByResults, lockMineOrForestry, calMineOutput, calForestryOutput, checkItemCanUserInFarm } from "../../../services/gvg/gvgPrepareService";
import { getGVGConfig, getGVGPeriodData } from "../../../services/gvg/gvgService";
import { sendMailByContent } from "../../../services/mailService";
import { getAllServerName, getRoleOnlineInfo } from "../../../services/redisService";
import { checkGVGTask } from "../../../services/task/taskService";


export default function (app: Application) {
    new HandlerService(app, {});
    return new GVGProduceHandler(app);
}

export class GVGProduceHandler {
    channelService: ChannelService;
    constructor(private app: Application) {
        this.channelService = app.get('channelService');
    }

    // 内政令兑换
    async exchangeItem(msg: { id: number, count: number }, session: BackendSession) {
        const roleId = session.get('roleId');
        const roleName = session.get('roleName');
        const sid = session.get('sid');
        const guildCode = session.get('guildCode');
        const { id, count } = msg;

        const dicGVGItem = gameData.gvgItem.get(id);
        if(!dicGVGItem) return resResult(STATUS.DIC_DATA_NOT_FOUND);
        if(dicGVGItem.type != GVG_ITEM_TYPE.SEED && dicGVGItem.type != GVG_ITEM_TYPE.SCOOP && dicGVGItem.type != GVG_ITEM_TYPE.AXE) {
            return resResult(STATUS.GVG_ITEMS_NOT_PRODUCE);
        }

        const myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        const leagueItems = dicGVGItem.leagueConsume.map(cur => ({ id: cur.id, count: cur.count * count }));
        const items = dicGVGItem.consume.map(cur => ({ id: cur.id, count: cur.count * count }));

        const costResult = await handleGVGCost(roleId, myLeague.leagueCode, sid, leagueItems, items, ITEM_CHANGE_REASON.GVG_EXCHANGE_SEEDS);
        if(!costResult) return resResult(STATUS.GVG_ITEMS_NOT_ENOUGH);

        const leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, [{ id, count }], [], ITEM_CHANGE_REASON.GVG_EXCHANGE_SEEDS);

        return resResult(STATUS.SUCCESS, {
            leagueGoods
        });
    }

    // 获取农场/矿山/林场状态
    async getProduceList(msg: { type: number }, session: BackendSession) {
        const roleId = session.get('roleId');
        const guildCode = session.get('guildCode');

        const { type } = msg;

        let { configId, period } = getGVGPeriodData();
        if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
        const leagueLv = leaguePrepare?.lv||0;

        const leagueFarms = await GVGLeagueFarmModel.findByType(configId, myLeague.leagueCode, type);

        const dicFarms = getGVGResourceBasesByType(type);
        const result: LeagueFarmListInfo[] = [];
        for(let { id, lv, type } of dicFarms) {
            if(lv > leagueLv) continue;
            const leagueFarm = leagueFarms.filter(cur => cur.farmId == id && cur.unlockTime >= nowSeconds()); // 已种植单位
            const canHarvestFarms = leagueFarms.filter(cur => type == GVG_RESOURCE_TYPE.FOOD && cur.farmId == id && cur.harvestTime > 0 && cur.harvestTime <= nowSeconds());
            let obj = new LeagueFarmListInfo(id, leagueFarm.length, canHarvestFarms.length > 0);
            result.push(obj);
        }

        return resResult(STATUS.SUCCESS, {
            type,
            list: result
        });
    }

    // 不能进的农场，获取其他人的状态
    async getOtherFarms(msg: { farmId: number }, session: BackendSession) {
        const roleId = session.get('roleId');
        const guildCode = session.get('guildCode');
        const { farmId } = msg;

        let { configId, period } = getGVGPeriodData();
        if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        const fields = await GVGLeagueFarmModel.findPlantedByFarmId(configId, myLeague.leagueCode, farmId);
        const roleIds: string[] = [], fieldByRoleId = new Map<string, GVGLeagueFarmType[]>();
        for(let field of fields) {
            if(roleIds.indexOf(field.lockRoleId) == -1) {
                roleIds.push(field.lockRoleId);
                fieldByRoleId.set(field.lockRoleId, []);
            }
            fieldByRoleId.get(field.lockRoleId).push(field);
        } 

        const serverNames = await getAllServerName();
        const roles = await RoleModel.findByRoleIds(roleIds);
        const result: LeagueFarmMember[] = [];
        for(let role of roles) {
            let obj = new LeagueFarmMember(role, serverNames);
            let myFields = fieldByRoleId.get(role.roleId)||[]
            obj.setByFields(myFields);
            result.push(obj);
        }

        return resResult(STATUS.SUCCESS, {
            ...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId, false),
            members: result
        });
    }

    // 小游戏界面
    async getMyFarm(msg: { farmId: number }, session: BackendSession) {
        const roleId = session.get('roleId');
        const roleName = session.get('roleName');
        const guildCode = session.get('guildCode');

        const { farmId } = msg;

        let { period } = getGVGPeriodData();
        if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
   
        let dicResource = gameData.gvgResource.get(farmId);
        if(dicResource.type == GVG_RESOURCE_TYPE.FOOD) {
            await lockField(myLeague.leagueCode, roleId, roleName, farmId);
        }
        const myRank = await getmyContributeRank(myLeague.leagueCode, myLeague.members, roleId);

        return resResult(STATUS.SUCCESS, {
            ...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId),
            myRank,
        });
    }

    // 种田
    async plant(msg: { farmId: number, seeds: { fieldId: number, seedType: number, index: number }[] }, session: BackendSession) {
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');
        const guildCode = session.get('guildCode');
        const sid = session.get('sid');

        const { farmId, seeds } = msg;
        let { configId, period } = getGVGPeriodData();
        if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        const fields = await GVGLeagueFarmModel.findByFieldIds(configId, myLeague.leagueCode, farmId, seeds.map(({fieldId}) => fieldId));
        for(let field of fields) {
            if(!field) return resResult(STATUS.GVG_FIELD_NOT_FOUND);
            if(field.lockRoleId != roleId && field.unlockTime > nowSeconds()) return resResult(STATUS.GVG_FIELD_HAS_LOCKED);
            if(field.lockRoleId == roleId && field.harvestTime > 0) return resResult(STATUS.GVG_FIELD_HAS_PLANT);
        }

        const cities = await getGVGCities(myLeague);
        const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);

        const cost: RewardInter[] = [], updateFields: { fieldId: number, seedType: number, index: number, time: number, output: number, outputStr: string }[] = [];
        for(let { fieldId, seedType, index } of seeds) {
            let itemId = getItemIdOfSeedType(seedType);
            let dicItem = gameData.gvgItem.get(itemId);
            let field = fields.find(cur => cur.fieldId == fieldId);
            if(!field) continue;
            let output = calFarmOutput(seedType, field.addType, farmId, cities, leaguePrepare?.activeTech||[]);
            updateFields.push({ fieldId, seedType, index, time: dicItem.ripeTime, ...output });
            // 算消耗的种子
            let costObj = cost.find(({ id }) => id == itemId);
            costObj? costObj.count++: cost.push({ id: itemId, count: 1 });
        }
        const costResult = await handleGVGCost(roleId, myLeague.leagueCode, sid, cost, [], ITEM_CHANGE_REASON.PLANT)
        if(!costResult) return resResult(STATUS.GVG_ITEMS_NOT_ENOUGH);

        const plantResult = await GVGLeagueFarmModel.plant(configId, myLeague.leagueCode, farmId, updateFields, roleId);
        await rollbackUnPlantFields(cost, plantResult, session, myLeague.leagueCode);  // 可能会有田已经被其他人占领的情况，将种子还回去
        await GVGLeagueFarmRecModel.insertRecs(GVG_RESOURCE_TYPE.FOOD, plantResult);
        checkGVGTask(serverId, roleId, sid, configId, myLeague.leagueCode, TASK_TYPE.GVG_FARM, { count: 1 });

        return resResult(STATUS.SUCCESS, {
            ...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId)
        });
    }

    // 收获
    async harvest(msg: { farmId: number, fieldIds: number[] }, session: BackendSession) {
        const roleId = session.get('roleId');
        const roleName = session.get('roleName');
        const sid = session.get('sid');
        const guildCode = session.get('guildCode');

        const { farmId, fieldIds } = msg;
        let { configId, period } = getGVGPeriodData();
        if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        const myResultFields = await GVGLeagueFarmModel.harvest(configId, myLeague.leagueCode, farmId, fieldIds, roleId); // 解锁
        if(myResultFields.length <= 0) return resResult(STATUS.GVG_CANNOT_HARVEST);
        // 计算产量
        const { foodSum, rewardSum, leagueRewardSum, activeSum } = await sumOutputByResults(myResultFields);
        // 资源
        let resourceResult = await addResource(myLeague, roleId, roleName, GVG_RESOURCE_TYPE.FOOD, foodSum)||{};
        // 相关物品
        let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueRewardSum, rewardSum, ITEM_CHANGE_REASON.HARVEST)
        // 活跃
        const active = await addGVGActive(myLeague.leagueCode, roleId, GVG_ACTIVE_TYPE.COST_PRODUCE_COIN, activeSum);
        // 收获后再次预锁定一批田
        // await lockField(myLeague.leagueCode, roleId, roleName, farmId);
        await GVGLeagueFarmRecModel.updateRecs(myResultFields, roleId);
        const myRank = await getmyContributeRank(myLeague.leagueCode, myLeague.members, roleId);

        return resResult(STATUS.SUCCESS, {
            myRank,
            ...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId),
            leagueGoods,
            active,
            ...resourceResult
        });
    }

    // 关闭页面
    async plantEnd(msg: { farmId: number }, session: BackendSession) {
        const roleId = session.get('roleId');
        const guildCode = session.get('guildCode');

        const { farmId } = msg;
        let { configId } = getGVGConfig();

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
        await GVGLeagueFarmModel.releaseLock(configId, myLeague.leagueCode, farmId, roleId);

        return resResult(STATUS.SUCCESS, {
            ...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId),
        });
    }

    // 帮收
    async helpHarvest(msg: { farmId: number, roleId: string }, session: BackendSession) {
        const roleId = session.get('roleId');
        const roleName = session.get('roleName');
        const guildCode = session.get('guildCode');

        const { farmId, roleId: targetRoleId } = msg;
        let { configId, period } = getGVGPeriodData();
        if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        const resultField = await GVGLeagueFarmModel.helpHarvest(configId, myLeague.leagueCode, farmId, targetRoleId); // 解锁
        if(!resultField || resultField.length == 0) return resResult(STATUS.GVG_CANNOT_HARVEST);

        let targetOnlineInfo = await getRoleOnlineInfo(targetRoleId);

        // 计算产量
        const { foodSum, rewardSum, leagueRewardSum, activeSum } = await sumOutputByResults(resultField);
        // 资源
        await addResource(myLeague, targetRoleId, resultField[0].lockRoleName, GVG_RESOURCE_TYPE.FOOD, foodSum)||{};
        await sendMailByContent(MAIL_TYPE.HELP_HARVEST, targetRoleId, { sendName: roleName, goods: rewardSum });
        // 相关物品
        await addGVGReward(targetRoleId, roleName, myLeague.leagueCode, targetOnlineInfo.sid, leagueRewardSum, [], ITEM_CHANGE_REASON.HARVEST)
        // 活跃
        await addGVGActive(myLeague.leagueCode, targetRoleId, GVG_ACTIVE_TYPE.COST_PRODUCE_COIN, activeSum);

        return resResult(STATUS.SUCCESS, {
            ...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId),
        });
    }

    // 进入矿山
    async mineStart(msg: { farmId: number, itemId: number }, session: BackendSession) {
        const roleId = session.get('roleId');
        const guildCode = session.get('guildCode');

        const { farmId, itemId } = msg;
        if(!checkItemCanUserInFarm(farmId, itemId)) return resResult(STATUS.GVG_ITEM_CANNOT_USE);

        let { configId, period } = getGVGPeriodData();
        if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        const hasItem = await GVGUserItemModel.checkItemCnt(configId, myLeague.leagueCode, roleId, itemId, 1);
        if(!hasItem) return resResult(STATUS.GVG_ITEMS_NOT_ENOUGH);

        const lockResult = await lockMineOrForestry(myLeague.leagueCode, roleId, farmId, itemId);
        if(!lockResult) return resResult(STATUS.GVG_MINE_HAS_LOCKED);
        const myRank = await getmyContributeRank(myLeague.leagueCode, myLeague.members, roleId);

        return resResult(STATUS.SUCCESS, {
            ...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId, false),
            myRank,
            fieldId: lockResult.fieldId,
            unlockTime: lockResult.unlockTime
        });
    }

    // 结算矿场
    async mineEnd(msg: { farmId: number, fieldId: number, result: [{ type: number, count: number }] }, session: BackendSession) {
        const roleId = session.get('roleId');
        const roleName = session.get('roleName');
        const guildCode = session.get('guildCode');
        const sid = session.get('sid');
        const serverId = session.get('serverId');

        const { farmId, fieldId, result } = msg;
        let { configId, period } = getGVGPeriodData();
        if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        // 检查数据是否上传争取
        let dicMine = gameData.gvgResource.get(farmId);
        if(!dicMine) return resResult(STATUS.DIC_DATA_NOT_FOUND);
        let mineralSum = 0;
        for(let { type, count } of result) {
            let max = dicMine.mineralValue.find(cur => cur.type == type)?.count||0;
            if(count > max) return resResult(STATUS.GVG_MINERAL_COUNT_OVER);
            mineralSum += count;
        }

        const field = await GVGLeagueFarmModel.findByField(configId, myLeague.leagueCode, farmId, fieldId);
        if(!field || field.lockRoleId != roleId) return resResult(STATUS.GVG_MINE_HAS_OVER);
        if(!!field.harvestTime) return resResult(STATUS.GVG_MINE_HAS_HARVEST);
        let dicGVGItem = gameData.gvgItem.get(field.itemId);
        if(mineralSum > (dicGVGItem?.value||0)) return resResult(STATUS.GVG_MINE_SCOOP_OVER);

        // 扣铲子
        const costResult = await handleGVGCost(roleId, myLeague.leagueCode, sid, [{ id: field.itemId, count: 1 }], [], ITEM_CHANGE_REASON.MINE_END);
        if(!costResult) return resResult(STATUS.GVG_ITEMS_NOT_ENOUGH);

        // 计算资源
        const cities = await getGVGCities(myLeague);
        const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
        const { output, outputStr } = calMineOutput(farmId, result, cities, leaguePrepare?.activeTech||[]);
        // 挖完
        await GVGLeagueFarmModel.mineOrForestryEnd(configId, myLeague.leagueCode, farmId, roleId, fieldId, output, outputStr);
        // 计算产量
        let {  reward, leagueReward, leagueConsume } = dicGVGItem;
        let produceCoin = getProduceCoinCnt(leagueConsume);
        // 资源
        let resourceResult = await addResource(myLeague, roleId, roleName, GVG_RESOURCE_TYPE.MINERAL, output)||{};
        // 相关物品
        let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueReward, reward, ITEM_CHANGE_REASON.HARVEST)
        // 活跃
        const active = await addGVGActive(myLeague.leagueCode, roleId, GVG_ACTIVE_TYPE.COST_PRODUCE_COIN, produceCoin);
        checkGVGTask(serverId, roleId, sid, configId, myLeague.leagueCode, TASK_TYPE.GVG_FARM, { count: 1 });
        const myRank = await getmyContributeRank(myLeague.leagueCode, myLeague.members, roleId);

        return resResult(STATUS.SUCCESS, {
            myRank,
            ...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId, false),
            ...resourceResult,
            leagueGoods,
            active
        });
    }

    // 不能进的矿山，获取其他人的状态
    async getOtherMines(msg: { farmId: number }, session: BackendSession) {
        const roleId = session.get('roleId');
        const guildCode = session.get('guildCode');
        const { farmId } = msg;

        let { configId, period } = getGVGPeriodData();
        if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        const fields = await GVGLeagueFarmModel.findLockedByFarmId(configId, myLeague.leagueCode, farmId);
        const roleIds: string[] = [], fieldByRoleId = new Map<string, GVGLeagueFarmType[]>();
        for(let field of fields) {
            if(roleIds.indexOf(field.lockRoleId) == -1) {
                roleIds.push(field.lockRoleId);
                fieldByRoleId.set(field.lockRoleId, []);
            }
            fieldByRoleId.get(field.lockRoleId).push(field);
        } 

        const serverNames = await getAllServerName();
        const roles = await RoleModel.findByRoleIds(roleIds);
        const result: LeagueFarmMember[] = [];
        for(let role of roles) {
            let obj = new LeagueFarmMember(role, serverNames);
            let myFields = fieldByRoleId.get(role.roleId)||[]
            obj.setByMines(myFields);
            result.push(obj);
        }

        return resResult(STATUS.SUCCESS, {
            ...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId, false),
            members: result
        });
    }

    // 进入林场
    async forestryStart(msg: { farmId: number, itemId: number }, session: BackendSession) {
        const roleId = session.get('roleId');
        const guildCode = session.get('guildCode');

        const { farmId, itemId } = msg;
        if(!checkItemCanUserInFarm(farmId, itemId)) return resResult(STATUS.GVG_ITEM_CANNOT_USE);

        let { configId, period } = getGVGPeriodData();
        if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        const hasItem = await GVGUserItemModel.checkItemCnt(configId, myLeague.leagueCode, roleId, itemId, 1);
        if(!hasItem) return resResult(STATUS.GVG_ITEMS_NOT_ENOUGH);

        const lockResult = await lockMineOrForestry(myLeague.leagueCode, roleId, farmId, itemId);
        if(!lockResult) return resResult(STATUS.GVG_MINE_HAS_LOCKED);
        const myRank = await getmyContributeRank(myLeague.leagueCode, myLeague.members, roleId);

        return resResult(STATUS.SUCCESS, {
            ...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId, false),
            myRank,
            fieldId: lockResult.fieldId,
            unlockTime: lockResult.unlockTime
        });
    }

    // 林场结算
    async forestryEnd(msg: { farmId: number, fieldId: number, result: number }, session: BackendSession) {
        const roleId = session.get('roleId');
        const roleName = session.get('roleName');
        const guildCode = session.get('guildCode');
        const sid = session.get('sid');
        const serverId = session.get('serverId');

        const { farmId, fieldId, result } = msg;
        let { configId, period } = getGVGPeriodData();
        if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        // 检查数据是否上传争取
        let dicForestry = gameData.gvgResource.get(farmId);
        if(!dicForestry) return resResult(STATUS.DIC_DATA_NOT_FOUND);

        const field = await GVGLeagueFarmModel.findByField(configId, myLeague.leagueCode, farmId, fieldId);
        if(!field || field.lockRoleId != roleId) return resResult(STATUS.GVG_FORESTRY_HAS_OVER);
        if(!!field.harvestTime) return resResult(STATUS.GVG_FORESTRY_HAS_HARVEST);
        let dicGVGItem = gameData.gvgItem.get(field.itemId);
        if(result > (dicGVGItem?.value||0)) return resResult(STATUS.GVG_MINE_SCOOP_OVER);

        // 扣斧头
        const costResult = await handleGVGCost(roleId, myLeague.leagueCode, sid, [{ id: field.itemId, count: 1 }], [], ITEM_CHANGE_REASON.MINE_END);
        if(!costResult) return resResult(STATUS.GVG_ITEMS_NOT_ENOUGH);

        // 计算资源
        const cities = await getGVGCities(myLeague);
        const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
        const { output, outputStr } = calForestryOutput(farmId, result, cities, leaguePrepare?.activeTech||[]);
        // 挖完
        await GVGLeagueFarmModel.mineOrForestryEnd(configId, myLeague.leagueCode, farmId, roleId, fieldId, output, outputStr);
        // 计算产量
        let {  reward, leagueReward, leagueConsume } = dicGVGItem;
        let produceCoin = getProduceCoinCnt(leagueConsume);
        // 资源
        let resourceResult = await addResource(myLeague, roleId, roleName, GVG_RESOURCE_TYPE.WOOD, output)||{};
        // 相关物品
        let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueReward, reward, ITEM_CHANGE_REASON.HARVEST)
        // 活跃
        const active = await addGVGActive(myLeague.leagueCode, roleId, GVG_ACTIVE_TYPE.COST_PRODUCE_COIN, produceCoin);
        checkGVGTask(serverId, roleId, sid, configId, myLeague.leagueCode, TASK_TYPE.GVG_FARM, { count: 1 });
        const myRank = await getmyContributeRank(myLeague.leagueCode, myLeague.members, roleId);

        return resResult(STATUS.SUCCESS, {
            myRank,
            ...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId, false),
            ...resourceResult,
            leagueGoods,
            active
        });
    }

    // 获取资源
    async debugAddResource(msg: { type: number, count: number }, session: BackendSession) {
        const roleId = session.get('roleId');
        const roleName = session.get('roleName');
        const guildCode = session.get('guildCode');
        const { type, count } = msg;

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        let resourceResult = await addResource(myLeague, roleId, roleName, type, count);
        if(!resourceResult) return resResult(STATUS.WRONG_PARMS);

        return resResult(STATUS.SUCCESS, resourceResult);
    }

    // 设置农田的收获时间
    async debugAdjustHarvest(msg: { time: number }, session: BackendSession) {
        const guildCode = session.get('guildCode');
        const { time } = msg;

        let { configId } = getGVGPeriodData();
        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        await GVGLeagueFarmModel.setMyHarvestTime(configId, myLeague.leagueCode, time);

        return resResult(STATUS.SUCCESS);
    }
}