import { prop } from "@typegoose/typegoose";
import { ArtifactModelType } from "../../db/Artifact";
import { GVGLeagueType } from "../../db/GVGLeague";
import { GVGVestigeRecType } from "../../db/GVGVestigeRec";
import { HeroType, Talent } from "../../db/Hero";
import { RoleType } from "../../db/Role";
import { gameData } from "../../pubUtils/data";
import { EXTERIOR, GVG } from "../../pubUtils/dicParam";
import { DicGVGVestige } from "../../pubUtils/dictionary/DicGVGVestige";
import { DicWarJson } from "../../pubUtils/dictionary/DicWarJson";
import { GVGHeroInfo } from "../dbGeneral";
import { LineupHero } from "../roleField/hero";

export class OppPlayerHeroInfo {
    @prop({ required: true })
    hid: number;				 // 武将id
    @prop({ required: true })
    skinId: number;				 // 皮肤id
    @prop({ required: true })
    quality: number;			 // 品质
    @prop({ required: true })
    star: number;				 // 星级
    @prop({ required: true })
    colorStar: number;			 // 彩星
    @prop({ required: true })
    lv: number;					 // 等级
    @prop({ required: true })
    dataId: number;              // 出兵表上所占位置
    @prop({ required: true })
    order: number;               // 行动顺序
    @prop({ required: true })
    ce: number;                  // 战力

    setByWarJson(warJson: DicWarJson) {
        this.hid = warJson.actorId;
        this.skinId = warJson.actorId;
        this.lv = warJson.lv;
        this.dataId = warJson.dataId;
        this.order = warJson.outIndex;
        let dicHero = gameData.hero.get(warJson.actorId);

        if(dicHero) {
            this.quality = dicHero.quality;
            if(this.quality == 4) {
                this.star = 6;
                this.colorStar = warJson.star;
            } else {
                this.star = warJson.star;
                this.colorStar = 0;
            }
        }
    }

    setByDefenseHero(hero: HeroType, lineup: {actorId: number, dataId: number, order: number}[]) {
        this.hid = hero.hid;
        this.skinId = hero.skinId;
        this.quality = hero.quality;
        this.star = hero.star;
        this.colorStar = hero.colorStar;
        this.lv = hero.lv;
        this.ce = hero.ce;
        let curLineup = lineup.find(cur => cur.actorId == hero.hid);
        if(curLineup) {
            this.dataId = curLineup.dataId;
            this.order = curLineup.order;
        }
    }
}

// ladderMatchRec
export class OppPlayerInfo {
    @prop({ required: true })
    oldRank: number = 0;					// 原排名
    @prop({ required: true })
    newRank: number = 0;					// 交换后的排名   
    @prop({ required: true })
    roleId: string = '';					// 角色 id
    @prop({ required: true })
    roleName: string = GVG.GVG_ROBOT_NAME; // 角色 名 
    @prop({ required: true })
    leagueName: string = '';			   // 联军名
    @prop({ required: true })
    leagueCode: string = '';			   // 联军id
    @prop({ required: true, default: 0 })
    lv: number = 1;               // 等级
    @prop({ required: true, default: EXTERIOR.EXTERIOR_FACE })
    head: number = EXTERIOR.EXTERIOR_FACE;          // 头像
    @prop({ required: true, default: EXTERIOR.EXTERIOR_FACECASE })
    frame: number = EXTERIOR.EXTERIOR_FACECASE;          // 相框
    @prop({ required: true, default: EXTERIOR.EXTERIOR_APPEARANCE })
    spine: number = EXTERIOR.EXTERIOR_APPEARANCE;             // 形象
    @prop({ required: true, default: 0 })
    title: number = 1;            // 爵位
    @prop({ required: true, default: 0 })
    ce: number = 0;               // 防守战力
    @prop({ required: true, default: false })
    isSuccess: boolean = false;			// 是否胜利
    @prop({ required: true, default: [], type: OppPlayerHeroInfo, _id: false })
    heroes: OppPlayerHeroInfo[] = [];			   	// 武将
    @prop({ required: true })
    isRobot: boolean = false;					// 原排名

    initByPlayer(rank: number, role: RoleType, league: GVGLeagueType, isSuccess: boolean ) {
        this.oldRank = rank;
        this.newRank = rank;
        this.roleId = role.roleId;
        this.roleName = role.roleName;
        this.head = role.head;
        this.frame = role.frame;
        this.spine = role.spine;
        this.title = role.title;
        this.lv = role.lv;
        this.isSuccess = isSuccess;
        this.isRobot = false;
        this.leagueCode = league.leagueCode;
        this.leagueName = league.name;
    }

    setPlayerHeroes(heroes: HeroType[], lineup: {actorId: number, dataId: number, order: number}[]) {
        for(let hero of heroes) {
            let obj = new OppPlayerHeroInfo();
            obj.setByDefenseHero(hero, lineup);
            this.ce += hero.ce;
            this.heroes.push(obj);
        }
    }

    initByRobot(dic: DicGVGVestige, heroes: OppPlayerHeroInfo[], isSuccess: boolean) {
        this.oldRank = dic.rank;
        this.newRank = dic.rank;
        this.roleId = `robot${this.oldRank}`;
        this.head = dic.head;
        this.spine = dic.spine;
        this.ce = dic.ce;
        this.lv = dic.level;
        this.isSuccess = isSuccess;
        this.heroes = heroes;
        this.isRobot = true;
    }
}

class HeroArtifact {
    @prop({ required: true })
    artifactId: number;
    
    @prop({ required: true })
    lv: number;
}

export class OppDetailHeroData {
    actorId: number = 0;             // 武将id            
    skinId: number = 0;              // 皮肤id，fashions表的heroId
    actorName: string = '';           // 武将名            
    dataId: number = 0;              // 出兵表唯一id            
    relation: number = 0;            // 地方还是我方            
    dirction: number = 0;           // 方向            
    outIndex: number = 0;            // 玩家设置的出场顺序，即order字段
    x: number = 0;                   // 战场x坐标            
    y: number = 0;                   // 战场y坐标            
    var: number = 0;                 // 变量            
    lv: number = 0;                  // 等级            
    hide: number = 0;                // 是否隐藏            
    initial_ai: number = 0;          // ai类型            
    attribute: string = '';          // 武将属性，格式 id&val|id&val|...，这里的次级属性都是没有除1000的值
    star: number = 0;                     // 星级            
    colorStar: number = 0;                // 彩星
    quality: number = 0;                  // 品质
    job: number = 0;                  // 职业
    skill: string = '';                    // 技能
    seid: string = '';                     // 技能 
    spine: string = '';                    // 动画
    talent: Talent[] = [];
    subHid: number = 0;                      // 副将
    artifact: HeroArtifact[] = [];

    constructor(warJson: DicWarJson, defensHero: OppPlayerHeroInfo, hero: HeroType, artifacts: ArtifactModelType[]) {
        this.dataId = warJson.dataId;
        this.relation = warJson.relation;
        this.dirction = warJson.dirction;
        this.initial_ai = warJson.initial_ai;
        this.x = warJson.x;
        this.y = warJson.y;
        this.var = warJson.var;
        this.hide = warJson.hide;
        this.skill = warJson.skill;
        this.seid = warJson.seid;
        this.spine = warJson.spine;
        let dicHero = gameData.hero.get(warJson.actorId);
        if(dicHero) this.job = dicHero.jobid;

        if(defensHero) {
            this.outIndex = defensHero.order;
            if(hero) {
                this.actorId = hero.hid;
                this.skinId = hero.skinId;
                this.actorName = hero.hName;
                this.lv = hero.lv;
                this.star = hero.star;
                this.colorStar = hero.colorStar;
                let skin = hero.skins.find(cur => cur.enable);
                if(skin) this.talent = skin.talent;
                this.job = hero.job;
                this.subHid = hero.subHid;
                let artifact = artifacts.find(cur => cur.seqId == hero.artifact);
                if(artifact) this.artifact.push({ artifactId: artifact.artifactId, lv: artifact.lv });
            }
        }
    }

    setAttribute(attribute: string) {
        this.attribute = attribute;
    }
}

export class OppDetailData{
    roleId: string;       // 对手的id
    isRobot: boolean;
    vestigeId: number;
    battleCode: string;
    warId: number;
    status: number;
    time: number;
    heroes: OppDetailHeroData[] = [];
    lineupCe: number = 0;

    constructor(rec: GVGVestigeRecType, obj: {status: number, time: number}) {
        this.vestigeId = rec.vestigeId;
        this.battleCode = rec.battleCode;
        this.warId = rec.warId;
        this.roleId = rec.defenseRoleId;
        this.isRobot = rec.defenseInfo.isRobot;
        this.status = obj.status;
        this.time = obj.time;
    }

    setByPlayer(dicWarJson: DicWarJson[], defenseHeroes: OppPlayerHeroInfo[], heroes: HeroType[], artifacts: ArtifactModelType[]) {
        for(let warJson of dicWarJson) {
            let defenseHero = defenseHeroes.find(cur => cur.dataId == warJson.dataId);
            if(!defenseHero) continue;
            let curHero = heroes.find(cur => cur.hid == defenseHero.hid);
            let hero = new OppDetailHeroData(warJson, defenseHero, curHero, artifacts);
            this.heroes.push(hero);
            this.lineupCe += curHero.ce;
        }
    }

    setAttribute(hid: number, attribute: string) {
        let hero = this.heroes.find(cur => cur.actorId == hid);
        if(hero) hero.setAttribute(attribute);
    }
}

export interface SaveTeamParam {
    cityId: number;
    index: number;
    head: number;
    frame: number;
    spine: number;
    lineup?: LineupHero[];
}

export interface SaveTeamUpdateParam {
    index: number;
    head: number;
    frame: number;
    spine: number;
    configId: number;
    groupKey: string;
    lineup?: GVGHeroInfo[];
    lineupCe?: number;
    cityId?: number;
    areaId?: number;
}

export interface InitTeamParam {
    roleName: string;
    serverId: number;
    leagueCode: string;
    leagueName: string;
    durability: number;
    maxDurability: number;
    lv: number;
}