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

import {
  DEFAULT_SITE_PRIMARY_COLOR,
  buildDefaultSiteSettings,
  normalizeSiteDefaultLocale,
  normalizeSitePrimaryColor,
  parseSiteSettingsValue,
} from "@/lib/site-settings";

describe("normalizeSiteDefaultLocale", () => {
  it("keeps the three supported locales", () => {
    expect(normalizeSiteDefaultLocale("ar")).toBe("ar");
    expect(normalizeSiteDefaultLocale("en")).toBe("en");
    expect(normalizeSiteDefaultLocale("de")).toBe("de");
  });

  it("defaults to de for anything else", () => {
    expect(normalizeSiteDefaultLocale("fr")).toBe("de");
    expect(normalizeSiteDefaultLocale(undefined)).toBe("de");
    expect(normalizeSiteDefaultLocale(123)).toBe("de");
  });
});

describe("normalizeSitePrimaryColor", () => {
  it("accepts and lowercases 6-digit hex", () => {
    expect(normalizeSitePrimaryColor("#AABBCC")).toBe("#aabbcc");
    expect(normalizeSitePrimaryColor("  #112233 ")).toBe("#112233");
  });

  it("rejects invalid colors", () => {
    expect(normalizeSitePrimaryColor("red")).toBe(DEFAULT_SITE_PRIMARY_COLOR);
    expect(normalizeSitePrimaryColor("#abc")).toBe(DEFAULT_SITE_PRIMARY_COLOR);
    expect(normalizeSitePrimaryColor("#12345g")).toBe(DEFAULT_SITE_PRIMARY_COLOR);
    expect(normalizeSitePrimaryColor(42)).toBe(DEFAULT_SITE_PRIMARY_COLOR);
    expect(normalizeSitePrimaryColor(null)).toBe(DEFAULT_SITE_PRIMARY_COLOR);
  });
});

describe("buildDefaultSiteSettings", () => {
  it("uses the fallback name across all locales", () => {
    const settings = buildDefaultSiteSettings("Studio Moh");
    expect(settings.defaultLocale).toBe("de");
    expect(settings.brand.primaryColor).toBe(DEFAULT_SITE_PRIMARY_COLOR);
    expect(settings.locales.ar.siteName).toBe("Studio Moh");
    expect(settings.locales.en.titleTemplate).toBe("{pageTitle} | {siteName}");
    expect(settings.locales.de.subhead).toBe("");
  });
});

describe("parseSiteSettingsValue", () => {
  it("returns defaults for empty input", () => {
    expect(parseSiteSettingsValue(null, "Fallback")).toEqual(buildDefaultSiteSettings("Fallback"));
  });

  it("returns defaults for invalid json", () => {
    expect(parseSiteSettingsValue("{bad", "Fallback")).toEqual(buildDefaultSiteSettings("Fallback"));
  });

  it("merges stored values with safe defaults", () => {
    const settings = parseSiteSettingsValue(
      JSON.stringify({
        defaultLocale: "ar",
        brand: { primaryColor: "#112233" },
        locales: {
          en: { siteName: "Brand EN", titleTemplate: "{pageTitle} - {siteName}", siteDescription: "English" },
          de: { siteName: "Brand DE", subhead: "Sub" },
        },
      }),
      "Fallback",
    );
    expect(settings.defaultLocale).toBe("ar");
    expect(settings.brand.primaryColor).toBe("#112233");
    expect(settings.locales.en.siteName).toBe("Brand EN");
    expect(settings.locales.en.titleTemplate).toBe("{pageTitle} - {siteName}");
    expect(settings.locales.en.subhead).toBe("");
    expect(settings.locales.ar.siteName).toBe("Fallback");
    expect(settings.locales.de.subhead).toBe("Sub");
  });

  it("ignores title templates that lack the {pageTitle} token", () => {
    const settings = parseSiteSettingsValue(
      JSON.stringify({ locales: { en: { siteName: "X", titleTemplate: "no token here" } } }),
      "Fallback",
    );
    expect(settings.locales.en.titleTemplate).toBe("{pageTitle} | {siteName}");
  });

  it("falls back for invalid default locale and primary color", () => {
    const settings = parseSiteSettingsValue(
      JSON.stringify({ defaultLocale: "fr", brand: { primaryColor: "nope" } }),
      "Fallback",
    );
    expect(settings.defaultLocale).toBe("de");
    expect(settings.brand.primaryColor).toBe(DEFAULT_SITE_PRIMARY_COLOR);
  });

  it("trims string fields", () => {
    const settings = parseSiteSettingsValue(
      JSON.stringify({ locales: { de: { siteName: "  Trimmed  ", siteDescription: "  d  " } } }),
      "Fallback",
    );
    expect(settings.locales.de.siteName).toBe("Trimmed");
    expect(settings.locales.de.siteDescription).toBe("d");
  });
});
