// Feature: snowui-dashboard-redesign, Property 5 & 6: KPI card elements and trend colors
// **Validates: Requirements 4.1, 4.2, 4.4**

import { describe, it, expect, vi } from 'vitest';
import * as fc from 'fast-check';
import { render } from '@testing-library/react';
import React from 'react';

// Mock Recharts components since they don't render in jsdom
vi.mock('recharts', () => ({
  ResponsiveContainer: ({ children }: { children: React.ReactNode }) =>
    React.createElement('div', { 'data-testid': 'responsive-container' }, children),
  AreaChart: ({ children }: { children: React.ReactNode }) =>
    React.createElement('div', { 'data-testid': 'area-chart' }, children),
  Area: () => React.createElement('div', { 'data-testid': 'area' }),
  defs: ({ children }: { children: React.ReactNode }) =>
    React.createElement('div', null, children),
  linearGradient: ({ children }: { children: React.ReactNode }) =>
    React.createElement('div', null, children),
  stop: () => React.createElement('div'),
}));

import KpiCard from '@/components/dashboard/KpiCard';

/**
 * Arbitrary for trend direction.
 */
const directionArb = fc.constantFrom<'up' | 'down'>('up', 'down');

/**
 * Arbitrary for valid KPI card props.
 */
const kpiPropsArb = fc.record({
  title: fc.string({ minLength: 1, maxLength: 30 }),
  value: fc.oneof(
    fc.integer({ min: 0, max: 999999 }).map(String),
    fc.integer({ min: 0, max: 999999 }),
  ),
  trend: fc.record({
    value: fc.float({ min: Math.fround(0.1), max: Math.fround(99.9), noNaN: true }),
    direction: directionArb,
  }),
  sparklineData: fc.array(fc.integer({ min: 0, max: 1000 }), { minLength: 7, maxLength: 7 }),
});

describe('Property 5: KPI card renders all required elements', () => {
  it('for any valid KPI props, all required elements render', () => {
    fc.assert(
      fc.property(kpiPropsArb, (props) => {
        const { container, unmount } = render(
          React.createElement(KpiCard, props),
        );

        // Title is present
        expect(container.textContent).toContain(props.title);

        // Value is present
        expect(container.textContent).toContain(String(props.value));

        // Trend percentage is present (the absolute value)
        const trendValue = Math.abs(props.trend.value);
        expect(container.textContent).toContain(`${trendValue}%`);

        // Directional arrow is present
        const arrow = props.trend.direction === 'up' ? '↑' : '↓';
        expect(container.textContent).toContain(arrow);

        // Sparkline container is present (the div wrapping the sparkline)
        const sparklineContainer = container.querySelector('[data-testid="responsive-container"]');
        expect(sparklineContainer).not.toBeNull();

        unmount();
      }),
      { numRuns: 100 },
    );
  });
});

describe('Property 6: KPI trend visual indicators match direction', () => {
  it('trend colors match direction: green for up, red for down', () => {
    fc.assert(
      fc.property(kpiPropsArb, (props) => {
        const { container, unmount } = render(
          React.createElement(KpiCard, props),
        );

        // Find the trend text element
        const trendSpan = container.querySelector('span.text-xs.font-medium');
        expect(trendSpan).not.toBeNull();

        if (props.trend.direction === 'up') {
          expect(trendSpan!.className).toContain('text-green-500');
        } else {
          expect(trendSpan!.className).toContain('text-red-500');
        }

        unmount();
      }),
      { numRuns: 100 },
    );
  });
});
