import { describe, it, expect, beforeEach, afterEach } from "vitest";
import {
  getGuestSessionId,
  setGuestSessionCookie,
  clearGuestSessionCookie,
  generateGuestSessionId,
} from "./cookie";

const UUID_REGEX =
  /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;

describe("cookie utilities", () => {
  const docCookie: { cookie: string } = { cookie: "" };
  let originalDocument: typeof globalThis.document | undefined;

  beforeEach(() => {
    originalDocument = globalThis.document;
    (globalThis as unknown as { document: { cookie: string } }).document =
      docCookie;
    docCookie.cookie = "";
  });

  afterEach(() => {
    (globalThis as unknown as { document: typeof originalDocument }).document =
      originalDocument;
  });

  describe("getGuestSessionId", () => {
    it("returns null when cookie is missing", () => {
      docCookie.cookie = "other=value";
      expect(getGuestSessionId()).toBeNull();
    });

    it("returns value when _store_session is present", () => {
      docCookie.cookie = "_store_session=abc-uuid-123";
      expect(getGuestSessionId()).toBe("abc-uuid-123");
    });

    it("returns decoded value when cookie is encoded", () => {
      docCookie.cookie =
        "_store_session=" + encodeURIComponent("id with spaces");
      expect(getGuestSessionId()).toBe("id with spaces");
    });

    it("returns null when _store_session has empty value", () => {
      docCookie.cookie = "_store_session=; other=val";
      expect(getGuestSessionId()).toBeNull();
    });
  });

  describe("setGuestSessionCookie", () => {
    it("sets cookie with name, value, Path, max-age, SameSite", () => {
      setGuestSessionCookie("my-session-id");
      expect(docCookie.cookie).toContain("_store_session=my-session-id");
      expect(docCookie.cookie).toContain("Path=/");
      expect(docCookie.cookie).toContain("SameSite=Lax");
      expect(docCookie.cookie).toMatch(/max-age=\d+/);
    });

    it("allows getGuestSessionId to read the set value", () => {
      setGuestSessionCookie("set-then-read");
      expect(getGuestSessionId()).toBe("set-then-read");
    });
  });

  describe("clearGuestSessionCookie", () => {
    it("sets max-age=0 so browser removes the cookie", () => {
      clearGuestSessionCookie();
      expect(docCookie.cookie).toContain("max-age=0");
      expect(docCookie.cookie).toContain("_store_session=");
    });
  });

  describe("generateGuestSessionId", () => {
    it("returns a string matching UUID v4 format", () => {
      const id = generateGuestSessionId();
      expect(id).toMatch(UUID_REGEX);
    });

    it("returns a new value each time", () => {
      const a = generateGuestSessionId();
      const b = generateGuestSessionId();
      expect(a).not.toBe(b);
    });
  });
});
