"use server";

import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { prisma } from "@/lib/db";
import { requireAdmin } from "@/lib/admin-guard";
import {
  createArticle,
  deleteArticle,
  publishArticle,
  unpublishArticle,
  updateArticle,
  type ArticleInput,
} from "@/lib/articles-repo";

type FormResult = { ok: true; id: string } | { ok: false; error: string };

function parseTags(raw: string): string[] {
  return raw
    .split(",")
    .map((s) => s.trim())
    .filter(Boolean);
}

function parseDateOrNull(s: string): Date | null {
  if (!s) return null;
  const d = new Date(s);
  return Number.isNaN(d.getTime()) ? null : d;
}

function buildInput(formData: FormData, authorId: string): ArticleInput {
  const status = String(formData.get("status") ?? "draft") as ArticleInput["status"];
  return {
    title: String(formData.get("title") ?? "").trim(),
    slug: String(formData.get("slug") ?? "").trim() || null,
    excerpt: String(formData.get("excerpt") ?? "").trim() || null,
    content: String(formData.get("content") ?? ""),
    coverImage: String(formData.get("coverImage") ?? "").trim() || null,
    status,
    publishedAt: parseDateOrNull(String(formData.get("publishedAt") ?? "")),
    scheduledFor: parseDateOrNull(String(formData.get("scheduledFor") ?? "")),
    metaTitle: String(formData.get("metaTitle") ?? "").trim() || null,
    metaDesc: String(formData.get("metaDesc") ?? "").trim() || null,
    metaKeywords: String(formData.get("metaKeywords") ?? "").trim() || null,
    focusKeyword: String(formData.get("focusKeyword") ?? "").trim() || null,
    canonicalUrl: String(formData.get("canonicalUrl") ?? "").trim() || null,
    noIndex: formData.get("noIndex") === "on",
    categorySlug: String(formData.get("categorySlug") ?? "").trim() || null,
    tags: parseTags(String(formData.get("tags") ?? "")),
    authorId,
    featured: formData.get("featured") === "on",
    pinned: formData.get("pinned") === "on",
    pinOrder: Number(formData.get("pinOrder") ?? 0) || 0,
  };
}

async function logAudit(
  user: { id: string; name: string; email: string },
  action: string,
  target: string,
  meta: Record<string, unknown>,
) {
  await prisma.auditLog.create({
    data: {
      actorId: user.id,
      actorName: user.name,
      actorEmail: user.email,
      source: "admin",
      action,
      target,
      meta: meta as never,
    },
  });
}

export async function createArticleAction(formData: FormData): Promise<FormResult> {
  const user = await requireAdmin();
  const input = buildInput(formData, user.id);
  if (!input.title) return { ok: false, error: "Thiếu tiêu đề." };
  if (!input.content) return { ok: false, error: "Thiếu nội dung." };

  const created = await createArticle(input);
  await logAudit(user, "article.create", created.id, {
    title: created.title,
    slug: created.slug,
    status: created.status,
  });
  revalidatePath("/admin/articles");
  redirect(`/admin/articles/${created.id}`);
}

export async function updateArticleAction(id: string, formData: FormData): Promise<FormResult> {
  const user = await requireAdmin();
  const input = buildInput(formData, user.id);
  if (!input.title) return { ok: false, error: "Thiếu tiêu đề." };
  if (!input.content) return { ok: false, error: "Thiếu nội dung." };

  const updated = await updateArticle({ ...input, id });
  await logAudit(user, "article.update", updated.id, {
    title: updated.title,
    slug: updated.slug,
    status: updated.status,
  });
  revalidatePath("/admin/articles");
  revalidatePath(`/admin/articles/${id}`);
  revalidatePath(`/${updated.slug}`);
  return { ok: true, id: updated.id };
}

export async function publishArticleAction(id: string): Promise<{ ok: boolean; error?: string }> {
  const user = await requireAdmin();
  const a = await publishArticle(id);
  await logAudit(user, "article.publish", id, { slug: a.slug });
  revalidatePath("/admin/articles");
  revalidatePath(`/admin/articles/${id}`);
  revalidatePath(`/${a.slug}`);
  return { ok: true };
}

export async function unpublishArticleAction(id: string): Promise<{ ok: boolean; error?: string }> {
  const user = await requireAdmin();
  const a = await unpublishArticle(id);
  await logAudit(user, "article.unpublish", id, { slug: a.slug });
  revalidatePath("/admin/articles");
  revalidatePath(`/admin/articles/${id}`);
  return { ok: true };
}

export async function deleteArticleAction(id: string): Promise<{ ok: boolean; error?: string }> {
  const user = await requireAdmin();
  const a = await prisma.article.findUnique({ where: { id }, select: { slug: true, title: true } });
  if (!a) return { ok: false, error: "Không tìm thấy bài viết." };
  await deleteArticle(id);
  await logAudit(user, "article.delete", id, a);
  revalidatePath("/admin/articles");
  redirect("/admin/articles");
}

// ===== Bulk actions =====

export async function bulkPublishAction(
  ids: string[],
): Promise<{ ok: boolean; count: number; error?: string }> {
  const user = await requireAdmin();
  if (ids.length === 0) return { ok: false, count: 0, error: "Chưa chọn bài nào." };
  let count = 0;
  for (const id of ids) {
    try {
      await publishArticle(id);
      count++;
    } catch {
      // skip — articles may have been deleted
    }
  }
  await logAudit(user, "article.bulk_publish", "", { ids, count });
  revalidatePath("/admin/articles");
  return { ok: true, count };
}

export async function bulkUnpublishAction(
  ids: string[],
): Promise<{ ok: boolean; count: number; error?: string }> {
  const user = await requireAdmin();
  if (ids.length === 0) return { ok: false, count: 0, error: "Chưa chọn bài nào." };
  let count = 0;
  for (const id of ids) {
    try {
      await unpublishArticle(id);
      count++;
    } catch {}
  }
  await logAudit(user, "article.bulk_unpublish", "", { ids, count });
  revalidatePath("/admin/articles");
  return { ok: true, count };
}

export async function bulkDeleteAction(
  ids: string[],
): Promise<{ ok: boolean; count: number; error?: string }> {
  const user = await requireAdmin();
  if (ids.length === 0) return { ok: false, count: 0, error: "Chưa chọn bài nào." };
  let count = 0;
  for (const id of ids) {
    try {
      await deleteArticle(id);
      count++;
    } catch {}
  }
  await logAudit(user, "article.bulk_delete", "", { ids, count });
  revalidatePath("/admin/articles");
  return { ok: true, count };
}

export async function bulkChangeCategoryAction(
  ids: string[],
  categorySlug: string,
): Promise<{ ok: boolean; count: number; error?: string }> {
  const user = await requireAdmin();
  if (ids.length === 0) return { ok: false, count: 0, error: "Chưa chọn bài nào." };
  if (!categorySlug) return { ok: false, count: 0, error: "Chưa chọn chuyên mục." };

  const cat = await prisma.category.findUnique({ where: { slug: categorySlug } });
  if (!cat) return { ok: false, count: 0, error: "Chuyên mục không tồn tại." };

  const result = await prisma.article.updateMany({
    where: { id: { in: ids } },
    data: { categoryId: cat.id },
  });
  await logAudit(user, "article.bulk_change_category", "", {
    ids,
    count: result.count,
    categorySlug,
  });
  revalidatePath("/admin/articles");
  return { ok: true, count: result.count };
}
