import { describe, expect, it } from 'vitest';
import { render, screen } from '@testing-library/react';
import type { FunnelQueryResponse } from '../../../api/types';
import { FunnelResult } from '../components/FunnelResult';

function renderResult(props: Parameters<typeof FunnelResult>[0]) {
  return render(<FunnelResult {...props} />);
}

const readyData: FunnelQueryResponse = {
  period: 'last_7d',
  snapshot_dt: '20260623',
  data_status: 'ready',
  results: [
    {
      step_index: 1,
      name: '启动',
      event_key: 'start',
      uv: 10000,
      conversion_rate: null,
      dropoff_rate: null,
    },
    {
      step_index: 2,
      name: '曝光',
      event_key: 'show',
      uv: 8200,
      conversion_rate: 0.82,
      dropoff_rate: 0.18,
    },
  ],
};

const baseProps = {
  period: 'last_7d' as const,
  isLoading: false,
  isError: false,
};

describe('FunnelResult states', () => {
  it('ready: renders funnel chart and result table', async () => {
    renderResult({ ...baseProps, data: readyData });
    // FunnelChart is lazy-loaded — await its appearance.
    expect(await screen.findByTestId('funnel-chart')).toBeInTheDocument();
    expect(screen.getByText('UV')).toBeInTheDocument();
    expect(screen.getByText('转化率')).toBeInTheDocument();
    expect(screen.getByText('流失率')).toBeInTheDocument();
    expect(screen.getByText(/启动/)).toBeInTheDocument();
    expect(screen.getByText(/曝光/)).toBeInTheDocument();
  });

  it('ready (7d): shows the rolling "数据截至 … （近 7 天）" caption', () => {
    renderResult({ ...baseProps, data: readyData });
    expect(
      screen.getByText(/数据截至 2026-06-23（近 7 天）/),
    ).toBeInTheDocument();
    expect(screen.queryByText(/数据快照日/)).not.toBeInTheDocument();
  });

  it('ready (30d): caption says （近 30 天）', () => {
    renderResult({
      ...baseProps,
      period: 'last_30d',
      data: { ...readyData, period: 'last_30d' },
    });
    expect(
      screen.getByText(/数据截至 2026-06-23（近 30 天）/),
    ).toBeInTheDocument();
  });

  it('ready (day): shows the "数据快照日" caption', () => {
    renderResult({
      ...baseProps,
      period: 'day',
      data: { ...readyData, period: 'day' },
    });
    expect(screen.getByText(/数据快照日：2026-06-23/)).toBeInTheDocument();
    expect(screen.queryByText(/数据截至/)).not.toBeInTheDocument();
  });

  it('ready: step 1 null conversion renders as "—", not 0%', () => {
    renderResult({ ...baseProps, data: readyData });
    const dashes = screen.getAllByText('—');
    // step 1 conversion + dropoff = two em-dashes
    expect(dashes.length).toBeGreaterThanOrEqual(2);
    expect(screen.queryByText('0%')).not.toBeInTheDocument();
    expect(screen.queryByText('0.00%')).not.toBeInTheDocument();
    // the real value still shows
    expect(screen.getByText('82.00%')).toBeInTheDocument();
  });

  it('missing: explicit 数据缺失 empty state, no zeros / no chart', () => {
    renderResult({
      ...baseProps,
      data: { ...readyData, results: [], data_status: 'missing' },
    });
    expect(screen.getByText(/数据缺失/)).toBeInTheDocument();
    expect(screen.queryByTestId('funnel-chart')).not.toBeInTheDocument();
    expect(screen.queryByText('0')).not.toBeInTheDocument();
  });

  it('request error: shows error state with message', () => {
    renderResult({
      ...baseProps,
      isError: true,
      errorMessage: '网络请求失败',
    });
    expect(screen.getByText('查询失败')).toBeInTheDocument();
    expect(screen.getByText('网络请求失败')).toBeInTheDocument();
  });

  it('loading / no data yet: shows loading card', () => {
    renderResult({ ...baseProps, isLoading: true });
    expect(screen.getByTestId('funnel-loading')).toBeInTheDocument();
  });
});
