// Marketplace Service Tests

import { marketplaceService } from '@/core/iru/marketplace.service';
import prisma from '@/shared/database/prisma';

jest.mock('@/shared/database/prisma', () => ({
  iruOffering: {
    findMany: jest.fn(),
    findUnique: jest.fn(),
  },
  iruInquiry: {
    findFirst: jest.fn(),
    create: jest.fn(),
    findUnique: jest.fn(),
  },
}));

describe('MarketplaceService', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  describe('getOfferings', () => {
    it('should return active offerings', async () => {
      const mockOfferings = [
        {
          id: '1',
          offeringId: 'IRU-OFF-001',
          name: 'Tier 1 IRU',
          capacityTier: 1,
          institutionalType: 'CentralBank',
          pricingModel: 'Fixed',
          basePrice: 100000,
          currency: 'USD',
          status: 'active',
          displayOrder: 0,
        },
      ];

      (prisma.iruOffering.findMany as jest.Mock).mockResolvedValue(mockOfferings);

      const offerings = await marketplaceService.getOfferings();

      expect(offerings).toHaveLength(1);
      expect(offerings[0].offeringId).toBe('IRU-OFF-001');
    });

    it('should filter by capacity tier', async () => {
      (prisma.iruOffering.findMany as jest.Mock).mockResolvedValue([]);

      await marketplaceService.getOfferings({ capacityTier: 1 });

      expect(prisma.iruOffering.findMany).toHaveBeenCalledWith(
        expect.objectContaining({
          where: expect.objectContaining({
            capacityTier: 1,
          }),
        })
      );
    });
  });

  describe('submitInquiry', () => {
    it('should create inquiry successfully', async () => {
      const mockOffering = {
        id: '1',
        offeringId: 'IRU-OFF-001',
        status: 'active',
      };

      (prisma.iruOffering.findUnique as jest.Mock).mockResolvedValue(mockOffering);
      (prisma.iruInquiry.findFirst as jest.Mock).mockResolvedValue(null);
      (prisma.iruInquiry.create as jest.Mock).mockImplementation(async ({ data }: { data: Record<string, unknown> }) => ({
        ...data,
        status: 'submitted',
      }));

      const result = await marketplaceService.submitInquiry({
        offeringId: 'IRU-OFF-001',
        organizationName: 'Test Bank',
        institutionalType: 'CentralBank',
        jurisdiction: 'US',
        contactEmail: 'test@bank.com',
        contactName: 'Test User',
      });

      expect(result.inquiryId).toMatch(/^INQ-[0-9A-F]{32}$/);
      expect(result.status).toBe('submitted');
      expect(prisma.iruInquiry.create).toHaveBeenCalledWith(
        expect.objectContaining({
          data: expect.objectContaining({
            offeringId: '1',
            inquiryId: expect.stringMatching(/^INQ-[0-9A-F]{32}$/),
          }),
        })
      );
    });

    it('should reject inquiry for inactive offering', async () => {
      const mockOffering = {
        id: '1',
        offeringId: 'IRU-OFF-001',
        status: 'inactive',
      };

      (prisma.iruOffering.findUnique as jest.Mock).mockResolvedValue(mockOffering);

      await expect(
        marketplaceService.submitInquiry({
          offeringId: 'IRU-OFF-001',
          organizationName: 'Test Bank',
          institutionalType: 'CentralBank',
          jurisdiction: 'US',
          contactEmail: 'test@bank.com',
          contactName: 'Test User',
        })
      ).rejects.toThrow('is not active');
    });
  });

  describe('getInquiryStatusPublic', () => {
    it('omits PII and internal fields', async () => {
      const submittedAt = new Date('2026-01-01T00:00:00.000Z');
      (prisma.iruInquiry.findUnique as jest.Mock).mockResolvedValue({
        inquiryId: 'INQ-PUB',
        status: 'submitted',
        organizationName: 'Secret',
        contactEmail: 'x@y.com',
        notes: 'internal',
        qualificationResult: {},
        riskScore: 1,
        submittedAt,
        acknowledgedAt: null,
        reviewedAt: null,
        completedAt: null,
        offering: { name: 'T1', capacityTier: 1 },
      });

      const row = await marketplaceService.getInquiryStatusPublic('INQ-PUB');
      expect(row).toEqual({
        inquiryId: 'INQ-PUB',
        status: 'submitted',
        offering: { name: 'T1', capacityTier: 1 },
        submittedAt,
        acknowledgedAt: null,
        reviewedAt: null,
        completedAt: null,
      });
    });
  });
});
