import { z } from "zod";
import { query } from "./db.js";
import { ApiError } from "./errors.js";
const registerSchema = z.object({
    push_token: z.string().min(1).max(4096),
    platform: z.enum(["android", "ios"]),
});
export async function registerPushToken(claims, body) {
    const parsed = registerSchema.safeParse(body);
    if (!parsed.success) {
        throw new ApiError(400, "invalid_body", parsed.error.issues[0]?.message ?? "Invalid body");
    }
    await query(`INSERT INTO device (user_id, app_id, platform, push_token)
     VALUES ($1, $2, $3, $4)
     ON CONFLICT (push_token) DO UPDATE
       SET user_id = EXCLUDED.user_id,
           app_id = EXCLUDED.app_id,
           platform = EXCLUDED.platform,
           updated_at = now()`, [claims.userId, claims.appId, parsed.data.platform, parsed.data.push_token]);
    return { ok: true };
}
export async function targetsFor(userIds, appId) {
    if (userIds.length === 0)
        return [];
    const res = await query(`SELECT id AS device_id, user_id, push_token, platform
       FROM device
      WHERE user_id = ANY($1::uuid[]) AND app_id = $2`, [userIds, appId]);
    return res.rows;
}
export async function forget(deviceId) {
    await query(`DELETE FROM device WHERE id = $1`, [deviceId]);
}
export async function forgetUser(userId, appId) {
    if (appId) {
        await query(`DELETE FROM device WHERE user_id = $1 AND app_id = $2`, [userId, appId]);
    }
    else {
        await query(`DELETE FROM device WHERE user_id = $1`, [userId]);
    }
}
export const pushDirectory = { targetsFor, forget };
