"use server";

import { auth } from "@/auth";
import { db } from "@/lib/db";
import { hasPermission } from "@/lib/permissions";
import { buildSignatureKey, uploadBuffer } from "@/lib/storage";
import { revalidatePath } from "next/cache";
import bcrypt from "bcryptjs";
import { z } from "zod";

type Result = { ok: true } | { error: string };

// ── Change password ───────────────────────────────────────────────────────────

const changePasswordSchema = z.object({
  currentPassword: z.string().optional(),
  newPassword: z.string().min(8, "New password must be at least 8 characters"),
});

export async function changePassword(formData: FormData): Promise<Result> {
  const session = await auth();
  if (!session?.user) return { error: "Unauthorized" };

  const parsed = changePasswordSchema.safeParse({
    currentPassword: formData.get("currentPassword"),
    newPassword: formData.get("newPassword"),
  });
  if (!parsed.success) return { error: parsed.error.errors[0]?.message ?? "Validation failed" };

  const user = await db.user.findUnique({
    where: { id: session.user.id },
    select: { passwordHash: true },
  });
  if (!user) return { error: "User not found" };

  if (user.passwordHash) {
    if (!parsed.data.currentPassword) return { error: "Current password is required." };
    const valid = await bcrypt.compare(parsed.data.currentPassword, user.passwordHash);
    if (!valid) return { error: "Current password is incorrect." };
  }

  const newHash = await bcrypt.hash(parsed.data.newPassword, 12);
  await db.user.update({
    where: { id: session.user.id },
    data: { passwordHash: newHash },
  });

  return { ok: true };
}

// ── Upload signature ──────────────────────────────────────────────────────────

export async function saveSignature(formData: FormData): Promise<Result> {
  const session = await auth();
  if (!session?.user) return { error: "Unauthorized" };

  if (!hasPermission(session.user.role, "approve_po")) {
    return { error: "Only approvers can upload a signature" };
  }

  const file = formData.get("signature") as File | null;
  if (!file || file.size === 0) return { error: "No file provided" };
  if (file.size > 2 * 1024 * 1024) return { error: "Signature must be under 2 MB" };

  const allowed = ["image/png", "image/jpeg", "image/jpg", "image/webp"];
  if (!allowed.includes(file.type)) {
    return { error: "Signature must be a PNG, JPG, or WebP image" };
  }

  const ext = file.type === "image/png" ? "png" : file.type === "image/webp" ? "webp" : "jpg";
  const key = buildSignatureKey(session.user.id, ext);
  const buffer = Buffer.from(await file.arrayBuffer());

  await uploadBuffer(key, buffer, file.type);

  await db.user.update({
    where: { id: session.user.id },
    data: { signatureKey: key },
  });

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

// ── Remove signature ──────────────────────────────────────────────────────────

export async function removeSignature(): Promise<Result> {
  const session = await auth();
  if (!session?.user) return { error: "Unauthorized" };

  await db.user.update({
    where: { id: session.user.id },
    data: { signatureKey: null },
  });

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

// ── Request SuperUser access ──────────────────────────────────────────────────

export async function requestSuperUser(formData: FormData): Promise<Result> {
  const session = await auth();
  if (!session?.user) return { error: "Unauthorized" };

  if (session.user.role === "SUPERUSER" || session.user.role === "ADMIN") {
    return { error: "You already have elevated access" };
  }

  const reason = (formData.get("reason") as string | null)?.trim() ?? "";

  // Check for an existing pending request
  const existing = await db.superUserRequest.findFirst({
    where: { userId: session.user.id, status: "PENDING" },
  });
  if (existing) return { error: "You already have a pending SuperUser request" };

  await db.superUserRequest.create({
    data: {
      userId: session.user.id,
      reason: reason || null,
    },
  });

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