"use server";

import { revalidatePath } from "next/cache";
import type { z } from "zod";

import { ActionError, runAction, type ActionResult } from "@/lib/actions";
import { refreshWebsite } from "@/lib/site";
import { requireActionAdmin } from "@/lib/auth/guards";
import { cmsMessage, cmsPaths, cmsRequest } from "@/lib/cms/api";
import { cleanText } from "@/lib/utils";

import { blogDefaultsSchema, type BlogDefaults } from "./schemas";

export async function saveBlogDefaults(
  input: z.input<typeof blogDefaultsSchema>,
): Promise<ActionResult> {
  return runAction(async () => {
    await requireActionAdmin("ADMIN");
    const parsed = blogDefaultsSchema.parse(input);

    const values: BlogDefaults = {
      ...parsed,
      ctaTitle: cleanText(parsed.ctaTitle),
      ctaDescription: cleanText(parsed.ctaDescription),
      ctaButtonText: cleanText(parsed.ctaButtonText),
      ctaButtonUrl: cleanText(parsed.ctaButtonUrl),
      ctaImage: parsed.ctaImage || null,
      defaultAuthorId: parsed.defaultAuthorId || null,
      defaultCategoryId: parsed.defaultCategoryId || null,
    };

    const fieldErrors: Record<string, string> = {};
    if (
      values.ctaImage &&
      !/^\/uploads\//.test(values.ctaImage) &&
      !/^https?:\/\/\S+$/i.test(values.ctaImage)
    ) {
      fieldErrors.ctaImage = "Choose an image from the media library.";
    }
    // Articles can't be published with an incomplete CTA, so don't make it the default.
    if (values.ctaEnabled) {
      if (!values.ctaTitle)
        fieldErrors.ctaTitle = "Add a title, or turn the CTA off by default.";
      if (!values.ctaButtonText) {
        fieldErrors.ctaButtonText =
          "Add button text, or turn the CTA off by default.";
      }
      if (!values.ctaButtonUrl) {
        fieldErrors.ctaButtonUrl =
          "Add a button URL, or turn the CTA off by default.";
      }
    }

    // Laravel checks that the default author and category exist and are active.
    if (Object.keys(fieldErrors).length > 0) {
      throw new ActionError(Object.values(fieldErrors)[0], 400, fieldErrors);
    }

    const body = await cmsRequest(cmsPaths.blogDefaults, {
      method: "PUT",
      json: values,
    });

    revalidatePath("/admin/settings");
    refreshWebsite();
    return {
      ok: true,
      message: cmsMessage(
        body,
        "Blog defaults saved. New articles will start with them.",
      ),
    };
  });
}
