/**
 * RED PHASE - Pricing Page Configuration Tests
 *
 * These tests validate the server-side pricing page component:
 * - Stripe product fetching
 * - Tier organization
 * - Product serialization
 * - Error handling
 * - ISR caching
 * - Metadata generation
 *
 * Expected: ALL TESTS FAIL initially (RED phase)
 */

import { render, waitFor } from "@testing-library/react";
import Stripe from "stripe";
import PricingPage, { generateMetadata } from "@/app/[lang]/pricing/page";
import { stripe } from "@/lib/stripe";
import { UI } from "@/lib/config";
import { CurrencyManager } from "@/lib/utils/currency";
import { PRICING_TIERS } from "@/lib/config/pricing-tiers";

// Mock Stripe
jest.mock("@/lib/stripe", () => ({
  stripe: {
    products: {
      list: jest.fn(),
    },
    prices: {
      list: jest.fn(),
    },
  },
}));

// Mock PricingClient component
jest.mock("@/app/[lang]/pricing/PricingClient", () => {
  return function MockPricingClient({ lang, dict, stripeProducts }: any) {
    return (
      <div data-testid="pricing-client">
        <div data-testid="lang">{lang}</div>
        <div data-testid="products">{JSON.stringify(stripeProducts)}</div>
      </div>
    );
  };
});

describe("Pricing Page - Server Component Configuration", () => {
  const mockProducts = [
    {
      id: "prod_tier1",
      name: "Starter Plan",
      description: "Perfect for small clinics",
      active: true,
      metadata: {
        tier_id: "tier1",
        features: JSON.stringify(["Feature 1", "Feature 2"]),
      },
    },
    {
      id: "prod_tier2",
      name: "Professional Plan",
      description: "For growing practices",
      active: true,
      metadata: {
        tier_id: "tier2",
        features: JSON.stringify(["Feature A", "Feature B", "Feature C"]),
      },
    },
    {
      id: "prod_tier3",
      name: "Business Plan",
      description: "For established clinics",
      active: true,
      metadata: {
        tier_id: "tier3",
        features: JSON.stringify(["Feature X", "Feature Y"]),
      },
    },
    {
      id: "prod_tier4",
      name: "Enterprise Plan",
      description: "For large medical centers",
      active: true,
      metadata: {
        tier_id: "tier4",
        features: JSON.stringify([
          "Feature 1",
          "Feature 2",
          "Feature 3",
          "Feature 4",
        ]),
      },
    },
    {
      id: "prod_tier5",
      name: "Ultimate Plan",
      description: "For enterprise networks",
      active: true,
      metadata: {
        tier_id: "tier5",
        features: JSON.stringify(["All Features", "Premium Support"]),
      },
    },
    {
      id: "prod_no_tier",
      name: "Invalid Product",
      description: "Product without tier_id",
      active: true,
      metadata: {}, // Missing tier_id
    },
  ];

  const mockPrices = [
    {
      id: "price_tier1_gbp_monthly",
      product: mockProducts[0],
      currency: "gbp",
      unit_amount: 9900, // £99
      recurring: { interval: "month", interval_count: 1 },
      active: true,
    },
    {
      id: "price_tier1_gbp_yearly",
      product: mockProducts[0],
      currency: "gbp",
      unit_amount: 110628, // £99 * 12 * 0.93 (7% discount)
      recurring: { interval: "year", interval_count: 1 },
      active: true,
    },
    {
      id: "price_tier2_gbp_monthly",
      product: mockProducts[1],
      currency: "gbp",
      unit_amount: 19900,
      recurring: { interval: "month", interval_count: 1 },
      active: true,
    },
  ];

  beforeEach(() => {
    jest.clearAllMocks();
    (stripe.products.list as jest.Mock).mockResolvedValue({
      data: mockProducts,
    });
    (stripe.prices.list as jest.Mock).mockResolvedValue({ data: mockPrices });
  });

  describe("Product Fetching", () => {
    test("TEST #1: Should fetch active Stripe products successfully", async () => {
      const params = { lang: "en" as const };
      await PricingPage({ params });

      expect(stripe.products.list).toHaveBeenCalledWith(
        expect.objectContaining({
          active: true,
          expand: ["data.default_price"],
        }),
      );
    });

    test("TEST #2: Should fetch all active prices", async () => {
      const params = { lang: "en" as const };
      await PricingPage({ params });

      expect(stripe.prices.list).toHaveBeenCalledWith(
        expect.objectContaining({
          active: true,
          expand: ["data.product"],
        }),
      );
    });

    test("TEST #3: Should handle Stripe API errors gracefully", async () => {
      (stripe.products.list as jest.Mock).mockRejectedValue(
        new Error("Stripe API error"),
      );

      const params = { lang: "en" as const };
      const result = await PricingPage({ params });

      // Should render without crashing and pass empty products
      expect(result).toBeDefined();
    });
  });

  describe("Tier Organization", () => {
    test("TEST #4: Should organize products by tier_id metadata", async () => {
      const params = { lang: "en" as const };
      const { container } = render(await PricingPage({ params }));

      const productsEl = container.querySelector('[data-testid="products"]');
      const products = JSON.parse(productsEl?.textContent || "[]");

      // Validate organization by tier
      const tierIds = products.map((p: any) => p.tierId);
      expect(tierIds).toContain("tier1");
      expect(tierIds).toContain("tier2");
      expect(tierIds).toContain("tier3");
    });

    test("TEST #5: Should handle products without tier_id gracefully", async () => {
      const params = { lang: "en" as const };
      const { container } = render(await PricingPage({ params }));

      const productsEl = container.querySelector('[data-testid="products"]');
      const products = JSON.parse(productsEl?.textContent || "[]");

      // Product without tier_id should not be included
      const invalidProduct = products.find(
        (p: any) => p.stripeProductId === "prod_no_tier",
      );
      expect(invalidProduct).toBeUndefined();
    });

    test("TEST #6: Should ensure all 5 tiers are represented when available", async () => {
      const params = { lang: "en" as const };
      const { container } = render(await PricingPage({ params }));

      const productsEl = container.querySelector('[data-testid="products"]');
      const products = JSON.parse(productsEl?.textContent || "[]");

      const tierIds = products.map((p: any) => p.tierId).sort();
      expect(tierIds).toEqual(["tier1", "tier2", "tier3", "tier4", "tier5"]);
    });
  });

  describe("Product Serialization", () => {
    test("TEST #7: Should include all required product fields", async () => {
      const params = { lang: "en" as const };
      const { container } = render(await PricingPage({ params }));

      const productsEl = container.querySelector('[data-testid="products"]');
      const products = JSON.parse(productsEl?.textContent || "[]");

      const product = products[0];
      expect(product).toHaveProperty("tierId");
      expect(product).toHaveProperty("stripeProductId");
      expect(product).toHaveProperty("name");
      expect(product).toHaveProperty("description");
      expect(product).toHaveProperty("features");
      expect(product).toHaveProperty("prices");
    });

    test("TEST #8: Should serialize prices correctly with all fields", async () => {
      const params = { lang: "en" as const };
      const { container } = render(await PricingPage({ params }));

      const productsEl = container.querySelector('[data-testid="products"]');
      const products = JSON.parse(productsEl?.textContent || "[]");

      const price = products[0]?.prices[0];
      expect(price).toHaveProperty("id");
      expect(price).toHaveProperty("currency");
      expect(price).toHaveProperty("unitAmount");
      expect(price).toHaveProperty("interval");
      expect(price).toHaveProperty("intervalCount");
    });

    test.skip("TEST #9: Should validate product.metadata.features is valid JSON", async () => {
      // Mock product with invalid JSON features
      const invalidProduct = {
        id: "prod_invalid_json",
        name: "Invalid Product",
        active: true,
        metadata: {
          tier_id: "tier1",
          features: "invalid-json-{not-an-array}",
        },
      };

      (stripe.products.list as jest.Mock).mockResolvedValue({
        data: [invalidProduct],
      });
      (stripe.prices.list as jest.Mock).mockResolvedValue({ data: [] });

      const params = { lang: "en" as const };
      const { container } = render(await PricingPage({ params }));

      const productsEl = container.querySelector('[data-testid="products"]');
      const products = JSON.parse(productsEl?.textContent || "[]");

      // Should handle gracefully with empty features array
      expect(products[0]?.features).toEqual([]);
    });

    test("TEST #10: Should filter prices by matching product ID", async () => {
      const params = { lang: "en" as const };
      const { container } = render(await PricingPage({ params }));

      const productsEl = container.querySelector('[data-testid="products"]');
      const products = JSON.parse(productsEl?.textContent || "[]");

      // Each product should only have prices matching its product ID
      products.forEach((product: any) => {
        product.prices.forEach((price: any) => {
          // This will fail initially if price filtering logic is incorrect
          expect(price.id).toMatch(new RegExp(`tier\\d+.*`));
        });
      });
    });
  });

  describe("Metadata Generation", () => {
    test("TEST #11: Should generate metadata for SEO with correct structure", async () => {
      const params = { lang: "en" as const };
      const metadata = await generateMetadata({ params });

      expect(metadata).toHaveProperty("title");
      expect(metadata).toHaveProperty("description");
      expect(metadata.title).toBeTruthy();
      expect(metadata.description).toBeTruthy();

      // Should use dictionary values
      const dict = UI["en"];
      if (dict.t.pricingTitle) {
        expect(metadata.title).toBe(dict.t.pricingTitle);
      }
      if (dict.t.pricingDescription) {
        expect(metadata.description).toBe(dict.t.pricingDescription);
      }
    });
  });

  describe("Type Safety Integration", () => {
    test("should export CurrencyManager with all methods", () => {
      expect(CurrencyManager.detectUserCurrency).toBeDefined();
      expect(CurrencyManager.convert).toBeDefined();
      expect(CurrencyManager.formatPrice).toBeDefined();
      expect(CurrencyManager.findStripePrice).toBeDefined();
      expect(CurrencyManager.getCurrencyInfo).toBeDefined();
      expect(CurrencyManager.getAllCurrencies).toBeDefined();
    });

    test("should export PRICING_TIERS with correct structure", () => {
      expect(PRICING_TIERS).toHaveLength(5);
      expect(PRICING_TIERS[0]).toHaveProperty("id");
      expect(PRICING_TIERS[0]).toHaveProperty("nameEn");
      expect(PRICING_TIERS[0]).toHaveProperty("nameAr");
      expect(PRICING_TIERS[0]).toHaveProperty("priceGBP");
      expect(PRICING_TIERS[0]).toHaveProperty("setupGBP");
      expect(PRICING_TIERS[0]).toHaveProperty("featuresEn");
      expect(PRICING_TIERS[0]).toHaveProperty("featuresAr");
      expect(PRICING_TIERS[0]).toHaveProperty("popular");
    });

    test("should have proper TypeScript types without any types", () => {
      // This test verifies compilation - if types are wrong, TypeScript will fail
      const tier = PRICING_TIERS[0];
      const tierId: string = tier.id;
      const price: number = tier.priceGBP;
      const popular: boolean = tier.popular;

      expect(tierId).toBeTruthy();
      expect(price).toBeGreaterThan(0);
      expect(typeof popular).toBe("boolean");
    });
  });
});
