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

import {
  getOGImageVersion,
  constructMeetingImage,
  constructAppImage,
  constructGenericImage,
} from "./OgImages";

describe("OgImages", () => {
  describe("getOGImageVersion", () => {
    it("returns a consistent hash for the same type", async () => {
      const version1 = await getOGImageVersion("generic");
      const version2 = await getOGImageVersion("generic");
      expect(version1).toBe(version2);
    });

    it("returns different hashes for different types", async () => {
      const meetingVersion = await getOGImageVersion("meeting");
      const appVersion = await getOGImageVersion("app");
      const genericVersion = await getOGImageVersion("generic");

      expect(meetingVersion).not.toBe(appVersion);
      expect(meetingVersion).not.toBe(genericVersion);
    });

    it("returns different hash when additionalInputs are provided", async () => {
      const base = await getOGImageVersion("app");
      const withInputs = await getOGImageVersion("app", { svgHash: "abc123" });
      expect(base).not.toBe(withInputs);
    });
  });

  describe("constructMeetingImage", () => {
    it("returns an encoded URL with meeting parameters", async () => {
      const result = await constructMeetingImage({
        title: "30min",
        profile: { name: "Test User" },
        users: [],
      });
      const decoded = decodeURIComponent(result);
      expect(decoded).toContain("type=meeting");
      expect(decoded).toContain("title=30min");
      expect(decoded).toContain("meetingProfileName=Test+User");
    });

    it("includes meetingImage when profile has an image", async () => {
      const result = await constructMeetingImage({
        title: "30min",
        profile: { name: "Test User", image: "https://example.com/avatar.png" },
        users: [],
      });
      const decoded = decodeURIComponent(result);
      expect(decoded).toContain("meetingImage=https%3A%2F%2Fexample.com%2Favatar.png");
    });
  });

  describe("constructAppImage", () => {
    it("returns an encoded URL with app parameters", async () => {
      const result = await constructAppImage({
        name: "TestApp",
        slug: "test-app",
        description: "A test app",
        logoUrl: "/app-store/test/icon.svg",
      });
      const decoded = decodeURIComponent(result);
      expect(decoded).toContain("type=app");
      expect(decoded).toContain("name=TestApp");
      expect(decoded).toContain("slug=test-app");
    });
  });

  describe("constructGenericImage", () => {
    it("returns an encoded URL with generic parameters", async () => {
      const result = await constructGenericImage({
        title: "Login",
        description: "Sign in to your account",
      });
      const decoded = decodeURIComponent(result);
      expect(decoded).toContain("type=generic");
      expect(decoded).toContain("title=Login");
      expect(decoded).toContain("description=Sign+in+to+your+account");
    });
  });

  describe("OG image branding uses configurable logo constants", () => {
    it("generic type uses LOGO_DARK (with LOGO fallback) for darker logo on light backgrounds", async () => {
      const genericVersion = await getOGImageVersion("generic");
      expect(genericVersion).toBeTruthy();
      expect(typeof genericVersion).toBe("string");
      expect(genericVersion.length).toBe(8);
    });

    it("meeting and app types use LOGO constant", async () => {
      const meetingVersion = await getOGImageVersion("meeting");
      const appVersion = await getOGImageVersion("app");
      expect(meetingVersion).toBeTruthy();
      expect(appVersion).toBeTruthy();
      expect(meetingVersion.length).toBe(8);
      expect(appVersion.length).toBe(8);
    });

    it("all three types produce distinct version hashes", async () => {
      const meetingVersion = await getOGImageVersion("meeting");
      const appVersion = await getOGImageVersion("app");
      const genericVersion = await getOGImageVersion("generic");

      expect(meetingVersion).not.toBe(appVersion);
      expect(meetingVersion).not.toBe(genericVersion);
      expect(appVersion).not.toBe(genericVersion);
    });

    it("self-hosters can override logos by replacing the referenced SVG files", async () => {
      const v1 = await getOGImageVersion("generic");
      const v2 = await getOGImageVersion("generic");
      expect(v1).toBe(v2);
    });
  });
});
