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

import { getCharacterRoutes, ROUTES } from "@/router/routes";

import {
  resolveCheckoutIntentDestination,
  resolveExternalEntryDestination,
  resolveExternalEntryPromotionType,
  resolveExternalEntryTarget,
  shouldBindExternalFacebookIdentity,
} from "../external_entry";

describe("checkout external browser destination", () => {
  it("restores subscription intent without carrying the handoff token", () => {
    expect(
      resolveCheckoutIntentDestination(
        {
          planId: "vip_monthly",
          autoRenew: true,
          commercialOfferId: "offer-1",
          chatActionId: "00000000-0000-0000-0000-000000000123",
        },
        "nayeli",
      ),
    ).toBe(
      "/subscription?planId=vip_monthly&autoRenew=1&character=nayeli&commercialOfferId=offer-1&chatActionId=00000000-0000-0000-0000-000000000123&payChannel=stripe",
    );
  });

  it("restores a character tip intent by canonical character id", () => {
    expect(
      resolveCheckoutIntentDestination({
        planId: "maya_coffee",
        autoRenew: false,
        recipientCharacterId: "maya-tan",
      }),
    ).toBe("/characters/maya/tip?planId=maya_coffee&payChannel=stripe");
  });
});

const facebookBusinessEntryCases = [
  ["private-space", "elio", "chat", null, null, getCharacterRoutes("elio").chat, null],
  ["private-space", "maya", "chat", null, null, getCharacterRoutes("maya").chat, null],
  ["private-space", "nayeli", "chat", null, null, getCharacterRoutes("nayeli").chat, null],
  ["voice", "elio", "chat", "promotion", "voice", getCharacterRoutes("elio").chat, "voice"],
  ["voice", "maya", "chat", "promotion", "voice", getCharacterRoutes("maya").chat, "voice"],
  ["voice", "nayeli", "chat", "promotion", "voice", getCharacterRoutes("nayeli").chat, "voice"],
  ["image-pack", "elio", "private-zone", null, null, getCharacterRoutes("elio").privateZone, null],
  ["image-pack", "maya", "private-zone", null, null, getCharacterRoutes("maya").privateZone, null],
  ["image-pack", "nayeli", "private-zone", null, null, getCharacterRoutes("nayeli").privateZone, null],
  ["coffee", "elio", "tip", null, null, getCharacterRoutes("elio").tip, null],
  ["coffee", "maya", "tip", null, null, getCharacterRoutes("maya").tip, null],
  ["coffee", "nayeli", "tip", null, null, getCharacterRoutes("nayeli").tip, null],
] as const;

describe("external entry navigation", () => {
  it("defaults to chat", () => {
    expect(resolveExternalEntryTarget({})).toBe(ROUTES.chat);
  });

  it("resolves canonical targets and the published private-room alias", () => {
    expect(resolveExternalEntryTarget({ target: "chat" })).toBe(ROUTES.chat);
    expect(resolveExternalEntryTarget({ target: "tip" })).toBe(ROUTES.tip);
    expect(resolveExternalEntryTarget({ target: "private-zone" })).toBe(
      ROUTES.privateZone,
    );
    expect(resolveExternalEntryTarget({ target: "private-room" })).toBe(
      ROUTES.privateZone,
    );
    expect(resolveExternalEntryTarget({ target: "topup" })).toBe(
      ROUTES.subscription,
    );
  });

  it("rejects removed aliases and unsupported targets", () => {
    expect(resolveExternalEntryTarget({ target: "tips" })).toBe(ROUTES.chat);
    expect(resolveExternalEntryTarget({ target: "coffee" })).toBe(ROUTES.chat);
    expect(resolveExternalEntryTarget({ target: "private_zone" })).toBe(
      ROUTES.chat,
    );
    expect(resolveExternalEntryTarget({ target: "/tip" })).toBe(ROUTES.chat);
    expect(resolveExternalEntryTarget({ target: "profile" })).toBe(ROUTES.chat);
  });

  it("routes every tip entry to the tier selection page", () => {
    expect(resolveExternalEntryDestination({ target: "tip" })).toBe(
      getCharacterRoutes("elio").tip,
    );
  });

  it("routes a top-up handoff directly to the credit packages", () => {
    expect(resolveExternalEntryDestination({ target: "topup" })).toBe(
      "/subscription?type=topup",
    );
  });

  it("uses a known character slug and falls back to Elio", () => {
    expect(
      resolveExternalEntryDestination({ target: "chat", character: "maya" }),
    ).toBe(getCharacterRoutes("maya").chat);
    expect(
      resolveExternalEntryDestination({
        target: "private-zone",
        character: "unknown",
      }),
    ).toBe(getCharacterRoutes("elio").privateZone);
  });

  it.each(facebookBusinessEntryCases)(
    "routes Facebook business entry %s for %s",
    (
      _entry,
      character,
      target,
      mode,
      promotionType,
      expectedDestination,
      expectedPromotionType,
    ) => {
      expect(resolveExternalEntryDestination({ target, character })).toBe(
        expectedDestination,
      );
      expect(
        resolveExternalEntryPromotionType({ mode, promotionType }),
      ).toBe(expectedPromotionType);
    },
  );

  it.each([
    ["chat", "elio", getCharacterRoutes("elio").chat],
    ["chat", "maya", getCharacterRoutes("maya").chat],
    ["chat", "nayeli", getCharacterRoutes("nayeli").chat],
    ["tip", "elio", getCharacterRoutes("elio").tip],
    ["tip", "maya", getCharacterRoutes("maya").tip],
    ["tip", "nayeli", getCharacterRoutes("nayeli").tip],
    ["private-zone", "elio", getCharacterRoutes("elio").privateZone],
    ["private-zone", "maya", getCharacterRoutes("maya").privateZone],
    ["private-zone", "nayeli", getCharacterRoutes("nayeli").privateZone],
    ["private-room", "elio", getCharacterRoutes("elio").privateZone],
    ["private-room", "maya", getCharacterRoutes("maya").privateZone],
    ["private-room", "nayeli", getCharacterRoutes("nayeli").privateZone],
  ])(
    "routes target=%s character=%s to %s",
    (target, character, expectedDestination) => {
      expect(resolveExternalEntryDestination({ target, character })).toBe(
        expectedDestination,
      );
    },
  );
});

describe("external entry facebook identity binding", () => {
  it("binds only a ready real-user session with an external id", () => {
    expect(
      shouldBindExternalFacebookIdentity({
        hasInitialized: true,
        isLoading: false,
        loginStatus: "email",
        asid: "asid-1",
      }),
    ).toBe(true);
    expect(
      shouldBindExternalFacebookIdentity({
        hasInitialized: true,
        isLoading: false,
        loginStatus: "google",
        asid: "asid-1",
      }),
    ).toBe(true);
    expect(
      shouldBindExternalFacebookIdentity({
        hasInitialized: true,
        isLoading: false,
        loginStatus: "facebook",
        psid: "psid-1",
      }),
    ).toBe(true);
  });

  it("skips guest, notLoggedIn, loading, and empty identity inputs", () => {
    expect(
      shouldBindExternalFacebookIdentity({
        hasInitialized: true,
        isLoading: false,
        loginStatus: "guest",
        asid: "asid-1",
      }),
    ).toBe(false);
    expect(
      shouldBindExternalFacebookIdentity({
        hasInitialized: true,
        isLoading: false,
        loginStatus: "notLoggedIn",
        psid: "psid-1",
      }),
    ).toBe(false);
    expect(
      shouldBindExternalFacebookIdentity({
        hasInitialized: true,
        isLoading: true,
        loginStatus: "google",
        asid: "asid-1",
      }),
    ).toBe(false);
    expect(
      shouldBindExternalFacebookIdentity({
        hasInitialized: true,
        isLoading: false,
        loginStatus: "google",
      }),
    ).toBe(false);
  });
});

describe("external entry promotion", () => {
  it("accepts only explicit promotion mode and supported message types", () => {
    expect(
      resolveExternalEntryPromotionType({
        mode: "promotion",
        promotionType: "voice",
      }),
    ).toBe("voice");
    expect(
      resolveExternalEntryPromotionType({
        mode: "promotion",
        promotionType: "image",
      }),
    ).toBe("image");
    expect(
      resolveExternalEntryPromotionType({
        mode: "normal",
        promotionType: "private",
      }),
    ).toBeNull();
    expect(
      resolveExternalEntryPromotionType({
        mode: "promotion",
        promotionType: "video",
      }),
    ).toBeNull();
  });
});
