import { createClient } from "@supabase/supabase-js";
import { testClient } from "hono/testing";
import { beforeEach, describe, expect, it } from "vitest";
import { createConfig } from "../../config.js";
import { MiddlewareManager } from "../../middlewares/middleware.js";
import { getMainRouter } from "../../routers/index.js";
import { getTestUser } from "../helpers/testUtils.js";

describe("RevenueCat Webhook Endpoint", () => {
  const config = createConfig();
  MiddlewareManager.initialize(config);
  const app = getMainRouter(config);
  // biome-ignore lint/suspicious/noExplicitAny: testClient requires any for dynamic route access
  const client = testClient(app) as any;
  const ownerUser = getTestUser("owner");
  const adminClient = createClient(config.SUPABASE_URL, config.SUPABASE_SERVICE_ROLE_KEY, {
    auth: {
      autoRefreshToken: false,
      persistSession: false,
    },
  });

  beforeEach(async () => {
    await adminClient.from("apple_subscription_events").delete().neq("id", 0);
    await adminClient.from("apple_subscriptions").delete().eq("owner_user_id", ownerUser.userId);
    await adminClient.from("apple_customers").delete().eq("user_id", ownerUser.userId);
  });

  it("rejects webhook calls without the configured authorization header", async () => {
    const res = await client["revenuecat-webhook"].$post({
      json: {
        event: {
          id: "unauthorized-event",
          type: "INITIAL_PURCHASE",
        },
      },
    });

    expect(res.status).toBe(401);
  });

  it("persists a mapped Apple subscription once and treats retries as duplicates", async () => {
    const eventId = `event-${Date.now()}`;
    const originalTransactionId = `orig-${Date.now()}`;

    const payload = {
      event: {
        aliases: [],
        app_user_id: ownerUser.userId,
        environment: "SANDBOX",
        expiration_at_ms: Date.now() + 86400000,
        id: eventId,
        original_app_user_id: ownerUser.userId,
        original_transaction_id: originalTransactionId,
        product_id: config.REVENUECAT_SOLO_PRODUCT_ID,
        purchased_at_ms: Date.now(),
        store: "APP_STORE",
        transaction_id: `txn-${Date.now()}`,
        type: "INITIAL_PURCHASE",
      },
    };

    const firstRes = await client["revenuecat-webhook"].$post(
      { json: payload },
      {
        headers: {
          authorization: config.REVENUECAT_WEBHOOK_AUTH_HEADER,
          "Content-Type": "application/json",
        },
      }
    );

    expect(firstRes.status).toBe(200);

    const secondRes = await client["revenuecat-webhook"].$post(
      { json: payload },
      {
        headers: {
          authorization: config.REVENUECAT_WEBHOOK_AUTH_HEADER,
          "Content-Type": "application/json",
        },
      }
    );

    expect(secondRes.status).toBe(200);
    expect(await secondRes.json()).toMatchObject({ duplicate: true, received: true });

    const { data: appleSubscriptions } = await adminClient
      .from("apple_subscriptions")
      .select("owner_user_id, plan, status, original_transaction_id")
      .eq("original_transaction_id", originalTransactionId);

    expect(appleSubscriptions).toHaveLength(1);
    expect(appleSubscriptions?.[0]).toMatchObject({
      owner_user_id: ownerUser.userId,
      plan: "solo",
      status: "active",
      original_transaction_id: originalTransactionId,
    });

    const { data: appleEvents } = await adminClient
      .from("apple_subscription_events")
      .select("event_id")
      .eq("event_id", eventId);

    expect(appleEvents).toHaveLength(1);
  });

  it("ignores unmapped products without creating entitlement rows", async () => {
    const res = await client["revenuecat-webhook"].$post(
      {
        json: {
          event: {
            app_user_id: ownerUser.userId,
            environment: "SANDBOX",
            expiration_at_ms: Date.now() + 86400000,
            id: `ignored-${Date.now()}`,
            original_transaction_id: `orig-ignored-${Date.now()}`,
            product_id: "team_ios_monthly",
            purchased_at_ms: Date.now(),
            store: "APP_STORE",
            transaction_id: `txn-ignored-${Date.now()}`,
            type: "INITIAL_PURCHASE",
          },
        },
      },
      {
        headers: {
          authorization: config.REVENUECAT_WEBHOOK_AUTH_HEADER,
          "Content-Type": "application/json",
        },
      }
    );

    expect(res.status).toBe(200);
    expect(await res.json()).toMatchObject({ ignored: true, reason: "unmapped_product" });

    const { data: rows } = await adminClient
      .from("apple_subscriptions")
      .select("id")
      .eq("owner_user_id", ownerUser.userId);

    expect(rows ?? []).toHaveLength(0);
  });
});
