import { describe, it, expect, beforeEach, vi } from "vitest";
import {
  getDefaultPreferences,
  getStoredConsent,
  saveConsent,
  acceptAll,
  rejectAll,
  hasConsent,
  isCategoryAllowed,
  clearConsent,
} from "./cookieConsent";

// Mock localStorage
const localStorageMock = (() => {
  let store: Record<string, string> = {};
  return {
    getItem: vi.fn((key: string) => store[key] ?? null),
    setItem: vi.fn((key: string, value: string) => {
      store[key] = value;
    }),
    removeItem: vi.fn((key: string) => {
      delete store[key];
    }),
    clear: vi.fn(() => {
      store = {};
    }),
    get length() {
      return Object.keys(store).length;
    },
    key: vi.fn((index: number) => Object.keys(store)[index] ?? null),
  };
})();

Object.defineProperty(globalThis, "localStorage", {
  value: localStorageMock,
  writable: true,
});

describe("Cookie Consent", () => {
  beforeEach(() => {
    localStorageMock.clear();
    vi.clearAllMocks();
  });

  describe("getDefaultPreferences", () => {
    it("returns essential=true, analytics=false, marketing=false", () => {
      const prefs = getDefaultPreferences();
      expect(prefs.essential).toBe(true);
      expect(prefs.analytics).toBe(false);
      expect(prefs.marketing).toBe(false);
    });
  });

  describe("hasConsent", () => {
    it("returns false when no consent stored", () => {
      expect(hasConsent()).toBe(false);
    });

    it("returns true after saving consent", () => {
      saveConsent(getDefaultPreferences());
      expect(hasConsent()).toBe(true);
    });
  });

  describe("saveConsent", () => {
    it("stores consent record in localStorage", () => {
      const record = saveConsent({ essential: true, analytics: true, marketing: false });
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        "alzar_cookie_consent",
        expect.any(String)
      );
      expect(record.preferences.essential).toBe(true);
      expect(record.preferences.analytics).toBe(true);
      expect(record.preferences.marketing).toBe(false);
      expect(record.version).toBe("1.0");
      expect(typeof record.timestamp).toBe("number");
    });

    it("always forces essential to true", () => {
      const record = saveConsent({ essential: false, analytics: false, marketing: false } as any);
      expect(record.preferences.essential).toBe(true);
    });
  });

  describe("getStoredConsent", () => {
    it("returns null when nothing stored", () => {
      expect(getStoredConsent()).toBeNull();
    });

    it("returns stored consent after save", () => {
      saveConsent({ essential: true, analytics: true, marketing: false });
      const stored = getStoredConsent();
      expect(stored).not.toBeNull();
      expect(stored!.preferences.analytics).toBe(true);
      expect(stored!.preferences.marketing).toBe(false);
    });

    it("returns null for corrupted data", () => {
      localStorageMock.setItem("alzar_cookie_consent", "not-json");
      expect(getStoredConsent()).toBeNull();
    });

    it("returns null for invalid structure", () => {
      localStorageMock.setItem("alzar_cookie_consent", JSON.stringify({ foo: "bar" }));
      expect(getStoredConsent()).toBeNull();
    });
  });

  describe("acceptAll", () => {
    it("enables all categories", () => {
      const record = acceptAll();
      expect(record.preferences.essential).toBe(true);
      expect(record.preferences.analytics).toBe(true);
      expect(record.preferences.marketing).toBe(true);
    });
  });

  describe("rejectAll", () => {
    it("disables optional categories, keeps essential", () => {
      const record = rejectAll();
      expect(record.preferences.essential).toBe(true);
      expect(record.preferences.analytics).toBe(false);
      expect(record.preferences.marketing).toBe(false);
    });
  });

  describe("isCategoryAllowed", () => {
    it("returns true for essential even without consent", () => {
      expect(isCategoryAllowed("essential")).toBe(true);
    });

    it("returns false for analytics without consent", () => {
      expect(isCategoryAllowed("analytics")).toBe(false);
    });

    it("returns true for analytics after accepting all", () => {
      acceptAll();
      expect(isCategoryAllowed("analytics")).toBe(true);
    });

    it("returns false for marketing after rejecting all", () => {
      rejectAll();
      expect(isCategoryAllowed("marketing")).toBe(false);
    });
  });

  describe("clearConsent", () => {
    it("removes consent from localStorage", () => {
      saveConsent(getDefaultPreferences());
      expect(hasConsent()).toBe(true);
      clearConsent();
      expect(hasConsent()).toBe(false);
    });
  });
});
