import "server-only";

import { ID, Permission, Query, Role } from "node-appwrite";

import { DATABASE_ID, TABLES, type Notification } from "./schema";
import { createAdminClient } from "./server";
import { toPlain } from "./serialize";

type CreateNotificationInput = {
  tenantId: string;
  userId?: string;
  jobId?: string;
  connectionId?: string;
  message: string;
};

/**
 * Idempotent notification creator. Best-effort: never re-throws so callers
 * (server actions in the hot path) stay reliable.
 */
export async function createNotification(input: CreateNotificationInput): Promise<void> {
  try {
    const { tablesDB } = createAdminClient();
    await tablesDB.createRow(
      DATABASE_ID,
      TABLES.notifications,
      ID.unique(),
      {
        tenantId: input.tenantId,
        userId: input.userId,
        jobId: input.jobId,
        connectionId: input.connectionId,
        message: input.message.slice(0, 500),
        read: false,
      },
      [
        Permission.read(Role.team(input.tenantId)),
        Permission.update(Role.team(input.tenantId)),
        Permission.delete(Role.team(input.tenantId, "owner")),
        Permission.delete(Role.team(input.tenantId, "admin")),
      ],
    );
  } catch (err) {
    console.error("[createNotification]", err);
  }
}

export async function countUnreadNotifications(tenantId: string): Promise<number> {
  try {
    const { tablesDB } = createAdminClient();
    const result = await tablesDB.listRows({
      databaseId: DATABASE_ID,
      tableId: TABLES.notifications,
      queries: [
        Query.equal("tenantId", tenantId),
        Query.equal("read", false),
        Query.limit(1),
      ],
    });
    return result.total;
  } catch {
    return 0;
  }
}

export async function listNotifications(
  tenantId: string,
  limit = 50,
): Promise<Notification[]> {
  const { tablesDB } = createAdminClient();
  const result = await tablesDB.listRows({
    databaseId: DATABASE_ID,
    tableId: TABLES.notifications,
    queries: [
      Query.equal("tenantId", tenantId),
      Query.orderDesc("$createdAt"),
      Query.limit(limit),
    ],
  });
  return toPlain(result.rows as unknown as Notification[]);
}
