import { beforeEach, describe, expect, it, vi } from "vitest";

vi.mock("next/cache", async () => ({ revalidatePath: (await import("@/tests/helpers/next-mocks")).revalidatePath }));
vi.mock("next/navigation", async () => ({ redirect: (await import("@/tests/helpers/next-mocks")).redirect }));
vi.mock("next/dist/client/components/redirect-error", async () => ({
  isRedirectError: (await import("@/tests/helpers/next-mocks")).isRedirectError,
}));
vi.mock("@/lib/admin-auth", async () => {
  const m = await import("@/tests/helpers/next-mocks");
  return { isAdminAuthenticated: m.isAdminAuthenticated, clearAdminSessionCookie: m.clearAdminSessionCookie };
});

import {
  saveSiteBrandSettingsAction,
  saveSiteLocalizationSettingsAction,
} from "@/app/_admin/site-settings/actions";
import { getSiteSettings, getSiteSettingsMediaBindings } from "@/lib/app-config";
import { adminAuth, captureRedirect, formDataFrom, resetNextMocks } from "@/tests/helpers/next-mocks";

beforeEach(() => {
  resetNextMocks();
});

describe("saveSiteBrandSettingsAction", () => {
  it("saves a normalized primary color", async () => {
    const url = await captureRedirect(() => saveSiteBrandSettingsAction(formDataFrom({ primaryColor: "#123456" })));
    expect(url).toContain("success=");
    expect((await getSiteSettings()).brand.primaryColor).toBe("#123456");
  });

  it("falls back to the default color for invalid input", async () => {
    await captureRedirect(() => saveSiteBrandSettingsAction(formDataFrom({ primaryColor: "not-a-color" })));
    expect((await getSiteSettings()).brand.primaryColor).toBe("#dc5a35");
  });

  it("wires an external favicon into media bindings", async () => {
    const faviconMedia = JSON.stringify({ mode: "external", url: "https://cdn/f.svg", kind: "IMAGE", label: "F" });
    const url = await captureRedirect(() =>
      saveSiteBrandSettingsAction(formDataFrom({ primaryColor: "#222222", faviconMedia })),
    );
    expect(url).toContain("success=");
    const bindings = await getSiteSettingsMediaBindings();
    expect(bindings.favicon?.url).toBe("https://cdn/f.svg");
  });

  it("errors on an invalid media json payload", async () => {
    const url = await captureRedirect(() =>
      saveSiteBrandSettingsAction(formDataFrom({ primaryColor: "#222222", faviconMedia: "{not json" })),
    );
    expect(url).toContain("error=");
  });

  it("redirects unauthenticated callers to the admin root", async () => {
    adminAuth.authenticated = false;
    const url = await captureRedirect(() => saveSiteBrandSettingsAction(formDataFrom({ primaryColor: "#123456" })));
    expect(url).toBe("/");
  });
});

const localizationForm = {
  defaultLocale: "en",
  siteNameAr: "الموقع",
  siteNameEn: "The Site",
  siteNameDe: "Die Seite",
  titleTemplateAr: "{pageTitle} | {siteName}",
  titleTemplateEn: "{pageTitle} | {siteName}",
  titleTemplateDe: "{pageTitle} | {siteName}",
  siteDescriptionAr: "وصف",
  siteDescriptionEn: "Description",
  siteDescriptionDe: "Beschreibung",
  subheadAr: "",
  subheadEn: "",
  subheadDe: "",
};

describe("saveSiteLocalizationSettingsAction", () => {
  it("saves valid localization settings and the default locale", async () => {
    const url = await captureRedirect(() => saveSiteLocalizationSettingsAction(formDataFrom(localizationForm)));
    expect(url).toContain("success=");
    const settings = await getSiteSettings();
    expect(settings.defaultLocale).toBe("en");
    expect(settings.locales.en.siteName).toBe("The Site");
  });

  it("requires a site name for every locale", async () => {
    const url = await captureRedirect(() =>
      saveSiteLocalizationSettingsAction(formDataFrom({ ...localizationForm, siteNameEn: "" })),
    );
    expect(url).toContain("error=");
  });

  it("requires the {pageTitle} token in every title template", async () => {
    const url = await captureRedirect(() =>
      saveSiteLocalizationSettingsAction(formDataFrom({ ...localizationForm, titleTemplateDe: "{siteName} only" })),
    );
    expect(url).toContain("error=");
  });

  it("redirects unauthenticated callers to the admin root", async () => {
    adminAuth.authenticated = false;
    const url = await captureRedirect(() => saveSiteLocalizationSettingsAction(formDataFrom(localizationForm)));
    expect(url).toBe("/");
  });
});
