import { ACTIVITY_TYPE, CURRENCY_BY_TYPE, CURRENCY_TYPE, HERO_SYSTEM_TYPE, LOG_TYPE } from "../consts";
import { HeroType } from "../db/Hero";
import { RoleModel, RoleType, RoleUpdate } from "../db/Role";
import { UserLogModel, GateHpLog, BossHpLog } from "../db/UserLog";
import { UserOrderModelType } from "../db/UserOrder";
import { Figure } from "../domain/dbGeneral";
import { MailParam } from "../domain/roleField/mail";
import { gameData } from "./data";

function getParamBySession(session: any) {
    let uid = session.get('userid');
    let roleId = session.get('roleId')||'';
    let roleName = session.get('roleName')||'';
    let ip = session.get('ip');
    let serverId = session.get('serverId');
    return { uid, roleId, roleName, ip, serverId };
}

function getParamByRole(role: RoleType) {
    let uid = role.userInfo.uid;
    let roleId = role.roleId;
    let roleName = role.roleName;
    let serverId = role.serverId;
    return { uid, roleId, roleName, serverId };
}

export async function saveLoginAndOutLog(type: LOG_TYPE, session: any) {
    try {
        let params = getParamBySession(session);
        if(params.roleId && params.roleName) {
            await UserLogModel.createRecord({ type, ...params });
        }
    } catch (e) {
        console.error(e);
    }
}

export async function saveCeChangeLog(role: RoleType, inc: number, count: number, type: number, ids: string[]) {
    try {
        if(inc != 0) {
            let params = getParamByRole(role);
            await UserLogModel.createRecord({ type: LOG_TYPE.CE_CHANGE, ...params, inc, count, ceChangeReason: type, ceChangeTxt: ids });    
        }
    } catch (e) {
        console.error(e);
    }
}

export function getReCalRoleAttrIds(type: number, update: RoleUpdate, args: number[]) {
    if (type == HERO_SYSTEM_TYPE.TITLE) {
        return [update.title];
    } else {
        return args;
    }
}

export async function savePayLog(order: UserOrderModelType) {
    try {
        let role = await RoleModel.findByRoleId(order.roleId, 'userInfo roleId roleName serverId');
        let params = getParamByRole(role);
        let { productID, message: productName, price, localOrderID, orderID, state, useVoucher } = order;
        let dicRmb = gameData.rmb.get(productID);
        let isYuanbao = dicRmb.type == ACTIVITY_TYPE.YUAN_BAO_SHOP;
        await UserLogModel.createRecord({ type: LOG_TYPE.PAY, ...params, productID, productName, price, isYuanbao, localOrderID, orderID, totalPay: role.totalPay, orderStatus: state, useVoucher });
    } catch (e) {
        console.error(e);
    }
}

export async function saveItemChangeLog(roleId: string, goods: { id: number, count: number, inc: number }[], reason: number) {
    try {
        let role = await RoleModel.findByRoleId(roleId, 'userInfo roleId roleName serverId');
        let params = getParamByRole(role);
        for (let { id, count, inc } of goods) {
            if(inc == 0) continue;
            let dicGoods = gameData.goods.get(id);
            await UserLogModel.createRecord({ type: LOG_TYPE.ITEM_CHANGE, ...params, itemId: id, itemName: dicGoods.name, itid: dicGoods.itid, inc, count, itemChangeReason: reason })
        }
    } catch (e) {
        console.error(e);
    }
}

export async function saveGoldChangeLog(roleId: string, count: number, inc: number, reason: number) {
    let id = CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD);
    return await saveItemChangeLog(roleId, [{ id, count, inc }], reason);
}

export async function saveCoinChangeLog(roleId: string, count: number, inc: number, reason: number) {
    let id = CURRENCY_BY_TYPE.get(CURRENCY_TYPE.COIN);
    return await saveItemChangeLog(roleId, [{ id, count, inc }], reason);
}

export async function saveFigureInfoLog(roleId: string, figureInfo: { heads: Figure[], frames: Figure[], spines: Figure[] }, reason: number) {
    try {
        await saveItemChangeLog(roleId, figureInfo.frames, reason);
        await saveItemChangeLog(roleId, figureInfo.heads, reason);
        await saveItemChangeLog(roleId, figureInfo.spines, reason);
    } catch (e) {
        console.error(e);
    }
}

export async function saveMailLog(session: any, mails: MailParam[]) {
    try {
        let params = getParamBySession(session);
        for(let { id, sendName, title, content, goods } of mails) {
            await UserLogModel.createRecord({ type: LOG_TYPE.RECEIVE_MAIL, ...params, mailId: id, goods: goods, mailContent: content, mailSendName: sendName, mailTitle: title });
        }
    } catch (e) {
        console.error(e);
    }
}

export async function saveGuildGateHpLog(serverId: number, cityId: number, log: GateHpLog) {
    try {
        await UserLogModel.createRecord({ type: LOG_TYPE.GATE_HP, serverId, cityId, gateHp: log });    
    } catch (e) {
        console.error(e);
    }
}

export async function saveGuildBossHpLog(serverId: number, warId: number, guildCode: string,  log: BossHpLog) {
    try {
        await UserLogModel.createRecord({ type: LOG_TYPE.BOSS_HP, serverId, warId, guildCode, bossHp: log });    
    } catch (e) {
        console.error(e);
    }
}

export async function saveRebirthLog(session: any, hero: HeroType) {
    try {
        let params = getParamBySession(session);
        await UserLogModel.createRecord({ type: LOG_TYPE.REBIRTH, ...params, hid: hero.hid, heroInfo: JSON.stringify(hero) });    
    } catch (e) {
        console.error(e);
    }
}

export async function saveMemoryLog(sid: string, memoryLogField: string, memoryData: string) {
    try {
        await UserLogModel.createRecord({ type: LOG_TYPE.MEMORY, sid, memoryLogField, memoryData });    
    } catch (e) {
        console.error(e);
    }
}

export async function saveMemoryLogs(sid: string, arr: { memoryLogField: string, memoryData: string} []) {
    try {
        let params = arr.map(({ memoryLogField, memoryData }) => {
            return { type: LOG_TYPE.MEMORY, sid, memoryLogField, memoryData }
        })
        await UserLogModel.createRecords(params);    
    } catch (e) {
        console.error(e);
    }
}