/**
 * StatsCards Component Tests
 *
 * Tests the admin dashboard stats cards and tier breakdown components.
 * Covers: stats display, revenue calculations, loading states, and formatting.
 */

import { render, screen } from '@testing-library/react';
import { StatsCards, TierBreakdown, formatCurrency } from '../admin/StatsCards';

describe('formatCurrency', () => {
  it('formats positive numbers as USD currency', () => {
    expect(formatCurrency(1234)).toBe('$1,234');
    expect(formatCurrency(0)).toBe('$0');
    expect(formatCurrency(999999)).toBe('$999,999');
  });

  it('rounds decimal values to whole numbers', () => {
    expect(formatCurrency(1234.56)).toBe('$1,235');
    expect(formatCurrency(1234.49)).toBe('$1,234');
  });

  it('handles negative numbers', () => {
    expect(formatCurrency(-500)).toBe('-$500');
  });
});

describe('StatsCards', () => {
  const mockStats = {
    totalDealers: 150,
    byTier: {
      starter: 50,
      growth: 40,
      enhanced: 35,
      professional: 25,
    },
    byStatus: {
      active: 120,
      pending: 15,
      suspended: 5,
      cancelled: 3,
      payment_failed: 7,
    },
  };

  describe('Normal rendering', () => {
    it('displays total dealers count', () => {
      render(<StatsCards stats={mockStats} />);
      expect(screen.getByText('150')).toBeInTheDocument();
      expect(screen.getByText('Total Dealers')).toBeInTheDocument();
    });

    it('displays active dealers count', () => {
      render(<StatsCards stats={mockStats} />);
      expect(screen.getByText('120')).toBeInTheDocument();
      expect(screen.getByText('Active')).toBeInTheDocument();
    });

    it('displays pending dealers count', () => {
      render(<StatsCards stats={mockStats} />);
      expect(screen.getByText('15')).toBeInTheDocument();
      expect(screen.getByText('Pending')).toBeInTheDocument();
    });

    it('displays payment failed count', () => {
      render(<StatsCards stats={mockStats} />);
      expect(screen.getByText('7')).toBeInTheDocument();
      expect(screen.getByText('Payment Failed')).toBeInTheDocument();
    });

    it('displays combined suspended/cancelled count', () => {
      render(<StatsCards stats={mockStats} />);
      // 5 suspended + 3 cancelled = 8
      expect(screen.getByText('8')).toBeInTheDocument();
      expect(screen.getByText('Suspended/Cancelled')).toBeInTheDocument();
    });
  });

  describe('Loading state', () => {
    it('shows skeleton cards when loading', () => {
      render(<StatsCards stats={mockStats} isLoading />);
      // Should not show actual stats
      expect(screen.queryByText('150')).not.toBeInTheDocument();
      expect(screen.queryByText('Total Dealers')).not.toBeInTheDocument();
    });
  });

  describe('Edge cases', () => {
    it('handles zero counts', () => {
      const zeroStats = {
        totalDealers: 0,
        byTier: { starter: 0, growth: 0, enhanced: 0, professional: 0 },
        byStatus: { active: 0, pending: 0, suspended: 0, cancelled: 0, payment_failed: 0 },
      };
      render(<StatsCards stats={zeroStats} />);
      expect(screen.getAllByText('0')).toHaveLength(5); // All cards show 0
    });
  });
});

describe('TierBreakdown', () => {
  const mockStats = {
    totalDealers: 150,
    byTier: {
      starter: 50,
      growth: 40,
      enhanced: 35,
      professional: 25,
    },
    byStatus: {
      active: 120,
      pending: 15,
      suspended: 5,
      cancelled: 3,
      payment_failed: 7,
    },
  };

  describe('Tier display', () => {
    it('displays all tier names', () => {
      render(<TierBreakdown stats={mockStats} />);
      expect(screen.getByText('Starter')).toBeInTheDocument();
      expect(screen.getByText('Growth')).toBeInTheDocument();
      expect(screen.getByText('Enhanced')).toBeInTheDocument();
      expect(screen.getByText('Professional')).toBeInTheDocument();
    });

    it('displays dealer counts per tier', () => {
      render(<TierBreakdown stats={mockStats} />);
      expect(screen.getByText('50')).toBeInTheDocument();
      expect(screen.getByText('40')).toBeInTheDocument();
      expect(screen.getByText('35')).toBeInTheDocument();
      expect(screen.getByText('25')).toBeInTheDocument();
    });
  });

  describe('Revenue calculations', () => {
    it('displays revenue labels in header and tier cards', () => {
      render(<TierBreakdown stats={mockStats} />);
      // "Monthly" and "Annual" appear in header + each of 4 tier cards = 5 each
      expect(screen.getAllByText('Monthly')).toHaveLength(5);
      expect(screen.getAllByText('Annual')).toHaveLength(5);
    });

    it('calculates total monthly revenue correctly', () => {
      // Based on PLAN_PRICES annualMonthly values:
      // Starter: 50 * $4 = $200
      // Growth: 40 * $25 = $1,000
      // Enhanced: 35 * $50 = $1,750
      // Professional: 25 * $200 = $5,000
      // Total: $7,950
      render(<TierBreakdown stats={mockStats} />);
      expect(screen.getByText('$7,950')).toBeInTheDocument();
    });

    it('calculates total annual revenue correctly', () => {
      // Based on PLAN_PRICES annual values:
      // Starter: 50 * $48 = $2,400
      // Growth: 40 * $300 = $12,000
      // Enhanced: 35 * $600 = $21,000
      // Professional: 25 * $2400 = $60,000
      // Total: $95,400
      render(<TierBreakdown stats={mockStats} />);
      expect(screen.getByText('$95,400')).toBeInTheDocument();
    });

    it('displays per-tier revenue breakdown', () => {
      render(<TierBreakdown stats={mockStats} />);
      // Check that monthly revenue values are present (values within spans)
      // Starter: $200, Growth: $1,000, Enhanced: $1,750, Professional: $5,000
      const tierSection = screen.getByText('By Subscription Tier').parentElement?.parentElement;
      expect(tierSection?.textContent).toContain('$200');
      expect(tierSection?.textContent).toContain('$1,000');
      expect(tierSection?.textContent).toContain('$1,750');
      expect(tierSection?.textContent).toContain('$5,000');
    });
  });

  describe('Tooltips', () => {
    it('has tooltip on header revenue totals explaining assumption', () => {
      render(<TierBreakdown stats={mockStats} />);
      // Get all Monthly labels, first one is in the header
      const monthlyLabels = screen.getAllByText('Monthly');
      const headerMonthlyLabel = monthlyLabels[0].closest('span');
      expect(headerMonthlyLabel?.parentElement).toHaveAttribute(
        'title',
        'Assumes annual billing for all dealers'
      );
    });
  });

  describe('Edge cases', () => {
    it('handles zero dealers across all tiers', () => {
      const zeroStats = {
        totalDealers: 0,
        byTier: { starter: 0, growth: 0, enhanced: 0, professional: 0 },
        byStatus: { active: 0, pending: 0, suspended: 0, cancelled: 0, payment_failed: 0 },
      };
      render(<TierBreakdown stats={zeroStats} />);
      // Header shows 2 $0 values (monthly + annual), plus per-tier breakdowns (4 tiers × 2 = 8)
      // Total: 10 instances of $0
      expect(screen.getAllByText('$0')).toHaveLength(10);
    });

    it('handles single tier with dealers', () => {
      const singleTierStats = {
        totalDealers: 10,
        byTier: { starter: 10, growth: 0, enhanced: 0, professional: 0 },
        byStatus: { active: 10, pending: 0, suspended: 0, cancelled: 0, payment_failed: 0 },
      };
      render(<TierBreakdown stats={singleTierStats} />);
      // Header shows $40 monthly and $480 annual (same as Starter tier values since others are 0)
      // These values appear in both header totals and Starter tier row
      expect(screen.getAllByText('$40')).toHaveLength(2); // Header + Starter monthly
      expect(screen.getAllByText('$480')).toHaveLength(2); // Header + Starter annual
    });
  });
});
