import { render, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { CostCalculator } from '../CostCalculator';

// Mock motion/react to render plain divs in tests
vi.mock('motion/react', () => ({
  motion: {
    div: ({ children, ...props }: React.PropsWithChildren<Record<string, unknown>>) => {
      const motionKeys = new Set(['initial', 'animate', 'transition', 'viewport', 'variants']);
      const htmlProps = Object.fromEntries(
        Object.entries(props).filter(([key]) => !motionKeys.has(key) && !key.startsWith('while'))
      );
      return <div {...(htmlProps as React.HTMLAttributes<HTMLDivElement>)}>{children}</div>;
    },
    span: ({ children, ...props }: React.PropsWithChildren<Record<string, unknown>>) => {
      const motionKeys = new Set(['initial', 'animate', 'transition', 'viewport', 'variants']);
      const htmlProps = Object.fromEntries(
        Object.entries(props).filter(([key]) => !motionKeys.has(key) && !key.startsWith('while'))
      );
      return <span {...(htmlProps as React.HTMLAttributes<HTMLSpanElement>)}>{children}</span>;
    },
  },
  useReducedMotion: () => true,
  AnimatePresence: ({ children }: React.PropsWithChildren) => <>{children}</>,
}));

describe('CostCalculator', () => {
  it('renders two sliders', () => {
    const { container } = render(<CostCalculator />);
    const sliders = container.querySelectorAll('input[type="range"]');
    expect(sliders.length).toBe(2);
  });

  it('displays $0 for LLMHosts local', () => {
    const { getByText } = render(<CostCalculator />);
    // LLMHosts Local card should show $0
    expect(getByText('LLMHosts Local')).toBeTruthy();
    expect(getByText('$0')).toBeTruthy();
  });

  it('displays positive cost for RunPod with correct formula', () => {
    const { getByTestId } = render(<CostCalculator />);
    // Default: 50,000 requests * 500 tokens * 30 days = 750,000,000 tokens
    // RunPod: (750,000,000 / 1000) * 0.0003 = $225
    const runpodCost = getByTestId('runpod-cost');
    expect(runpodCost.textContent).toBe('$225');
  });

  it('calculates savings correctly at default values', () => {
    const { getByTestId } = render(<CostCalculator />);
    // Together.ai: (750,000,000 / 1000) * 0.0002 = $150
    const togetherCost = getByTestId('together-cost');
    expect(togetherCost.textContent).toBe('$150');

    // Savings vs Together.ai = $150 - $0 = $150
    const savings = getByTestId('savings-amount');
    expect(savings.textContent).toContain('$150');
  });

  it('shows yearly savings when monthly savings > $100', () => {
    const { getByTestId } = render(<CostCalculator />);
    // $150/month * 12 = $1,800/year
    const yearlySavings = getByTestId('yearly-savings');
    expect(yearlySavings.textContent).toContain('$1,800');
  });

  it('has a CTA link to register', () => {
    const { getByRole } = render(<CostCalculator />);
    const cta = getByRole('link', { name: /start saving/i });
    expect(cta).toBeTruthy();
    expect(cta.getAttribute('href')).toBe('/auth/register');
  });

  it('updates calculations when sliders change', () => {
    const { container, getByTestId } = render(<CostCalculator />);
    const sliders = container.querySelectorAll('input[type="range"]');
    const requestsSlider = sliders[0] as HTMLInputElement;

    // Change requests to 100,000
    fireEvent.change(requestsSlider, { target: { value: '100000' } });

    // 100,000 * 500 * 30 = 1,500,000,000 tokens
    // RunPod: (1,500,000,000 / 1000) * 0.0003 = $450
    const runpodCost = getByTestId('runpod-cost');
    expect(runpodCost.textContent).toBe('$450');
  });
});
