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

import {
  PrivateRoomMomentsResponse,
  PrivateRoomUnlockResponse,
} from "@/data/dto/private-room";
import { ApiPath } from "@/data/services/api";

const lockedMoment = {
  momentId: "schedule:91",
  source: "elio_schedules",
  sourceId: "91",
  characterId: "elio",
  author: {
    id: "elio",
    name: "Elio Silvestri",
    avatarUrl: null,
  },
  createdAt: "2026-07-01T08:11:35+00:00",
  publishedAt: "2026-07-01T08:11:35+00:00",
  timeText: "7 days ago",
  title: "Paris morning",
  content: null,
  text: null,
  textPreview: "Unlock to view private room photos",
  mediaCount: 1,
  images: [
    {
      url: null,
      type: "image",
      locked: true,
      index: 0,
    },
  ],
  locked: true,
  unlocked: false,
  unlockCost: 40,
  unlockCostPerImage: 40,
  requiredCredits: 40,
  currency: "credits",
  lockDetail: {
    locked: true,
    showContent: false,
    showUpgrade: true,
    reason: "private_room_moment",
    hint: "40 credits · Unlock photo",
    actionLabel: "Unlock",
    type: "private_room_moment",
    requiredCredits: 40,
    currentCredits: 100,
    shortfallCredits: 0,
    mediaCount: 1,
    unlockCostPerImage: 40,
  },
};

describe("PrivateRoom DTOs", () => {
  it("parses locked moments without image URLs", () => {
    const response = PrivateRoomMomentsResponse.from({
      profile: {
        characterId: "elio",
        displayName: "Elio Silvestri",
        authorName: "Elio Silvestri",
        avatarUrl: null,
        coverUrl: null,
        title: "Elio Private room",
        subtitle: "Join me, unlock my private room",
      },
      items: [lockedMoment],
      nextCursor: null,
      hasMore: false,
      creditBalance: 100,
      unlockCostDefault: 40,
      unlockCostPerImage: 40,
      currency: "credits",
      source: "elio_schedules",
    });

    expect(response.items[0]?.locked).toBe(true);
    expect(response.items[0]?.images[0]?.url).toBeNull();
    expect(response.items[0]?.unlockCost).toBe(40);
    expect(response.profile.displayName).toBe("Elio Silvestri");
  });

  it("parses unlock success with real image URLs", () => {
    const response = PrivateRoomUnlockResponse.from({
      ...lockedMoment,
      locked: false,
      unlocked: true,
      content: "A quiet morning in Paris.",
      text: "A quiet morning in Paris.",
      images: [
        {
          url: "https://lehwkihwnlqkavhcspel.supabase.co/storage/v1/object/public/elio-schedules/schedules/91/photo.jpg",
          type: "image",
          locked: false,
          index: 0,
        },
      ],
      reason: "ok",
      creditsCharged: 40,
      creditBalance: 60,
      previousCreditBalance: 100,
      persisted: true,
    });

    expect(response.unlocked).toBe(true);
    expect(response.reason).toBe("ok");
    expect(response.images[0]?.url).toContain("https://");
    expect(response.creditBalance).toBe(60);
  });

  it("parses insufficient credits as business data", () => {
    const response = PrivateRoomUnlockResponse.from({
      ...lockedMoment,
      reason: "insufficient_credits",
      currentCredits: 10,
      shortfallCredits: 30,
      creditBalance: 10,
    });

    expect(response.unlocked).toBe(false);
    expect(response.locked).toBe(true);
    expect(response.reason).toBe("insufficient_credits");
    expect(response.images[0]?.url).toBeNull();
  });

  it("encodes moment id in the unlock path", () => {
    expect(ApiPath.privateRoomMomentUnlock("schedule:91")).toBe(
      "/api/private-room/moments/schedule%3A91/unlock",
    );
  });
});
