import { pinus, } from 'pinus';
import { ActivityModel } from '../../db/Activity';
import { ActivityInRemote } from '../../domain/activityField/activityField';
import { ActivityGroupModel } from '../../db/ActivityGroup';

const activityByServer: Map<number, number[]> = new Map();  // serverId => activityId[];
const activities: Map<number, ActivityInRemote> = new Map(); // activityId => activity
const activityByType: Map<number, Map<number, number[]>> = new Map(); // serverId => type => activityId[];
const groupToServer: Map<number, number[]> = new Map(); // group => serverId[];

export function clearData() {
    activityByServer.clear();
    activities.clear();
    activityByType.clear();
    groupToServer.clear();
}

function updateActivityByType(_activityByType: Map<number, Map<number, number[]>>) {
    activityByType.clear();
    for(let [serverId, map] of _activityByType) {
        activityByType.set(serverId, map);
    }
    pinus.app.set('activityByServer', activityByType);
}

function updateActivityByServer(_activityByServer: Map<number, number[]>) {
    activityByServer.clear();
    for(let [serverId, arr] of _activityByServer) {
        activityByServer.set(serverId, arr);
    }
    pinus.app.set('activityByServer', activityByServer);
}

export async function loadActivities() {
    clearData();
    let activityGroup = await ActivityGroupModel.findAllActivityGroup();
    for(let { groupId, serverIds } of activityGroup) {
        for(let serverId of serverIds) {
            if(!groupToServer.has(groupId)) {
                groupToServer.set(groupId, []);
            }
            groupToServer.get(groupId).push(serverId);
        }
    }

    let activityDb = await ActivityModel.findOpenAndComingActivityes();
    let activityIds: number[] = [];
    for(let activity of activityDb) {
        activities.set(activity.activityId, new ActivityInRemote(activity));
        activityIds.push(activity.activityId);
    }
    setActivityTypeAndServer();

    pinus.app.set('activityByServer', activityByServer);
    pinus.app.set('activityByType', activityByType);
    pinus.app.set('activities', activities);
    pinus.app.set('groupToServer', groupToServer);
}

export async function setActivityTypeAndServer() {
    let _activityByServer: Map<number, number[]> = new Map();  // serverId => activityId[];
    let _activityByType: Map<number, Map<number, number[]>> = new Map();

    for(let [_, activity] of activities) {
        let servers = groupToServer.get(activity.groupId)||[];
        for(let serverId of servers) {
            if(!_activityByServer.has(serverId)) {
                _activityByServer.set(serverId, []);
            }
            _activityByServer.get(serverId).push(activity.activityId);

            if(!_activityByType.has(serverId)) {
                _activityByType.set(serverId, new Map());
            }
            if(!_activityByType.get(serverId).has(activity.type)) {
                _activityByType.get(serverId).set(activity.type, []);
            }
            _activityByType.get(serverId).get(activity.type).push(activity.activityId);
        }
    }
    updateActivityByServer(_activityByServer);
    updateActivityByType(_activityByType);
    

}

export function updateActivities(activityDb: ActivityInRemote[]) {
    // console.log('******* activities', activities)
    let activityIds: number[] = [];
    for(let activity of activityDb) {
        activities.set(activity.activityId, activity);
        activityIds.push(activity.activityId);
    }
    setActivityTypeAndServer();
}

export function deleteActivities(activityIds: number[]) {

    for(let activityId of activityIds) {
        activities.delete(activityId);
    }
    setActivityTypeAndServer();
}

export function saveGroupToServer(groupIds: number[], serverIds: number[]) {
    for(let groupId of groupIds) {
        groupToServer.set(groupId, serverIds);
    }
    setActivityTypeAndServer();
}

export function addServerToGroup(groupIds: number[], serverIds: number[]) {
    for(let groupId of groupIds) {

        if(!groupToServer.has(groupId)) {
            groupToServer.set(groupId, []);
        }
        for(let serverId of serverIds) {
            let arr = groupToServer.get(groupId)||[];
            if(arr.indexOf(serverId) == -1) {
                groupToServer.get(groupId).push(serverId);
            }
        }
    }
    setActivityTypeAndServer();
}

export function saveActivitiesToGroup(groupId: number, activityDb: number[]) {
    for(let activityId of activityDb) {
        if(activities.get(activityId)) {
            activities.get(activityId).groupId = groupId;
        }
    }
    setActivityTypeAndServer();
}

export function _getActivityById(activityId: number) {
    return <ActivityInRemote>activities?.get(activityId);
}

export function _getActivitiesByType(serverId: number, type: number) {
    let activityByTypeData = activityByType?.get(serverId)?.get(type)??[];
    let activities: Map<number, ActivityInRemote> = pinus.app.get('activities');
    let result: ActivityInRemote[] = [];
    for(let activityId of activityByTypeData) {
        let activity = activities.get(activityId);
        if(activity && activity.isEnable) {
            result.push(activity);
        }
    }
    return result;
}

export function _getActivitiesByServerId(serverId: number) {
    let activityByServerId = activityByServer?.get(serverId)||[]
    let activities: Map<number, ActivityInRemote> = pinus.app.get('activities');
    let result: ActivityInRemote[] = [];
    for(let activityId of activityByServerId) {
        let activity = activities.get(activityId);
        if(activity && activity.isEnable) {
            result.push(activity);
        }
    }
    return result;
}

export function _getActivities() {
    try {
        // console.log('***** activities', activities);
        let result: ActivityInRemote[] = [];
        for(let [_, activity] of activities) {
            result.push(activity);
        }
        return result;
    } catch(e) {
        console.log('******** activity e', e)
    }
}
