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

import { getRouteAccess, isInternalRoute } from "../route-meta";
import { ALL_STATIC_ROUTES, getCharacterRoutes, ROUTES } from "../routes";

describe("route meta", () => {
  it("classifies global routes by access level", () => {
    expect(getRouteAccess(ROUTES.splash)).toBe("authOnly");
    expect(getRouteAccess(ROUTES.auth)).toBe("authOnly");
    expect(getRouteAccess(ROUTES.chat)).toBe("guestEntry");
    expect(getRouteAccess(ROUTES.privateZone)).toBe("guestEntry");
    expect(getRouteAccess(ROUTES.tip)).toBe("public");
    expect(getRouteAccess(ROUTES.externalEntry)).toBe("public");
    expect(getRouteAccess(ROUTES.profile)).toBe("realUser");
    expect(getRouteAccess(ROUTES.feedback)).toBe("session");
    expect(getRouteAccess(ROUTES.subscription)).toBe("realUser");
    expect(getRouteAccess(ROUTES.coinsRules)).toBe("public");
  });

  it("does not keep the removed chat image route as a guarded route", () => {
    expect(getRouteAccess("/chat/image/msg_1")).toBe("public");
  });

  it("classifies character-scoped routes by their page", () => {
    const routes = getCharacterRoutes("maya");
    expect(routes).toEqual({
      splash: "/characters/maya/splash",
      chat: "/characters/maya/chat",
      call: "/characters/maya/call",
      privateZone: "/characters/maya/private-zone",
      tip: "/characters/maya/tip",
    });
    expect(getRouteAccess(routes.splash)).toBe("authOnly");
    expect(getRouteAccess(routes.chat)).toBe("guestEntry");
    expect(getRouteAccess(routes.call)).toBe("guestEntry");
    expect(getRouteAccess(routes.privateZone)).toBe("guestEntry");
    expect(getRouteAccess(routes.tip)).toBe("public");
  });

  it("does not classify removed character-scoped global pages", () => {
    expect(getRouteAccess("/characters/maya/profile")).toBe("public");
    expect(getRouteAccess("/characters/maya/feedback")).toBe("public");
    expect(getRouteAccess("/characters/maya/coins-rules")).toBe("public");
  });

  it("includes private zone in static routes", () => {
    expect(ALL_STATIC_ROUTES).toContain(ROUTES.privateZone);
  });

  it("includes tip in static routes", () => {
    expect(ALL_STATIC_ROUTES).toContain(ROUTES.tip);
  });

  it("includes external entry in static routes", () => {
    expect(ALL_STATIC_ROUTES).toContain(ROUTES.externalEntry);
  });

  it("includes feedback in static routes", () => {
    expect(ALL_STATIC_ROUTES).toContain(ROUTES.feedback);
  });

  it("treats unknown routes as public by default", () => {
    expect(getRouteAccess("/unknown")).toBe("public");
  });

  it("accepts only internal redirect targets", () => {
    expect(isInternalRoute("/chat")).toBe(true);
    expect(isInternalRoute("/subscription?type=vip")).toBe(true);
    expect(isInternalRoute("https://example.com/chat")).toBe(false);
    expect(isInternalRoute("//example.com/chat")).toBe(false);
    expect(isInternalRoute(null)).toBe(false);
  });
});
