"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 { atlasRegions, atlasConditions } 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 statusValues = ["draft", "published", "archived"] as const;
const categoryValues = [
  "Degenerative",
  "Traumatic",
  "Inflammatory",
  "Congenital",
  "Infectious",
  "Neoplastic",
] as const;

// -------------------------------------------------------------------------
// Regions
// -------------------------------------------------------------------------

const createRegionSchema = z.object({
  name: z.string().min(2).max(200),
  slug: z.string().max(80).optional(),
});

export async function createRegion(formData: FormData) {
  const adminId = await ensureAdmin();
  const parsed = createRegionSchema.parse({
    name: formData.get("name"),
    slug: formData.get("slug") ?? "",
  });

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

  const [row] = await db
    .insert(atlasRegions)
    .values({ slug, name: parsed.name })
    .returning({ id: atlasRegions.id });

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

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

const updateRegionSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(2).max(200),
  slug: z.string().min(1).max(80),
  summary: z.string().max(2000),
  icon: z.string().max(80),
  photoUrl: z.string().max(500),
  photoAlt: z.string().max(500),
  status: z.enum(statusValues),
  position: z.coerce.number().int().min(0).max(1000),
});

export async function updateRegion(formData: FormData) {
  const adminId = await ensureAdmin();
  const parsed = updateRegionSchema.parse({
    id: formData.get("id"),
    name: formData.get("name") ?? "",
    slug: formData.get("slug") ?? "",
    summary: formData.get("summary") ?? "",
    icon: formData.get("icon") ?? "",
    photoUrl: formData.get("photoUrl") ?? "",
    photoAlt: formData.get("photoAlt") ?? "",
    status: formData.get("status") ?? "published",
    position: formData.get("position") ?? 0,
  });

  await db
    .update(atlasRegions)
    .set({
      name: parsed.name,
      slug: parsed.slug,
      summary: parsed.summary,
      icon: parsed.icon || null,
      photoUrl: parsed.photoUrl || null,
      photoAlt: parsed.photoAlt || null,
      status: parsed.status,
      position: parsed.position,
      updatedAt: new Date(),
    })
    .where(eq(atlasRegions.id, parsed.id));

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

  revalidatePath("/admin/atlas");
  revalidatePath(`/admin/atlas/regions/${parsed.id}`);
  revalidatePath("/products/atlas/regions");
  revalidatePath(`/products/atlas/regions/${parsed.slug}`);
}

export async function deleteRegion(formData: FormData) {
  const adminId = await ensureAdmin();
  const id = z.string().uuid().parse(formData.get("id"));
  await db.delete(atlasRegions).where(eq(atlasRegions.id, id));
  await logAdminAction({
    adminUserId: adminId,
    action: "delete_atlas_region",
    targetId: id,
  });
  revalidatePath("/admin/atlas");
  revalidatePath("/products/atlas/regions");
  redirect("/admin/atlas");
}

// -------------------------------------------------------------------------
// Conditions
// -------------------------------------------------------------------------

const createConditionSchema = z.object({
  name: z.string().min(2).max(200),
  regionSlug: z.string().min(1).max(80),
  category: z.enum(categoryValues),
});

export async function createCondition(formData: FormData) {
  const adminId = await ensureAdmin();
  const parsed = createConditionSchema.parse({
    name: formData.get("name"),
    regionSlug: formData.get("regionSlug") ?? "",
    category: formData.get("category") ?? "Degenerative",
  });

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

  const [row] = await db
    .insert(atlasConditions)
    .values({
      slug,
      name: parsed.name,
      regionSlug: parsed.regionSlug,
      category: parsed.category,
      status: "draft",
    })
    .returning({ id: atlasConditions.id });

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

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

const updateConditionSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(2).max(200),
  slug: z.string().min(1).max(80),
  regionSlug: z.string().min(1).max(80),
  category: z.enum(categoryValues),
  summary: z.string().max(2000),
  overview: z.string().max(8000),
  epidemiology: z.string().max(4000),
  symptoms: z.string().max(4000),
  imaging: z.string().max(4000),
  classification: z.string().max(4000),
  management: z.string().max(6000),
  outcomes: z.string().max(4000),
  referencesList: z.string().max(4000),
  status: z.enum(statusValues),
  position: z.coerce.number().int().min(0).max(10_000),
});

export async function updateCondition(formData: FormData) {
  const adminId = await ensureAdmin();
  const parsed = updateConditionSchema.parse({
    id: formData.get("id"),
    name: formData.get("name") ?? "",
    slug: formData.get("slug") ?? "",
    regionSlug: formData.get("regionSlug") ?? "",
    category: formData.get("category") ?? "Degenerative",
    summary: formData.get("summary") ?? "",
    overview: formData.get("overview") ?? "",
    epidemiology: formData.get("epidemiology") ?? "",
    symptoms: formData.get("symptoms") ?? "",
    imaging: formData.get("imaging") ?? "",
    classification: formData.get("classification") ?? "",
    management: formData.get("management") ?? "",
    outcomes: formData.get("outcomes") ?? "",
    referencesList: formData.get("referencesList") ?? "",
    status: formData.get("status") ?? "published",
    position: formData.get("position") ?? 0,
  });

  const references = parsed.referencesList
    .split("\n")
    .map((l) => l.trim())
    .filter(Boolean);

  await db
    .update(atlasConditions)
    .set({
      name: parsed.name,
      slug: parsed.slug,
      regionSlug: parsed.regionSlug,
      category: parsed.category,
      summary: parsed.summary,
      sections: {
        overview: parsed.overview,
        epidemiology: parsed.epidemiology,
        symptoms: parsed.symptoms,
        imaging: parsed.imaging,
        classification: parsed.classification,
        management: parsed.management,
        outcomes: parsed.outcomes,
      },
      referencesList: references,
      status: parsed.status,
      position: parsed.position,
      updatedAt: new Date(),
    })
    .where(eq(atlasConditions.id, parsed.id));

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

  revalidatePath("/admin/atlas");
  revalidatePath(`/admin/atlas/conditions/${parsed.id}`);
  revalidatePath("/products/atlas/conditions");
  revalidatePath(`/products/atlas/conditions/${parsed.slug}`);
}

export async function deleteCondition(formData: FormData) {
  const adminId = await ensureAdmin();
  const id = z.string().uuid().parse(formData.get("id"));
  await db.delete(atlasConditions).where(eq(atlasConditions.id, id));
  await logAdminAction({
    adminUserId: adminId,
    action: "delete_atlas_condition",
    targetId: id,
  });
  revalidatePath("/admin/atlas");
  revalidatePath("/products/atlas/conditions");
  redirect("/admin/atlas");
}
