"use server";

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

import { logAudit } from "./audit";
import { DATABASE_ID, TABLES, type FinanceEntry } from "./schema";
import { createAdminClient } from "./server";
import { requireRole, requireTenant } from "./tenant-guard";
import type { FinanceActionState } from "./finance-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;
}

async function loadEntryForTenant(
  id: string,
  tenantId: string,
): Promise<FinanceEntry | null> {
  try {
    const { tablesDB } = createAdminClient();
    const row = await tablesDB.getRow(DATABASE_ID, TABLES.financeEntries, id);
    const entry = row as unknown as FinanceEntry;
    if (entry.tenantId !== tenantId) return null;
    return entry;
  } catch {
    return null;
  }
}

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

  let ctx;
  try {
    ctx = await requireTenant();
    requireRole(ctx, ["owner", "admin"]);
  } catch {
    return { ok: false, error: "Bu işlem için yetkiniz yok." };
  }

  const entry = await loadEntryForTenant(id, ctx.tenantId);
  if (!entry) return { ok: false, error: "Kayıt bulunamadı." };
  if (entry.status === "paid") return { ok: false, error: "Bu kayıt zaten ödenmiş." };

  try {
    const { tablesDB } = createAdminClient();
    await tablesDB.updateRow(DATABASE_ID, TABLES.financeEntries, id, {
      status: "paid",
    });
    await logAudit({
      tenantId: ctx.tenantId,
      userId: ctx.user.id,
      action: "update",
      entityType: "finance_entry",
      entityId: id,
      changes: { status: "paid" },
    });
  } catch (e) {
    return { ok: false, error: appwriteError(e, "Güncellenemedi.") };
  }

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

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

  let ctx;
  try {
    ctx = await requireTenant();
    requireRole(ctx, ["owner", "admin"]);
  } catch {
    return { ok: false, error: "Bu işlem için yetkiniz yok." };
  }

  const entry = await loadEntryForTenant(id, ctx.tenantId);
  if (!entry) return { ok: false, error: "Kayıt bulunamadı." };
  if (entry.status === "pending") return { ok: false, error: "Bu kayıt zaten bekliyor." };

  try {
    const { tablesDB } = createAdminClient();
    await tablesDB.updateRow(DATABASE_ID, TABLES.financeEntries, id, {
      status: "pending",
    });
    await logAudit({
      tenantId: ctx.tenantId,
      userId: ctx.user.id,
      action: "update",
      entityType: "finance_entry",
      entityId: id,
      changes: { status: "pending" },
    });
  } catch (e) {
    return { ok: false, error: appwriteError(e, "Güncellenemedi.") };
  }

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