
import { addGVGHistoryAreas, addGVGHistoryAreaTeam, addGVGHistoryCityTeam, addRedisChannel, delGVGHistoryAreas, delGVGHistoryAreaTeam, delGVGHistoryCityTeam, getGVGHistoryAreas, getGVGHistoryAreaTeam, getGVGHistoryCityTeam, redisChannelServer } from './redisService';
import { groupRoomId } from './chatService';
import { pinus } from 'pinus';
import { crc32 } from 'crc';
import { CHANNEL_PREFIX } from '../consts';
import { RoleModel } from './../db/Role';

export async function channelServer(roomId: string) {
    const existSid = await redisChannelServer(roomId);
    if (existSid) {
        return existSid;
    }
    const servers = pinus.app.getServersByType('chat');
    if (!servers || !servers.length) return null;

    let index = Math.abs(crc32(roomId)) % servers.length;
    const newSid = servers[index].id;
    const addResult = await addRedisChannel(roomId, newSid);
    if (!addResult) return null;
    return newSid;
}

async function addRoleToChannel(roomId: string, roleId: string, sid: string) {
    const channelSid = await channelServer(roomId);
    await pinus.app.rpc.chat.chatRemote.addChannel.toServer(channelSid, roomId, roleId, sid);
}

export async function addRoleToSysChannel(roleId: string, sid: string, serverId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.SYS, serverId);
    await addRoleToChannel(roomId, roleId, sid);
}

export async function addRoleToWorldChannel(roleId: string, sid: string, serverId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.WORLD, serverId);
    await addRoleToChannel(roomId, roleId, sid);
}

export async function addRoleToGuildChannel(roleId: string, sid: string, guildCode: string) {
    const roomId = groupRoomId(CHANNEL_PREFIX.GUILD, guildCode);
    await addRoleToChannel(roomId, roleId, sid);
}

export async function addRoleToCityChannel(roleId: string, sid: string, serverId: number, cityId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.CITY, `${serverId}_${cityId}`);
    await addRoleToChannel(roomId, roleId, sid);
}

export async function addRoleToGuildAuctionChannel(roleId: string, sid: string, guildCode: string) {
    const roomId = groupRoomId(CHANNEL_PREFIX.GUILD_AUCTION, guildCode);
    await addRoleToChannel(roomId, roleId, sid);
}

export async function addRoleToWorldAuctionChannel(roleId: string, sid: string, serverId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.WORLD_AUCTION, serverId);
    await addRoleToChannel(roomId, roleId, sid);
}

export async function addRoleToGroupShopChannel(roleId: string, sid: string) {
    const roomId = groupRoomId(CHANNEL_PREFIX.GROUP_SHOP);
    await addRoleToChannel(roomId, roleId, sid);
}

export async function addRoleToAreaChannel(roleId: string, groupKey: string, areaIds: number[], sid: string) {
    for(let areaId of areaIds) {
        const roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREAS, `${groupKey}_${areaId}`);
        await addRoleToChannel(roomId, roleId, sid);
    }
    await addGVGHistoryAreas(roleId, groupKey, areaIds);
}

export async function addRoleToAreaTeamChannel(roleId: string, groupKey: string, areaId: number, sid: string) {
    const roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREA_BY_TEAM, `${groupKey}_${areaId}`);
    await addRoleToChannel(roomId, roleId, sid);
    await addGVGHistoryAreaTeam(roleId, groupKey, areaId);
}

export async function addRoleToGVGCityChannel(roleId: string, groupKey: string, cityId: number, sid: string) {
    const roomId = groupRoomId(CHANNEL_PREFIX.GVG_CITY, `${groupKey}_${cityId}`);
    await addRoleToChannel(roomId, roleId, sid);
    await addGVGHistoryCityTeam(roleId, groupKey, cityId);
}
async function leaveChannel(roomId: string, roleId: string, sid: string) {
    const channelSid = await channelServer(roomId);
    await pinus.app.rpc.chat.chatRemote.leaveChannel.toServer(channelSid, roomId, roleId, sid);
}

export async function leaveSysChannel(roleId: string, sid: string, serverId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.SYS, serverId);
    await leaveChannel(roomId, roleId, sid);
}

export async function leaveWorldChannel(roleId: string, sid: string, serverId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.WORLD, serverId);
    await leaveChannel(roomId, roleId, sid);
}

export async function leaveCityChannel(roleId: string, sid: string, serverId: number, cityId: string) {
    const roomId = groupRoomId(CHANNEL_PREFIX.CITY, `${serverId}_${cityId}`);
    await leaveChannel(roomId, roleId, sid);
}

export async function leaveGuildAuctionChannel(roleId: string, sid: string, guildCode: string) {
    const roomId = groupRoomId(CHANNEL_PREFIX.GUILD_AUCTION, guildCode);
    await leaveChannel(roomId, roleId, sid);
}

export async function leaveWorldAuctionChannel(roleId: string, sid: string, serverId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.WORLD_AUCTION, serverId);
    await leaveChannel(roomId, roleId, sid);
}

export async function leaveGroupShopChannel(roleId: string, sid: string) {
    const roomId = groupRoomId(CHANNEL_PREFIX.GROUP_SHOP);
    await leaveChannel(roomId, roleId, sid);
}

export async function leaveGuildChannel(roleId: string, sid: string, guildCode: string) {
    if (!guildCode) return;
    const roomId = groupRoomId(CHANNEL_PREFIX.GUILD, guildCode);
    await leaveChannel(roomId, roleId, sid);
}

export async function leaveGVGAreaChannel(roleId: string, sid: string) {
    let keys = await getGVGHistoryAreas(roleId)||[];
    for(let key of keys) {
        const roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREAS, key);
        await leaveChannel(roomId, roleId, sid);
    }
    await delGVGHistoryAreas(roleId);
}

export async function leaveGVGAreaTeamChannel(roleId: string, sid: string) {
    let channelName = await getGVGHistoryAreaTeam(roleId);
    if(channelName) {
        const roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREA_BY_TEAM, channelName);
        await leaveChannel(roomId, roleId, sid);
    }
    await delGVGHistoryAreaTeam(roleId);
}

export async function leaveGVGCityTeamChannel(roleId: string, sid: string) {
    let channelName = await getGVGHistoryCityTeam(roleId);
    if(channelName) {
        const roomId = groupRoomId(CHANNEL_PREFIX.GVG_CITY, channelName);
        await leaveChannel(roomId, roleId, sid);
    }
    await delGVGHistoryCityTeam(roleId);
}

export async function getWorldChannelSid(serverId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.WORLD, serverId);
    const channelSid = await channelServer(roomId);
    return channelSid;
}

export async function getGuildChannelSid(guildCode: string) {
    const roomId = groupRoomId(CHANNEL_PREFIX.GUILD, guildCode);
    const channelSid = await channelServer(roomId);
    return channelSid;
}

export async function getCityChannelSid(serverId: number, cityId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.CITY, `${serverId}_${cityId}`);
    const channelSid = await channelServer(roomId);
    return channelSid;
}

export async function getGuildAuctionChannelSid(guildCode: string) {
    const roomId = groupRoomId(CHANNEL_PREFIX.GUILD_AUCTION, guildCode);
    const channelSid = await channelServer(roomId);
    return channelSid;
}

export async function getWorldAuctionChannelSid(serverId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.CITY, serverId);
    const channelSid = await channelServer(roomId);
    return channelSid;
}

export async function getGroupShopSid() {
    const roomId = groupRoomId(CHANNEL_PREFIX.GROUP_SHOP);
    const channelSid = await channelServer(roomId);
    return channelSid;
}

export async function getGVGAreaChannelSid(groupKey: string, areaId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREAS, `${groupKey}_${areaId}`);
    const channelSid = await channelServer(roomId);
    return channelSid;
}

export async function getGVGAreaTeamChannelSid(groupKey: string, areaId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREA_BY_TEAM, `${groupKey}_${areaId}`);
    const channelSid = await channelServer(roomId);
    return channelSid;
}

export async function getGVGCityTeamChannelSid(groupKey: string, cityId: number) {
    const roomId = groupRoomId(CHANNEL_PREFIX.GVG_CITY, `${groupKey}_${cityId}`);
    const channelSid = await channelServer(roomId);
    return channelSid;
}

async function delChannel(roomId: string) {
    const channelSid = await channelServer(roomId);
    await pinus.app.rpc.chat.chatRemote.deleteChannel.toServer(channelSid, roomId);
}

export async function delGuildChannel(guildCode: string) {
    if (!guildCode) return;
    const roomId = groupRoomId(CHANNEL_PREFIX.GUILD, guildCode);
    await delChannel(roomId);
}