import { REGISTRY_URL } from "@/src/registry/constants"
import { describe, expect, it } from "vitest"

import { DEFAULT_PRESETS, resolveCreateUrl, resolveInitUrl } from "./presets"

const SHADCN_URL = REGISTRY_URL.replace(/\/r\/?$/, "")

const mockPreset = {
  name: "default",
  title: "Default",
  description: "The default preset.",
  base: "radix",
  style: "new-york-v4",
  baseColor: "neutral",
  theme: "default",
  iconLibrary: "lucide",
  font: "inter",
  fontHeading: "inherit",
  rtl: false,
  menuAccent: "subtle" as const,
  menuColor: "default" as const,
  radius: "0.5",
}

describe("createPresetUrl", () => {
  it("should not include rtl by default", () => {
    const url = resolveCreateUrl()
    const parsed = new URL(url)
    expect(parsed.origin + parsed.pathname).toBe(`${SHADCN_URL}/create`)
    expect(parsed.searchParams.has("rtl")).toBe(false)
  })

  it("should append search params when provided", () => {
    const url = resolveCreateUrl({
      rtl: true,
      pointer: true,
      template: "next",
    })
    const parsed = new URL(url)
    expect(parsed.searchParams.get("rtl")).toBe("true")
    expect(parsed.searchParams.get("pointer")).toBe("true")
    expect(parsed.searchParams.get("template")).toBe("next")
  })
})

describe("buildInitUrl", () => {
  it("should build url with all preset fields as query params", () => {
    const url = resolveInitUrl(mockPreset)
    const parsed = new URL(url)
    expect(parsed.origin + parsed.pathname).toBe(`${SHADCN_URL}/init`)
    expect(parsed.searchParams.get("base")).toBe("radix")
    expect(parsed.searchParams.get("style")).toBe("new-york-v4")
    expect(parsed.searchParams.get("baseColor")).toBe("neutral")
    expect(parsed.searchParams.get("theme")).toBe("default")
    expect(parsed.searchParams.get("iconLibrary")).toBe("lucide")
    expect(parsed.searchParams.get("font")).toBe("inter")
    expect(parsed.searchParams.get("rtl")).toBe("false")
    expect(parsed.searchParams.get("menuAccent")).toBe("subtle")
    expect(parsed.searchParams.get("menuColor")).toBe("default")
    expect(parsed.searchParams.get("radius")).toBe("0.5")
  })

  it("should set rtl=true when preset.rtl is true", () => {
    const url = resolveInitUrl({ ...mockPreset, rtl: true })
    const parsed = new URL(url)
    expect(parsed.searchParams.get("rtl")).toBe("true")
  })

  it("should include template when provided", () => {
    const url = resolveInitUrl(mockPreset, { template: "next" })
    const parsed = new URL(url)
    expect(parsed.searchParams.get("template")).toBe("next")
  })

  it("should not include template when not provided", () => {
    const url = resolveInitUrl(mockPreset)
    const parsed = new URL(url)
    expect(parsed.searchParams.has("template")).toBe(false)
  })

  it("should include chartColor when provided", () => {
    const url = resolveInitUrl({ ...mockPreset, chartColor: "emerald" })
    const parsed = new URL(url)
    expect(parsed.searchParams.get("chartColor")).toBe("emerald")
  })

  it("should not include chartColor when it is neutral", () => {
    const url = resolveInitUrl({ ...mockPreset, chartColor: "neutral" })
    const parsed = new URL(url)
    expect(parsed.searchParams.has("chartColor")).toBe(false)
  })

  it("should include chartColor from default presets", () => {
    const url = resolveInitUrl({ ...DEFAULT_PRESETS.sera, base: "base" })
    const parsed = new URL(url)
    expect(parsed.searchParams.get("chartColor")).toBe("taupe")
  })

  it("should not include chartColor when not provided", () => {
    const url = resolveInitUrl(mockPreset)
    const parsed = new URL(url)
    expect(parsed.searchParams.has("chartColor")).toBe(false)
  })

  it("should include fontHeading when it is explicitly set", () => {
    const url = resolveInitUrl({
      ...mockPreset,
      fontHeading: "playfair-display",
    })
    const parsed = new URL(url)
    expect(parsed.searchParams.get("fontHeading")).toBe("playfair-display")
  })

  it("should not include fontHeading when it inherits the body font", () => {
    const url = resolveInitUrl(mockPreset)
    const parsed = new URL(url)
    expect(parsed.searchParams.has("fontHeading")).toBe(false)
  })

  it("should include preset code when provided", () => {
    const url = resolveInitUrl(mockPreset, { preset: "a0" })
    const parsed = new URL(url)
    expect(parsed.searchParams.get("preset")).toBe("a0")
  })

  it("should not include preset when not provided", () => {
    const url = resolveInitUrl(mockPreset)
    const parsed = new URL(url)
    expect(parsed.searchParams.has("preset")).toBe(false)
  })

  it("should include pointer when enabled", () => {
    const url = resolveInitUrl(mockPreset, { pointer: true })
    const parsed = new URL(url)
    expect(parsed.searchParams.get("pointer")).toBe("true")
  })

  it("should not include pointer when disabled", () => {
    const url = resolveInitUrl(mockPreset, { pointer: false })
    const parsed = new URL(url)
    expect(parsed.searchParams.has("pointer")).toBe(false)
  })

  it("should include pointer with preset codes", () => {
    const url = resolveInitUrl(mockPreset, { preset: "a0", pointer: true })
    const parsed = new URL(url)
    expect(parsed.searchParams.get("preset")).toBe("a0")
    expect(parsed.searchParams.get("pointer")).toBe("true")
  })
})
