import { TRPCError } from "@trpc/server"; import { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/postgres"; import type { Chats, ChatsChatid } from "~/schemas/public/Chats"; import type { Etichette } from "~/schemas/public/Etichette"; import type { Users, UsersId } from "~/schemas/public/Users"; import type { Message } from "~/server/api/routers/chat_sse"; import { db } from "~/server/db"; import { add, type ChatUserInfo, getRaw } from "~/server/services/chat.service"; import { getUserInfo } from "~/utils/kysely-helper"; export type ActiveChatsType = Pick & Pick & { lastmessage: Message | null; etichette: Etichette[]; }; export const getActiveInfos = async (): Promise => { const chats = await db .selectFrom("chats") .innerJoin("users", "users.id", "chats.user_ref") .select((eb) => [ "chatid", "chats.created_at", "id", "username", "email", "nome", jsonObjectFrom( eb .selectFrom("messages") .whereRef("messages.chatid", "=", "chats.chatid") .innerJoin("users", "users.id", "messages.sender") .select([ "messages.message", "messages.messageid", "messages.chatid", (eb) => eb .cast( eb.fn("to_char", [ "messages.time", eb.val("YYYY-MM-DD HH24:MI:SS"), ]), "text", ) .as("time"), "messages.sender", "messages.isread", "users.nome as sender_nome", "users.isAdmin as sender_isAdmin", ]) .orderBy("messages.messageid", "desc") .limit(1), ).as("lastmessage"), jsonArrayFrom( eb .selectFrom("etichette") .selectAll("etichette") .innerJoin( "chats_etichette", "etichette.id_etichetta", "chats_etichette.etichettaid", ) .whereRef("chats_etichette.chatid", "=", "chats.chatid") .select([ "etichette.id_etichetta", "etichette.title", "etichette.color_hex", ]), ).as("etichette"), ]) .orderBy("created_at", "desc") .execute(); return chats; }; export const getChatInfo = async ({ chatId, }: { chatId: ChatsChatid; }): Promise => { return await getRaw({ chatId, db }); }; export const getChatByUser = async ({ userId }: { userId: UsersId }) => { try { const chat = await db .selectFrom("chats") .select(["chatid", getUserInfo()]) .where("chats.user_ref", "=", userId) .executeTakeFirst(); if (!chat) { await add({ db, userId: userId, }); const chat = await db .selectFrom("chats") .select(["chatid", getUserInfo()]) .where("chats.user_ref", "=", userId) .executeTakeFirst(); if (!chat) { throw new TRPCError({ code: "NOT_FOUND" }); } return chat; } return chat; } catch (e) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Error while getting chat: ${(e as Error).message}`, }); } }; export const deleteChatHandler = async ({ chatId, }: { chatId: ChatsChatid; }) => { try { return await db .deleteFrom("chats") .where("chats.chatid", "=", chatId) .returning("chatid") .execute(); } catch (e) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Error while deleting chat: ${(e as Error).message}`, }); } }; export const getUserByChatHandler = async ({ chatId, }: { chatId: ChatsChatid; }) => { const chat = await db .selectFrom("chats") .select(["chatid", "created_at", "user_ref", getUserInfo()]) .where("chats.chatid", "=", chatId) .executeTakeFirstOrThrow( () => new Error(`Chat not found - chatId: ${chatId}`), ); if (!chat.userinfo) { throw new TRPCError({ code: "NOT_FOUND" }); } return chat.userinfo as ChatUserInfo; }; export const getChatByUserIdHandler = async ({ userId, }: { userId: UsersId; }) => { const chat = await db .selectFrom("chats") .select("chatid") .where("chats.user_ref", "=", userId) .executeTakeFirst(); return chat?.chatid || null; };