"use server";

import { revalidatePath } from "next/cache";
import { ID, Permission, Role } from "node-appwrite";
import { InputFile } from "node-appwrite/file";

import { logAudit } from "./audit";
import type { LogoActionState } from "./logo-types";
import { BUCKETS, DATABASE_ID, TABLES } from "./schema";
import { createAdminClient } from "./server";
import { requireRole, requireTenant } from "./tenant-guard";

const MAX_BYTES = 2 * 1024 * 1024;
const ALLOWED_TYPES = new Set([
  "image/png",
  "image/jpeg",
  "image/jpg",
  "image/webp",
  "image/svg+xml",
]);

function teamLogoPermissions(tenantId: string) {
  return [
    Permission.read(Role.any()),
    Permission.update(Role.team(tenantId, "owner")),
    Permission.update(Role.team(tenantId, "admin")),
    Permission.delete(Role.team(tenantId, "owner")),
    Permission.delete(Role.team(tenantId, "admin")),
  ];
}

export async function uploadLogoAction(
  _prev: LogoActionState,
  formData: FormData,
): Promise<LogoActionState> {
  let ctx;
  try {
    ctx = await requireTenant();
    requireRole(ctx, ["owner", "admin"]);
  } catch {
    return { ok: false, error: "Logo yüklemek için yönetici yetkisi gerekli." };
  }

  const file = formData.get("logo");
  if (!(file instanceof File) || file.size === 0) {
    return { ok: false, error: "Dosya seçin." };
  }

  if (file.size > MAX_BYTES) {
    return { ok: false, error: "Dosya 2MB'dan büyük olamaz." };
  }
  if (!ALLOWED_TYPES.has(file.type)) {
    return { ok: false, error: "Sadece PNG, JPG, WebP veya SVG yükleyebilirsiniz." };
  }
  if (!ctx.settings) {
    return { ok: false, error: "Çalışma alanı ayarları bulunamadı." };
  }

  const { storage, tablesDB } = createAdminClient();
  const previousLogoId = ctx.settings.logo;

  let newFileId: string | null = null;
  try {
    const buffer = Buffer.from(await file.arrayBuffer());
    const inputFile = InputFile.fromBuffer(buffer, file.name);

    const created = await storage.createFile({
      bucketId: BUCKETS.tenantLogos,
      fileId: ID.unique(),
      file: inputFile,
      permissions: teamLogoPermissions(ctx.tenantId),
    });
    newFileId = created.$id;

    await tablesDB.updateRow(DATABASE_ID, TABLES.tenantSettings, ctx.settings.$id, {
      logo: newFileId,
    });

    if (previousLogoId && previousLogoId !== newFileId) {
      try {
        await storage.deleteFile({
          bucketId: BUCKETS.tenantLogos,
          fileId: previousLogoId,
        });
      } catch {
        // best-effort — orphaned file is acceptable, won't block the new logo
      }
    }

    await logAudit({
      tenantId: ctx.tenantId,
      userId: ctx.user.id,
      action: "update",
      entityType: "tenant_logo",
      entityId: newFileId,
      changes: { previous: previousLogoId ?? null },
    });
  } catch (e) {
    if (newFileId) {
      try {
        await storage.deleteFile({
          bucketId: BUCKETS.tenantLogos,
          fileId: newFileId,
        });
      } catch {
        /* ignore cleanup error */
      }
    }
    return {
      ok: false,
      error: e instanceof Error ? e.message : "Logo yüklenemedi.",
    };
  }

  revalidatePath("/settings/workspace");
  revalidatePath("/", "layout");
  return { ok: true };
}

export async function removeLogoAction(): Promise<LogoActionState> {
  let ctx;
  try {
    ctx = await requireTenant();
    requireRole(ctx, ["owner", "admin"]);
  } catch {
    return { ok: false, error: "Logo silmek için yönetici yetkisi gerekli." };
  }

  if (!ctx.settings) {
    return { ok: false, error: "Çalışma alanı ayarları bulunamadı." };
  }

  const previousLogoId = ctx.settings.logo;
  if (!previousLogoId) {
    return { ok: true };
  }

  try {
    const { storage, tablesDB } = createAdminClient();

    await tablesDB.updateRow(DATABASE_ID, TABLES.tenantSettings, ctx.settings.$id, {
      logo: null,
    });

    try {
      await storage.deleteFile({
        bucketId: BUCKETS.tenantLogos,
        fileId: previousLogoId,
      });
    } catch {
      /* file already gone, fine */
    }

    await logAudit({
      tenantId: ctx.tenantId,
      userId: ctx.user.id,
      action: "delete",
      entityType: "tenant_logo",
      entityId: previousLogoId,
    });
  } catch (e) {
    return {
      ok: false,
      error: e instanceof Error ? e.message : "Logo silinemedi.",
    };
  }

  revalidatePath("/settings/workspace");
  revalidatePath("/", "layout");
  return { ok: true };
}
