import { EXTERIOR } from "../pubUtils/dicParam";
import { WoodenHorse } from "./battleField/guildActivity";
import { RoleUpdate, RoleType } from "../db/Role";
import { reduceCe } from "../pubUtils/util";
import { GuildUpdateParam } from "../db/Guild";
import { HeroType, HeroUpdate } from "../db/Hero";
import { getSeconds } from "../pubUtils/timeUtil";

// 排行榜返回玩家值
export class RankParam {
    roleName: string = "";
    lv: number = 0;
    vLv: number = 0;
    guildName: string = "";
    head: number = EXTERIOR.EXTERIOR_FACE;
    frame: number = EXTERIOR.EXTERIOR_FACECASE;
    spine: number = EXTERIOR.EXTERIOR_APPEARANCE;
    title: number = 1;
    ce: number = 0;
    updatedAt: number = 0;

    constructor(role: RoleUpdate, fromDb: boolean) {
        if(role.roleName) this.roleName = role.roleName;
        if(role.lv) this.lv = role.lv;
        if(role.vLv) this.vLv = role.vLv;
        if(role.head) this.head = role.head;
        if(role.frame) this.frame = role.frame;
        if(role.spine) this.spine = role.spine;
        if(role.title) this.title = role.title;
        if(role.guildName) this.guildName = role.guildName||"";
        if(role.ce) {
            if(fromDb && !role.isReducedCe) {
                this.ce = reduceCe(role.ce);
            } else {
                this.ce = role.ce;
            }
        }
        if(role.updatedAt) {
            if(typeof role.updatedAt == 'number') {
                this.updatedAt = role.updatedAt;
            } else {
                this.updatedAt = getSeconds(role.updatedAt);
            }
        } 
    }
}

export class RoleRankInfo extends RankParam {
    rank: number = 1;
    roleId: string = "";
    num: number = 0;
    time: number = 0;
    hero: LineupParam[];
    lineup: LineupParam[];
    
    setInfo(rank: number, myId: myIdInter, num: number, time: number) {
        this.rank = rank;
        this.roleId = myId.roleId;
        this.num = num;
        this.time = time;
    }

    isMyInfo(myId: myIdInter) {
        return this.roleId == myId.roleId;
    }

    setTopLine(lineup: LineupParam[]){
        this.lineup = lineup;
    }

    setSingleHero(hero: LineupParam[]){
        this.hero = hero;
    }
}

// 公会排行榜返回值
export class GuildRankParam {
    icon: number;
    name: string;
    lv: number;
    memberCnt: number;
    leader: {
        roleId: string;
        roleName: string;
        title: number;
        lv: number;
        head: number;
        frame: number;
        spine: number;

    }

    constructor(guild: GuildUpdateParam) {
        this.icon = guild.icon;
        this.name = guild.name;
        this.lv = guild.lv;
        let leader = <RoleType>guild.leader;
        let _leader = new GuildLeader(leader);
        this.leader = _leader;
        this.memberCnt = guild.memberCnt;
    }
}

export class GuildRankInfo extends GuildRankParam {
    rank: number;
    code: string;
    num: number;
    time: number;
    
    setInfo(rank: number, myId: myIdInter, num: number, time: number) {
        this.rank = rank;
        this.code = myId.guildCode;
        this.num = num;
        this.time = time;
    }

    isMyInfo(myId: myIdInter) {
        return this.code == myId.guildCode;
    }
}

export class GuildLeader {
    roleId: string;
    roleName: string;
    title: number;
    lv: number;
    head: number;
    frame: number;
    spine: number;

    constructor(leader: { roleId: string, roleName: string, title: number, lv: number, head: number, frame: number, spine: number}) {
        this.roleId = leader.roleId;
        this.roleName = leader.roleName;
        this.title = leader.title;
        this.lv = leader.lv;
        this.head = leader.head;
        this.frame = leader.frame;
        this.spine = leader.spine;
    }
}

// 排行榜返回玩家值
export class LineupParam {
    hid: number;
    star: number;
    colorStar: number;
    lv: number;
    quality: number;
    job: number;

    constructor(hero: HeroType) {
        this.hid = hero.hid;
        this.star = hero.star;
        this.colorStar = hero.colorStar;
        this.lv = hero.lv;
        this.quality = hero.quality;
        this.job = hero.job;
    }
}

export class SimpleGuildRankParam {
    rank: number = 0;
    code: string = "";
    name: string = "";
    num: number = 0;
    
    constructor(rank: number, code: string, name: string, num: number) {
        this.rank = rank;
        this.code = code;
        this.name = name;
        this.num = num;
    }
}

export class SimpleGuildRankWithTimeParam extends SimpleGuildRankParam {
    time: number = 0;
    durability: number = 0;
    
    constructor(rank: number, code: string, name: string, obj: WoodenHorse|{distance: number, time: number, startTime: number, durability: number}|false) {
        super(rank, code, name, obj?obj.distance:0);
        // console.log(JSON.stringify(obj));
        if(obj) {
            this.num = obj.distance;
            this.time = Math.floor((obj.time - obj.startTime)/1000);
            this.durability = obj.durability;
        }
    }
}

export class SimpleRoleRankParam {
    rank: number;
    roleId: string;
    roleName: string;
    num: number;

    constructor(rank: number, roleId: string, roleName: string, num: number) {
        this.rank = rank;
        this.roleId = roleId;
        this.roleName = roleName;
        this.num = num;
    }
}

export class KeyName {
    key: string;
    serverId?: number;
    guildCode?: string;
    cityId?: number;
    hid?: number;

    constructor(key: string, param: KeyNameParam) {
        this.key = key;
        if(param.serverId) this.serverId = param.serverId;
        if(param.guildCode) this.guildCode = param.guildCode;
        if(param.cityId) this.cityId = param.cityId;
        if(param.hid) this.hid = param.hid;
    }

    public getName() {
        let res = this.key;
        if(this.serverId) res += `:${this.serverId}`;
        if(this.guildCode) res += `:${this.guildCode}`;
        if(this.cityId) res += `:${this.cityId}`;
        if(this.hid) res += `:${this.hid}`;
        return res;
    }

    public getNameWithPlus(...plus: string[]) {
        let res = this.getName();
        for(let p of plus) {
            res += `:${p}`;
        }
        return res;
    }

    public getTimeName() {
        return this.getNameWithPlus('time');
    }

    public getUnionName() {
        return this.getNameWithPlus('union');
    }
}

export type KeyNameParam = Partial<KeyName>;


export interface myIdInter {
    roleId?: string;
    guildCode?: string;
    hid?: number;
}

// 排行榜总览左边的数据
export class GeneralRankParamRole {
    type: number;  // 排行榜id
    roleId: string;
    roleName: string;
    head: number;
    frame: number;
    spine: number;
    lv: number;
    vLv: number;
    guildName: string;
    ce: number;
    num: number;
    received: number[];

    constructor(type: number, rankInfo: RoleRankInfo, received?: number[]) {
        this.type = type;
        this.roleId = rankInfo.roleId;
        this.roleName = rankInfo.roleName;
        this.head = rankInfo.head;
        this.frame = rankInfo.frame;
        this.spine = rankInfo.spine;
        this.lv = rankInfo.lv;
        this.vLv = rankInfo.vLv;
        this.guildName = rankInfo.guildName;
        this.ce = rankInfo.ce;
        this.num = rankInfo.num;
        this.received = received;
    }
}

// 排行榜右边的数据
export class GeneralRankParamBattle {
    type: number;
    roleId: string;
    roleName: string;
    guildName: string;
    hid: number = 0;
    skinId: number = 0;
    num: number;
    received: number[];
    head: number;
    frame: number;
    spine: number;

    constructor(type: number, rankInfo: RoleRankInfo, hero: HeroUpdate, received?: number[]) {
        this.type = type;
        this.roleId = rankInfo.roleId;
        this.roleName = rankInfo.roleName;
        this.guildName = rankInfo.guildName;
        this.num = rankInfo.num;
        this.head = rankInfo.head;
        this.frame = rankInfo.frame;
        this.spine = rankInfo.spine;
        if(hero) {
            this.hid = hero.hid;
            let curSkin = hero.skins.find(cur => cur.enable);
            this.skinId = curSkin?curSkin.id: 0;
        }
        this.received = received;
    }
}