"use server";

import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { eq } from "drizzle-orm";
import { z } from "zod";
import { db } from "@/lib/db/client";
import { teamMembers } from "@/lib/db/schema";
import { requireAdmin } from "@/lib/auth/admin-guard";
import { logAdminAction } from "@/lib/audit";

function slugify(input: string): string {
  return input
    .toLowerCase()
    .trim()
    .replace(/[^a-z0-9\s-]/g, "")
    .replace(/\s+/g, "-")
    .replace(/-+/g, "-")
    .slice(0, 80);
}

async function ensureAdmin() {
  const session = await requireAdmin();
  return (session.user as { id?: string }).id!;
}

const roleValues = ["lead", "committee", "contributor"] as const;
const statusValues = ["active", "archived"] as const;

const createSchema = z.object({
  name: z.string().min(2).max(200),
  title: z.string().max(200).optional(),
  role: z.enum(roleValues).optional(),
});

export async function createTeamMember(formData: FormData) {
  const adminId = await ensureAdmin();
  const parsed = createSchema.parse({
    name: formData.get("name"),
    title: formData.get("title") ?? "",
    role: (formData.get("role") as string) || undefined,
  });

  let slug = slugify(parsed.name) || "member";
  const [existing] = await db
    .select({ id: teamMembers.id })
    .from(teamMembers)
    .where(eq(teamMembers.slug, slug))
    .limit(1);
  if (existing) slug = `${slug}-${Math.random().toString(36).slice(2, 6)}`;

  const siblings = await db.select({ id: teamMembers.id }).from(teamMembers);

  const [row] = await db
    .insert(teamMembers)
    .values({
      slug,
      name: parsed.name,
      title: parsed.title ?? "",
      role: parsed.role ?? "contributor",
      position: siblings.length,
    })
    .returning({ id: teamMembers.id });

  await logAdminAction({
    adminUserId: adminId,
    action: "create_team_member",
    targetId: row.id,
  });

  revalidatePath("/admin/team");
  redirect(`/admin/team/${row.id}`);
}

const updateSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(2).max(200),
  title: z.string().max(200),
  role: z.enum(roleValues),
  bio: z.string().max(10_000),
  photo: z.string().max(400),
  photoAlt: z.string().max(400),
  country: z.string().max(200),
  institution: z.string().max(200),
  orcidUrl: z.string().max(400),
  linkedinUrl: z.string().max(400),
  websiteUrl: z.string().max(400),
  position: z.coerce.number().int().min(0).max(1000),
});

export async function updateTeamMember(formData: FormData) {
  const adminId = await ensureAdmin();
  const parsed = updateSchema.parse({
    id: formData.get("id"),
    name: formData.get("name") ?? "",
    title: formData.get("title") ?? "",
    role: formData.get("role") ?? "contributor",
    bio: formData.get("bio") ?? "",
    photo: formData.get("photo") ?? "",
    photoAlt: formData.get("photoAlt") ?? "",
    country: formData.get("country") ?? "",
    institution: formData.get("institution") ?? "",
    orcidUrl: formData.get("orcidUrl") ?? "",
    linkedinUrl: formData.get("linkedinUrl") ?? "",
    websiteUrl: formData.get("websiteUrl") ?? "",
    position: formData.get("position") ?? 0,
  });

  await db
    .update(teamMembers)
    .set({
      name: parsed.name,
      title: parsed.title,
      role: parsed.role,
      bio: parsed.bio,
      photo: parsed.photo || null,
      photoAlt: parsed.photoAlt || null,
      country: parsed.country,
      institution: parsed.institution,
      orcidUrl: parsed.orcidUrl || null,
      linkedinUrl: parsed.linkedinUrl || null,
      websiteUrl: parsed.websiteUrl || null,
      position: parsed.position,
      updatedAt: new Date(),
    })
    .where(eq(teamMembers.id, parsed.id));

  await logAdminAction({
    adminUserId: adminId,
    action: "update_team_member",
    targetId: parsed.id,
  });

  revalidatePath("/admin/team");
  revalidatePath(`/admin/team/${parsed.id}`);
  revalidatePath("/team");
}

const setStatusSchema = z.object({
  id: z.string().uuid(),
  status: z.enum(statusValues),
});

export async function setTeamMemberStatus(formData: FormData) {
  const adminId = await ensureAdmin();
  const parsed = setStatusSchema.parse({
    id: formData.get("id"),
    status: formData.get("status"),
  });

  await db
    .update(teamMembers)
    .set({ status: parsed.status, updatedAt: new Date() })
    .where(eq(teamMembers.id, parsed.id));

  await logAdminAction({
    adminUserId: adminId,
    action: `team_member_${parsed.status}`,
    targetId: parsed.id,
  });

  revalidatePath("/admin/team");
  revalidatePath(`/admin/team/${parsed.id}`);
  revalidatePath("/team");
}

export async function deleteTeamMember(formData: FormData) {
  const adminId = await ensureAdmin();
  const id = z.string().uuid().parse(formData.get("id"));
  await db.delete(teamMembers).where(eq(teamMembers.id, id));
  await logAdminAction({
    adminUserId: adminId,
    action: "delete_team_member",
    targetId: id,
  });
  revalidatePath("/admin/team");
  revalidatePath("/team");
  redirect("/admin/team");
}
