import type { DB } from "@/internal/datastore/db";
import type { UserAgentInfo } from "@/lib/user_agent";
import type { Generated, Kysely } from "kysely";

export interface ConsoleUserSessions {
    id: Generated<string>;
    console_user_id: string; // UUID
    fcm_token: string;
    ip_address: string;
    device_type: string;
    os: string;
    browser: string;
    refresh_token: string;
    location: string;
    created_at: Generated<Date>;
    updated_at: Date | null;
}

export class AdminConsoleSessionRepository {
    private db: Kysely<DB & { console_user_sessions: ConsoleUserSessions }>;

    constructor(db: Kysely<DB>) {
        this.db = db as unknown as Kysely<DB & { console_user_sessions: ConsoleUserSessions }>;
    }

    async createSession({
        userId,
        ua,
        refreshToken,
        fcmToken,
        location
    }: {
        userId: string;
        ua: UserAgentInfo;
        refreshToken: string;
        fcmToken: string;
        location: string;
    }) {
        const now = new Date();
        return await this.db
            .insertInto("console_user_sessions")
            .values({
                console_user_id: userId,
                fcm_token: fcmToken,
                device_type: ua.device_type,
                ip_address: ua.ip_address,
                os: ua.os,
                browser: ua.browser,
                refresh_token: refreshToken,
                location,
            })
            .returningAll()
            .executeTakeFirst();
    }

    async getSessionByRefreshToken(refreshToken: string) {
        return await this.db
            .selectFrom("console_user_sessions")
            .selectAll()
            .where("refresh_token", "=", refreshToken)
            .executeTakeFirst();
    }

    async getSessionById(sessionId: string) {
        return await this.db
            .selectFrom("console_user_sessions")
            .selectAll()
            .where("id", "=", sessionId)
            .executeTakeFirst();
    }

    async updateRefreshToken(id: string, newRefreshToken: string) {
        return await this.db
            .updateTable("console_user_sessions")
            .set({
                refresh_token: newRefreshToken,
                updated_at: new Date()
            })
            .where("id", "=", id)
            .returningAll()
            .executeTakeFirst();
    }

    async deleteSession(refreshToken: string) {
        return await this.db
            .deleteFrom("console_user_sessions")
            .where("refresh_token", "=", refreshToken)
            .execute();
    }
}
