/** @vitest-environment jsdom */
import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import {
  ChartContainer,
  ChartTooltipContent,
  ChartCard,
  DashboardBarChart,
  DashboardLineChart,
  HorizontalBarChart,
  ComboMetricChart,
  DonutBreakdownChart,
} from './chart';
import React from 'react';

// Mock recharts
vi.mock('recharts', () => ({
  ResponsiveContainer: ({ children }: any) => <div>{children}</div>,
  Legend: ({ children }: any) => <div>{children}</div>,
  Tooltip: ({ content, payload, active }: any) => {
    if (typeof content === 'function') return content({ payload, active });
    return React.cloneElement(content, { payload, active });
  },
  BarChart: ({ children }: any) => <div data-testid="mock-chart">{children}</div>,
  LineChart: ({ children }: any) => <div data-testid="mock-chart">{children}</div>,
  AreaChart: ({ children }: any) => <div data-testid="mock-chart">{children}</div>,
  ComposedChart: ({ children }: any) => <div data-testid="mock-chart">{children}</div>,
  PieChart: ({ children }: any) => <div data-testid="mock-chart">{children}</div>,
  CartesianGrid: ({ children }: any) => <div data-testid="mock-primitive">{children}</div>,
  XAxis: ({ children }: any) => <div data-testid="mock-primitive">{children}</div>,
  YAxis: ({ children }: any) => <div data-testid="mock-primitive">{children}</div>,
  Bar: ({ children, dataKey, barSize }: any) => (
    <div data-testid={`series-${dataKey}`} data-bar-size={barSize}>
      {children}
    </div>
  ),
  Area: ({ children, dataKey }: any) => <div data-testid={`series-${dataKey}`}>{children}</div>,
  Line: ({ children, dataKey }: any) => <div data-testid={`series-${dataKey}`}>{children}</div>,
  Pie: ({ children }: any) => <div data-testid="mock-pie">{children}</div>,
  Cell: ({ children }: any) => <div data-testid="mock-cell">{children}</div>,
  Label: ({ children }: any) => <div data-testid="mock-label">{children}</div>,
}));

describe('Chart Components', () => {
  const config = {
    label1: { label: 'Label 1', color: '#000' },
  };

  it('renders ChartContainer correctly', () => {
    render(
      <ChartContainer config={config}>
        <div data-testid="chart-child">Chart Content</div>
      </ChartContainer>
    );
    expect(screen.getByTestId('chart-child')).toBeInTheDocument();
  });

  it('renders ChartTooltipContent correctly', () => {
    const payload = [{ name: 'item1', value: 10, fill: '#000', dataKey: 'label1', graphicalItemId: 'item1' }];

    // Test the content component directly since Tooltip is tricky
    render(
      <ChartContainer config={config}>
        <ChartTooltipContent payload={payload} active={true} />
      </ChartContainer>
    );

    expect(screen.getByText('Label 1')).toBeInTheDocument();
    expect(screen.getByText('10')).toBeInTheDocument();
  });

  it('renders ChartCard structure', () => {
    render(
      <ChartCard title="Revenue" description="Monthly view" footer="Updated now">
        <div>Chart body</div>
      </ChartCard>
    );

    expect(screen.getByText('Revenue')).toBeInTheDocument();
    expect(screen.getByText('Monthly view')).toBeInTheDocument();
    expect(screen.getByText('Chart body')).toBeInTheDocument();
    expect(screen.getByText('Updated now')).toBeInTheDocument();
    expect(screen.getByText('Revenue').closest('[data-slot="card"]')).toHaveClass('w-full');
  });

  it('renders dashboard chart series from config', () => {
    render(
      <DashboardBarChart
        data={[{ name: 'Jan', revenue: 100, expenses: 80 }]}
        config={{
          revenue: { label: 'Revenue', color: 'var(--chart-1)' },
          expenses: { label: 'Expenses', color: 'var(--chart-5)' },
        }}
        colors={{ revenue: 'var(--chart-1)', expenses: 'var(--chart-5)' }}
        barSize="lg"
      />
    );

    expect(screen.getByTestId('series-revenue')).toBeInTheDocument();
    expect(screen.getByTestId('series-expenses')).toBeInTheDocument();
    expect(screen.getByTestId('series-revenue')).toHaveAttribute('data-bar-size', '22');
  });

  it('renders empty, loading, and connection error states', () => {
    render(
      <>
        <DashboardBarChart
          data={[]}
          config={{ revenue: { label: 'Revenue', color: 'var(--chart-1)' } }}
        />
        <DashboardLineChart
          data={[]}
          config={{ revenue: { label: 'Revenue', color: 'var(--chart-1)' } }}
          isLoading
        />
        <HorizontalBarChart
          data={[{ name: 'Enterprise', revenue: 100 }]}
          config={{ revenue: { label: 'Revenue', color: 'var(--chart-1)' } }}
          error="Unable to connect to the analytics service."
        />
      </>
    );

    expect(screen.getByText('No data available')).toBeInTheDocument();
    expect(screen.getByLabelText('Loading chart data')).toBeInTheDocument();
    expect(screen.getByText('Connection error')).toBeInTheDocument();
    expect(screen.getByText('Unable to connect to the analytics service.')).toBeInTheDocument();
  });

  it('renders line and horizontal chart series', () => {
    const config = {
      revenue: { label: 'Revenue', color: 'var(--chart-1)' },
      pipeline: { label: 'Pipeline', color: 'var(--chart-4)' },
    };

    render(
      <>
        <DashboardLineChart data={[{ name: 'Jan', revenue: 100, pipeline: 80 }]} config={config} />
        <HorizontalBarChart
          data={[{ name: 'Enterprise', revenue: 100 }]}
          config={config}
          series={[{ key: 'revenue' }]}
        />
      </>
    );

    expect(screen.getAllByTestId('series-revenue')[0]).toBeInTheDocument();
    expect(screen.getByTestId('series-pipeline')).toBeInTheDocument();
  });

  it('renders combo chart and donut chart primitives', () => {
    const config = {
      revenue: { label: 'Revenue', color: 'var(--chart-1)' },
      conversion: { label: 'Conversion', color: 'var(--chart-2)' },
    };

    render(
      <>
        <ComboMetricChart
          data={[{ name: 'Jan', revenue: 100, conversion: 25 }]}
          config={config}
          series={[
            { key: 'revenue', type: 'bar' },
            { key: 'conversion', type: 'line' },
          ]}
        />
        <DonutBreakdownChart
          data={[{ name: 'revenue', value: 100 }]}
          config={config}
          centerValue="100"
        />
      </>
    );

    expect(screen.getAllByTestId('series-revenue')[0]).toBeInTheDocument();
    expect(screen.getByTestId('series-conversion')).toBeInTheDocument();
  });
});
