"use server";

import { revalidatePath } from "next/cache";
import { AppwriteException, Query } from "node-appwrite";

import { DATABASE_ID, TABLES, type Notification } from "./schema";
import { createAdminClient } from "./server";
import { requireTenant } from "./tenant-guard";
import type { NotificationActionState } from "./notification-types";

function appwriteError(e: unknown, fallback = "Beklenmeyen bir hata oluştu."): string {
  if (e instanceof AppwriteException) return e.message || fallback;
  return process.env.NODE_ENV !== "production" && e instanceof Error
    ? `${fallback} (${e.message})`
    : fallback;
}

export async function markNotificationReadAction(
  _prev: NotificationActionState,
  formData: FormData,
): Promise<NotificationActionState> {
  const id = String(formData.get("id") ?? "").trim();
  if (!id) return { ok: false, error: "Bildirim bulunamadı." };

  let ctx;
  try {
    ctx = await requireTenant();
  } catch {
    return { ok: false, error: "Oturum yok." };
  }

  try {
    const { tablesDB } = createAdminClient();
    const row = (await tablesDB.getRow(
      DATABASE_ID,
      TABLES.notifications,
      id,
    )) as unknown as Notification;
    if (row.tenantId !== ctx.tenantId) return { ok: false, error: "Yetki yok." };
    if (row.read) return { ok: true };
    await tablesDB.updateRow(DATABASE_ID, TABLES.notifications, id, { read: true });
  } catch (e) {
    return { ok: false, error: appwriteError(e, "İşaretlenemedi.") };
  }

  revalidatePath("/notifications");
  return { ok: true };
}

export async function markAllNotificationsReadAction(): Promise<NotificationActionState> {
  let ctx;
  try {
    ctx = await requireTenant();
  } catch {
    return { ok: false, error: "Oturum yok." };
  }

  try {
    const { tablesDB } = createAdminClient();
    const result = await tablesDB.listRows({
      databaseId: DATABASE_ID,
      tableId: TABLES.notifications,
      queries: [
        Query.equal("tenantId", ctx.tenantId),
        Query.equal("read", false),
        Query.limit(100),
      ],
    });
    await Promise.allSettled(
      (result.rows as unknown as Notification[]).map((row) =>
        tablesDB.updateRow(DATABASE_ID, TABLES.notifications, row.$id, { read: true }),
      ),
    );
  } catch (e) {
    return { ok: false, error: appwriteError(e, "İşaretlenemedi.") };
  }

  revalidatePath("/notifications");
  return { ok: true };
}
