"use server";

import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { prisma } from "@/lib/prisma";
import { hashPassword } from "@/lib/password";
import { requirePermission, ADMIN_ROLES } from "@/lib/permissions";
import { isValidEmail } from "@/lib/customer-otp";

const BASE = "/iv-manage-84x2/settings";

async function getOrCreate<T extends { id: string }>(
  find: () => Promise<T | null>,
  create: () => Promise<T>
): Promise<T> {
  const existing = await find();
  if (existing) return existing;
  return create();
}

// ---------- Store Settings ----------

export async function updateStoreSettings(formData: FormData) {
  await requirePermission("settings", "edit");
  const row = await getOrCreate(
    () => prisma.storeSettings.findFirst(),
    () => prisma.storeSettings.create({ data: {} })
  );
  const maintenanceMode = formData.get("maintenanceMode") === "on";
  const showWhatsAppButton = formData.get("showWhatsAppButton") === "on";
  const salesEnabled = formData.get("salesEnabled") === "on";
  const checkoutPausedMessage = String(formData.get("checkoutPausedMessage") ?? "").trim().slice(0, 500) || null;
  await prisma.storeSettings.update({
    where: { id: row.id },
    data: { maintenanceMode, showWhatsAppButton, salesEnabled, checkoutPausedMessage },
  });
  revalidatePath(BASE);
  revalidatePath("/", "layout");
  redirect(`${BASE}?success=Store+settings+updated.`);
}

// ---------- Company Details ----------

export async function updateCompanyDetails(formData: FormData) {
  await requirePermission("settings", "edit");
  const row = await getOrCreate(
    () => prisma.companyDetails.findFirst(),
    () => prisma.companyDetails.create({ data: {} })
  );
  const field = (name: string) => String(formData.get(name) ?? "").trim() || null;
  const gstin = field("gstin")?.toUpperCase() ?? null;
  const pan = field("pan")?.toUpperCase() ?? null;
  const pincode = field("pincode");

  if (gstin && !/^\d{2}[A-Z]{5}\d{4}[A-Z]\d[A-Z0-9]Z[A-Z0-9]$/.test(gstin)) {
    redirect(`${BASE}/company?error=Enter+a+valid+GSTIN`);
  }
  if (pan && !/^[A-Z]{5}\d{4}[A-Z]$/.test(pan)) {
    redirect(`${BASE}/company?error=Enter+a+valid+PAN`);
  }
  if (pincode && !/^\d{6}$/.test(pincode)) {
    redirect(`${BASE}/company?error=Enter+a+valid+6-digit+pincode`);
  }

  await prisma.companyDetails.update({
    where: { id: row.id },
    data: {
      legalName: field("legalName"),
      gstin,
      pan,
      addressLine1: field("addressLine1"),
      addressLine2: field("addressLine2"),
      city: field("city"),
      state: field("state"),
      pincode,
    },
  });
  revalidatePath(`${BASE}/company`);
  revalidatePath(`${BASE}/gst`);
  revalidatePath(`${BASE}/invoice`);
  redirect(`${BASE}/company?success=Company+details+updated.`);
}

// ---------- GST ----------

export async function updateGstSettings(formData: FormData) {
  await requirePermission("settings", "edit");
  const row = await getOrCreate(
    () => prisma.taxSettings.findFirst(),
    () => prisma.taxSettings.create({ data: {} })
  );
  const gstRateRaw = Number(formData.get("gstRatePercent") ?? 0);
  if (!Number.isFinite(gstRateRaw)) redirect(`${BASE}/gst?error=Enter+a+valid+GST+rate`);
  const gstRatePercent = Math.max(0, Math.min(50, Math.round(gstRateRaw)));
  const pricesIncludeTax = formData.get("pricesIncludeTax") === "on";
  await prisma.taxSettings.update({ where: { id: row.id }, data: { gstRatePercent, pricesIncludeTax } });
  revalidatePath(`${BASE}/gst`);
  revalidatePath("/iv-manage-84x2/reports/tax");
  redirect(`${BASE}/gst?success=GST+settings+updated.`);
}

// ---------- Invoice ----------

export async function updateInvoiceSettings(formData: FormData) {
  await requirePermission("settings", "edit");
  const row = await getOrCreate(
    () => prisma.invoiceSettings.findFirst(),
    () => prisma.invoiceSettings.create({ data: {} })
  );
  const prefix = (String(formData.get("prefix") ?? "INV").trim() || "INV").slice(0, 20);
  const nextNumberRaw = Number(formData.get("nextNumber") ?? 1);
  if (!Number.isFinite(nextNumberRaw)) redirect(`${BASE}/invoice?error=Enter+a+valid+number`);
  const nextNumber = Math.max(1, Math.round(nextNumberRaw));
  await prisma.invoiceSettings.update({ where: { id: row.id }, data: { prefix, nextNumber } });
  revalidatePath(`${BASE}/invoice`);
  redirect(`${BASE}/invoice?success=Invoice+settings+updated.`);
}

// ---------- Notifications ----------

export async function updateNotificationSettings(formData: FormData) {
  await requirePermission("settings", "edit");
  const row = await getOrCreate(
    () => prisma.notificationSettings.findFirst(),
    () => prisma.notificationSettings.create({ data: {} })
  );
  const notifyEmail = String(formData.get("notifyEmail") ?? "").trim() || null;
  if (notifyEmail && !isValidEmail(notifyEmail)) {
    redirect(`${BASE}/notifications?error=Enter+a+valid+email+address`);
  }
  const notifyOnNewOrder = formData.get("notifyOnNewOrder") === "on";
  const notifyOnNewTicket = formData.get("notifyOnNewTicket") === "on";
  await prisma.notificationSettings.update({ where: { id: row.id }, data: { notifyEmail, notifyOnNewOrder, notifyOnNewTicket } });
  revalidatePath(`${BASE}/notifications`);
  redirect(`${BASE}/notifications?success=Notification+settings+updated.`);
}

// ---------- Users & Roles ----------

const ASSIGNABLE_ROLES = ADMIN_ROLES.map((r) => r.value).filter((v) => v !== "super_admin");

export async function createAdminUser(formData: FormData) {
  await requirePermission("settings", "add");
  const email = String(formData.get("email") ?? "").trim().toLowerCase();
  const password = String(formData.get("password") ?? "");
  const role = String(formData.get("role") ?? "");

  if (!email || password.length < 8) {
    redirect(`${BASE}/users?error=Username+and+an+8%2B+character+password+are+required`);
  }
  if (!ASSIGNABLE_ROLES.includes(role as (typeof ASSIGNABLE_ROLES)[number])) {
    redirect(`${BASE}/users?error=Pick+a+valid+role`);
  }
  const existing = await prisma.adminUser.findUnique({ where: { email } });
  if (existing) redirect(`${BASE}/users?error=That+username+already+has+an+account`);

  const { hash, salt } = hashPassword(password);
  await prisma.adminUser.create({ data: { email, passwordHash: hash, passwordSalt: salt, role } });
  revalidatePath(`${BASE}/users`);
  redirect(`${BASE}/users?success=Admin+user+created.`);
}

export async function toggleAdminUser(id: string) {
  await requirePermission("settings", "edit");
  const user = await prisma.adminUser.findUniqueOrThrow({ where: { id } });
  await prisma.adminUser.update({ where: { id }, data: { active: !user.active } });
  revalidatePath(`${BASE}/users`);
  redirect(`${BASE}/users?success=Admin+user+updated.`);
}

export async function deleteAdminUser(id: string) {
  await requirePermission("settings", "delete");
  await prisma.adminUser.delete({ where: { id } });
  revalidatePath(`${BASE}/users`);
  redirect(`${BASE}/users?success=Admin+user+deleted.`);
}
