"use server";

import { redirect } from "next/navigation";
import { revalidatePath } from "next/cache";
import { z } from "zod";
import { eq } from "drizzle-orm";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { db } from "@/db";
import { clients, projects, payments } from "@/db/schema";

async function requireAdmin() {
  const session = await getServerSession(authOptions);
  if (!session) throw new Error("Non autorizzato");
}

function randomAlpha(len: number): string {
  const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  return Array.from({ length: len }, () => chars[Math.floor(Math.random() * chars.length)]).join("");
}

function toSlug(name: string): string {
  const base = name
    .toLowerCase()
    .normalize("NFD")
    .replace(/[̀-ͯ]/g, "")
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "")
    .slice(0, 44);
  return `${base}-${randomAlpha(4)}`;
}

async function uniqueSlug(base: string): Promise<string | null> {
  if (base.length < 3) return null;
  const candidates = [base, ...Array.from({ length: 8 }, (_, i) => `${base.slice(0, 47)}-${i + 2}`)];
  for (const candidate of candidates) {
    const rows = await db.select({ id: clients.id }).from(clients).where(eq(clients.slug, candidate)).limit(1);
    if (rows.length === 0) return candidate;
  }
  return null;
}

const createClientSchema = z.object({
  name: z.string().min(1, "Nome richiesto"),
  brand_name: z.string().min(1, "Nome brand richiesto"),
  brief: z.string().min(1, "Brief richiesto"),
});

export async function createClient(formData: FormData) {
  await requireAdmin();
  const raw = {
    name: formData.get("name") as string,
    brand_name: formData.get("brand_name") as string,
    brief: formData.get("brief") as string,
  };

  const parsed = createClientSchema.safeParse(raw);
  if (!parsed.success) {
    throw new Error(
      parsed.error.issues.map((i) => i.message).join(", ")
    );
  }

  // Auto-generate slug from name (e.g. "Mario Rossi" → "mario-rossi")
  const slug = await uniqueSlug(toSlug(parsed.data.name));

  // Insert client — token and id are auto-generated by $defaultFn(() => nanoid())
  const [newClient] = await db
    .insert(clients)
    .values({
      name: parsed.data.name,
      brand_name: parsed.data.brand_name,
      brief: parsed.data.brief,
      slug,
    })
    .returning({ id: clients.id, token: clients.token, brand_name: clients.brand_name });

  // Create a default project for the client — all work items are project-scoped
  const [newProject] = await db
    .insert(projects)
    .values({
      client_id: newClient.id,
      name: newClient.brand_name,
    })
    .returning({ id: projects.id });

  // Always create two payment stubs per project — Acconto 50% and Saldo 50%
  await db.insert(payments).values([
    {
      project_id: newProject.id,
      label: "Acconto 50%",
      amount: "0",
      status: "da_saldare",
    },
    {
      project_id: newProject.id,
      label: "Saldo 50%",
      amount: "0",
      status: "da_saldare",
    },
  ]);

  revalidatePath("/admin");
  redirect(`/admin/clients/${newClient.id}`);
}