// 军团活动蛮夷入侵城门血量等数据存储

import { GUILD_ACTIVITY_STATUS } from "../../consts";
import { Member } from "../../domain/battleField/guildActivity";
import { getCityActivityGateHp } from "./guildActivityService";

// 军团诸侯混战等数据
export class CityActivityObject {
    public guildActivityStatus = GUILD_ACTIVITY_STATUS.WAITING; // 活动状态 0-未开始 1-已开始 2-已结束 
    private gateHp: Map<string, number> = new Map(); // 城门血条，每个cityId有一条血条 serverId&cityId => gateHp
    private maxHp: Map<string, number> = new Map(); // 城门血条，每个cityId最大城门血量 serverId&cityId => gateHp
    private members: Map<string, Array<Member>> = new Map(); // 每个军团参与的成员 guildCode => [{roleId, job}]
    private cities: Map<string, string[]> = new Map(); // 各个城池参与的军团 serverId&cityId => [guildCode]
    private guilds: Map<string, number> = new Map();  // 军团所在的城池 guildCode => cityId
    private sentCity: string[] = [];
    private startTime: number = 0;

    private getKey(serverId: number, cityId: number) {
        return `${serverId}_${cityId}`;
    }

    private decodeKey(key: string) {
        let arr = key.split('_');
        return {
            serverId: parseInt(arr[0]),
            cityId: parseInt(arr[1])
        }
    }

    public getObj( serverId: number, cityId: number, guildCode: string) {
        let key = this.getKey(serverId, cityId);
        return {
            gateHp: this.gateHp.get(key),
            maxHp: this.maxHp.get(key),
            members: this.members.get(guildCode),
            city: this.cities.get(key),
            guild: this.guilds.get(guildCode)
        }
    }

    public startActivity() {
        this.startTime = Date.now();
        this.guildActivityStatus = GUILD_ACTIVITY_STATUS.START;
    }

    public endActivity() {
        this.guildActivityStatus = GUILD_ACTIVITY_STATUS.END;
    }

    public getTimeGap() {
        return Math.floor((Date.now() - this.startTime)/1000);
    }

    public lockCity(serverId: number, cityId: number) {
        if(this.hasSent(serverId, cityId)) return false;
        this.unlockCity(serverId, cityId);
        return true;
    }

    private unlockCity(serverId: number, cityId: number) {
        let key = this.getKey(serverId, cityId);
        // let guildCodes = this.cities.get(key)||[];
        // for(let guildCode of guildCodes) {
        //     this.members.delete(guildCode);
        //     this.guilds.delete(guildCode);
        // }
        // this.cities.delete(key);
        this.sentCity.push(key);
    }

    public hasSent(serverId: number, cityId: number) {
        let key = this.getKey(serverId, cityId);
        return this.sentCity.indexOf(key) != -1;
    }

    public getAllCities() {
        let allCities = new Array<{ serverId: number, cityId: number, guildCodes: string[]}>();
        let serverlists = new Array<number>();
        for(let [key, guildCodes] of this.cities) {
            let { serverId, cityId } = this.decodeKey(key);
            if(!this.hasSent(serverId, cityId)) {
                allCities.push({ serverId, cityId, guildCodes });
                if(!serverlists.includes(serverId)) serverlists.push(serverId);
            }
        }
        return {cities: allCities, serverlists};
    }

    public getGuildsInCity(serverId: number, cityId: number) {
        let key = this.getKey(serverId, cityId);
        return this.cities.get(key)||[];
    }

    public getMembersOfGuild(guildCode: string) {
        return this.members.get(guildCode)||[];
    }

    public async getGateHpAndInc(serverId: number, cityId: number, inc: number = 0) {
        let key = this.getKey(serverId, cityId);
        let gateHp = this.gateHp.get(key);
        if(!this.gateHp.has(key)) {
            gateHp = await getCityActivityGateHp(serverId, cityId);
            this.gateHp.set(key, gateHp);
            this.maxHp.set(key, gateHp);
        }
        if(inc != 0) {
            gateHp += inc;
            this.gateHp.set(key, gateHp);
        }
        if(gateHp <= 0) gateHp = 0;
        return { gateHp, maxHp: this.maxHp.get(key)||0 }
    }

    public pushMembers(guildCode: string, roleId: string, job: number, code: string) {

        if(this.members.has(guildCode)) {
            let members = this.members.get(guildCode);
            if(members.findIndex(cur => cur.roleId == roleId) == -1) {
                members.push({ roleId, job, code });
            }
        } else {
            let arr = new Array<string>();
            arr.push(roleId);
            this.members.set(guildCode, [{ roleId, job, code }]);
        }
    }

    public pushGuild(guildCode: string, serverId: number, cityId: number) {
        let key = this.getKey(serverId, cityId);
        if(!this.cities.has(key)) {
            this.cities.set(key, [guildCode]);
        } else {
            let arr = this.cities.get(key);
            if(!arr.includes(guildCode)) {
                arr.push(guildCode);
            }
        }
        this.guilds.set(guildCode, cityId);
    }
}