import { Users } from "../models/index.js";
import { Cache } from "../misc/cache.js";
import { redisClient, subscriber } from "../db/redis.js";
export const userByIdCache = new Cache("userById", 60 * 30);
export const localUserByNativeTokenCache = new Cache("localUserByNativeToken", 60 * 30);
export const localUserByIdCache = new Cache("localUserByIdCache", 60 * 30);
export const uriPersonCache = new Cache("uriPerson", 60 * 30);
subscriber.on("message", async (_, data)=>{
    const obj = JSON.parse(data);
    if (obj.channel === "internal") {
        const { type, body } = obj.message;
        switch(type){
            case "localUserDeleted":
                {
                    await userByIdCache.delete(body.id);
                    await localUserByIdCache.delete(body.id);
                    const toDelete = Array.from(await localUserByNativeTokenCache.getAll()).filter((v)=>v[1]?.id === body.id).map((v)=>v[0]);
                    await localUserByNativeTokenCache.delete(...toDelete);
                    const uriCacheToDelete = Array.from(await uriPersonCache.getAll()).filter((v)=>v[1]?.id === body.id).map((v)=>v[0]);
                    await uriPersonCache.delete(...uriCacheToDelete);
                    break;
                }
            case "localUserUpdated":
                {
                    await userByIdCache.delete(body.id);
                    await localUserByIdCache.delete(body.id);
                    const toDelete = Array.from(await localUserByNativeTokenCache.getAll()).filter((v)=>v[1]?.id === body.id).map((v)=>v[0]);
                    await localUserByNativeTokenCache.delete(...toDelete);
                    break;
                }
            case "userChangeSuspendedState":
            case "userChangeSilencedState":
            case "userChangeModeratorState":
            case "remoteUserUpdated":
                {
                    const user = await Users.findOneByOrFail({
                        id: body.id
                    });
                    await userByIdCache.set(user.id, user);
                    const trans = redisClient.multi();
                    for (const [k, v] of (await uriPersonCache.getAll()).entries()){
                        if (v?.id === user.id) {
                            await uriPersonCache.set(k, user, trans);
                        }
                    }
                    await trans.exec();
                    if (Users.isLocalUser(user)) {
                        await localUserByNativeTokenCache.set(user.token, user);
                        await localUserByIdCache.set(user.id, user);
                    }
                    break;
                }
            case "remoteUserDeleted":
                {
                    await userByIdCache.delete(body.id);
                    const toDelete = Array.from(await uriPersonCache.getAll()).filter((v)=>v[1]?.id === body.id).map((v)=>v[0]);
                    await uriPersonCache.delete(...toDelete);
                    break;
                }
            case "userTokenRegenerated":
                {
                    const user = await Users.findOneByOrFail({
                        id: body.id
                    });
                    await localUserByNativeTokenCache.delete(body.oldToken);
                    await localUserByNativeTokenCache.set(body.newToken, user);
                    break;
                }
            default:
                break;
        }
    }
});
