// Feature: snowui-dashboard-redesign, Property 7 & 8: ChartCard tab selection and legend toggle isolation
// **Validates: Requirements 5.1, 5.2, 5.3**

import { describe, it, expect, vi } from 'vitest';
import * as fc from 'fast-check';
import { render, fireEvent } from '@testing-library/react';
import React from 'react';
import ChartCard, { type ChartTab, type LegendToggle } from '@/components/charts/ChartCard';

/**
 * Arbitrary for generating a set of chart tabs with unique keys and identifiable content.
 * Uses predictable labels (Tab-0, Tab-1, etc.) to avoid text matching issues.
 */
const chartTabsArb = fc
  .integer({ min: 1, max: 5 })
  .map((count) => {
    const tabs: ChartTab[] = [];
    for (let i = 0; i < count; i++) {
      const key = `tab-${i}`;
      tabs.push({
        key,
        label: `Tab-${i}`,
        content: React.createElement('div', { 'data-testid': `content-${key}` }, `Content for ${key}`),
      });
    }
    return tabs;
  });

/**
 * Arbitrary for generating legend toggle items with predictable labels.
 */
const legendItemsArb = fc
  .integer({ min: 2, max: 6 })
  .chain((count) =>
    fc.array(fc.boolean(), { minLength: count, maxLength: count }).map((enabledStates) =>
      enabledStates.map((enabled, i) => ({
        key: `legend-${i}`,
        label: `Series-${i}`,
        color: ['#ff0000', '#00ff00', '#0000ff', '#ff9900', '#9900ff', '#00ffcc'][i % 6],
        enabled,
      })),
    ),
  );

describe('Property 7: ChartCard tab selection displays correct content', () => {
  it('for any set of tabs, selecting one shows only its content', () => {
    fc.assert(
      fc.property(
        chartTabsArb,
        fc.nat(),
        (tabs, selectedIndexRaw) => {
          fc.pre(tabs.length > 0);
          const selectedIndex = selectedIndexRaw % tabs.length;

          const { container, getByText, queryByTestId, unmount } = render(
            React.createElement(ChartCard, {
              title: 'Test Chart',
              tabs,
              children: React.createElement('div', null, 'fallback'),
            }),
          );

          // Click the tab at selectedIndex
          const tabButton = getByText(tabs[selectedIndex].label);
          fireEvent.click(tabButton);

          // Only the selected tab's content should be visible
          const selectedContent = queryByTestId(`content-${tabs[selectedIndex].key}`);
          expect(selectedContent).not.toBeNull();

          // Other tabs' content should not be visible
          for (let i = 0; i < tabs.length; i++) {
            if (i !== selectedIndex) {
              const otherContent = queryByTestId(`content-${tabs[i].key}`);
              expect(otherContent).toBeNull();
            }
          }

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

  it('the selected tab header is visually highlighted', () => {
    fc.assert(
      fc.property(
        chartTabsArb,
        fc.nat(),
        (tabs, selectedIndexRaw) => {
          fc.pre(tabs.length > 0);
          const selectedIndex = selectedIndexRaw % tabs.length;

          const { getByText, unmount } = render(
            React.createElement(ChartCard, {
              title: 'Test Chart',
              tabs,
              children: React.createElement('div', null, 'fallback'),
            }),
          );

          // Click the tab at selectedIndex
          const tabButton = getByText(tabs[selectedIndex].label);
          fireEvent.click(tabButton);

          // The selected tab button should have the active styling class
          expect(tabButton.className).toContain('bg-divisi-accent');

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

describe('Property 8: Legend toggle state isolation', () => {
  it('toggling a legend item affects only that item', () => {
    fc.assert(
      fc.property(
        legendItemsArb,
        fc.nat(),
        (items, toggleIndexRaw) => {
          fc.pre(items.length >= 2);
          const toggleIndex = toggleIndexRaw % items.length;

          const toggledKeys: string[] = [];
          const handleToggle = (key: string) => {
            toggledKeys.push(key);
          };

          const { container, unmount } = render(
            React.createElement(ChartCard, {
              title: 'Test Chart',
              legendItems: items,
              onLegendToggle: handleToggle,
              children: React.createElement('div', null, 'chart content'),
            }),
          );

          // Find all legend buttons
          const legendButtons = container.querySelectorAll('button');
          // Legend buttons are after any tab buttons; since no tabs, all buttons are legend
          const legendButtonArray = Array.from(legendButtons);

          // Click the target legend item
          fc.pre(legendButtonArray.length > toggleIndex);
          fireEvent.click(legendButtonArray[toggleIndex]);

          // Only the toggled item's key should have been passed to onLegendToggle
          expect(toggledKeys).toHaveLength(1);
          expect(toggledKeys[0]).toBe(items[toggleIndex].key);

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