"use server";

import { revalidatePath } from "next/cache";
import { AppwriteException, ID, Permission, Query, Role } from "node-appwrite";
import { z } from "zod";

import { logAudit } from "./audit";
import { DATABASE_ID, TABLES, type TenantSettings } from "./schema";
import { createAdminClient } from "./server";
import { requireRole, requireTenant } from "./tenant-guard";
import type { WorkspaceSettingsState } from "./workspace-types";
import { workspaceSettingsSchema } from "@/lib/validation/workspace";

function appwriteError(e: unknown): string {
  if (e instanceof AppwriteException) return e.message || "Beklenmeyen hata.";
  return "Bağlantı hatası. Tekrar deneyin.";
}

function flattenErrors(err: z.ZodError): Record<string, string> {
  const out: Record<string, string> = {};
  for (const issue of err.issues) {
    const key = issue.path.join(".");
    if (key && !out[key]) out[key] = issue.message;
  }
  return out;
}

function pickFormFields(formData: FormData) {
  return {
    companyName: String(formData.get("companyName") ?? "").trim(),
    companyTaxId: String(formData.get("companyTaxId") ?? "").trim(),
    companyAddress: String(formData.get("companyAddress") ?? "").trim(),
    companyEmail: String(formData.get("companyEmail") ?? "").trim(),
    companyPhone: String(formData.get("companyPhone") ?? "").trim(),
    defaultCurrency: String(formData.get("defaultCurrency") ?? "").trim(),
  };
}

export async function updateWorkspaceSettingsAction(
  _prev: WorkspaceSettingsState,
  formData: FormData,
): Promise<WorkspaceSettingsState> {
  let ctx;
  try {
    ctx = await requireTenant();
    requireRole(ctx, ["owner", "admin"]);
  } catch {
    return { ok: false, error: "Düzenleme yetkiniz yok." };
  }

  const parsed = workspaceSettingsSchema.safeParse(pickFormFields(formData));
  if (!parsed.success) {
    return { ok: false, error: "Form geçersiz.", fieldErrors: flattenErrors(parsed.error) };
  }

  try {
    const { tablesDB } = createAdminClient();

    const existing = await tablesDB.listRows({
      databaseId: DATABASE_ID,
      tableId: TABLES.tenantSettings,
      queries: [Query.equal("tenantId", ctx.tenantId), Query.limit(1)],
    });
    const row = existing.rows[0] as unknown as TenantSettings | undefined;

    if (row) {
      await tablesDB.updateRow(DATABASE_ID, TABLES.tenantSettings, row.$id, parsed.data);
      await logAudit({
        tenantId: ctx.tenantId,
        userId: ctx.user.id,
        action: "update",
        entityType: "tenant_settings",
        entityId: row.$id,
        changes: parsed.data,
      });
    } else {
      const created = await tablesDB.createRow(
        DATABASE_ID,
        TABLES.tenantSettings,
        ID.unique(),
        { tenantId: ctx.tenantId, ...parsed.data },
        [
          Permission.read(Role.team(ctx.tenantId)),
          Permission.update(Role.team(ctx.tenantId, "owner")),
          Permission.update(Role.team(ctx.tenantId, "admin")),
          Permission.delete(Role.team(ctx.tenantId, "owner")),
        ],
      );
      await logAudit({
        tenantId: ctx.tenantId,
        userId: ctx.user.id,
        action: "create",
        entityType: "tenant_settings",
        entityId: created.$id,
        changes: parsed.data,
      });
    }
  } catch (e) {
    return { ok: false, error: appwriteError(e) };
  }

  // Tenant name shows up everywhere — revalidate broadly
  revalidatePath("/", "layout");
  return { ok: true };
}
