/**
 * Unit tests for CTASection component
 *
 * Tests cover:
 * - Component rendering in both variants (default and minimal)
 * - CTA text rendering
 * - Button/link presence and navigation
 * - Click navigation behavior
 * - Icon display
 * - Internationalization (i18n)
 * - Accessibility
 * - Styling variations
 */

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import userEvent from '@testing-library/user-event';
import React from 'react';
import CTASection from '../CTASection';

// Mock react-i18next
vi.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string) => {
      const translations: Record<string, string> = {
        'marketing.cta.ready': 'Ready to get started?',
        'marketing.cta.readySubtitle': 'Join thousands of businesses already using SmoothSchedule.',
        'marketing.cta.startFree': 'Get Started Free',
        'marketing.cta.talkToSales': 'Talk to Sales',
        'marketing.cta.noCredit': 'No credit card required',
      };
      return translations[key] || key;
    },
  }),
}));

// Test wrapper with Router
const createWrapper = () => {
  return ({ children }: { children: React.ReactNode }) => (
    <BrowserRouter>{children}</BrowserRouter>
  );
};

describe('CTASection', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  describe('Default Variant', () => {
    describe('Rendering', () => {
      it('should render the CTA section', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        const heading = screen.getByRole('heading', { name: /ready to get started/i });
        expect(heading).toBeInTheDocument();
      });

      it('should render CTA text elements', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        // Main heading
        const heading = screen.getByRole('heading', { name: /ready to get started/i });
        expect(heading).toBeInTheDocument();

        // Subtitle
        const subtitle = screen.getByText(/join thousands of businesses/i);
        expect(subtitle).toBeInTheDocument();

        // No credit card required
        const disclaimer = screen.getByText(/no credit card required/i);
        expect(disclaimer).toBeInTheDocument();
      });

      it('should render with correct text hierarchy', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        const heading = screen.getByRole('heading', { name: /ready to get started/i });
        expect(heading.tagName).toBe('H2');
      });
    });

    describe('Button/Link Presence', () => {
      it('should render the signup button', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });
        expect(signupButton).toBeInTheDocument();
      });

      it('should render the talk to sales button', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        const salesButton = screen.getByRole('link', { name: /talk to sales/i });
        expect(salesButton).toBeInTheDocument();
      });

      it('should render both CTA buttons', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        const links = screen.getAllByRole('link');
        expect(links).toHaveLength(2);
      });
    });

    describe('Navigation', () => {
      it('should have correct href for signup button', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });
        expect(signupButton).toHaveAttribute('href', '/signup');
      });

      it('should have correct href for sales button', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        const salesButton = screen.getByRole('link', { name: /talk to sales/i });
        expect(salesButton).toHaveAttribute('href', '/contact');
      });

      it('should navigate when signup button is clicked', async () => {
        const user = userEvent.setup();
        render(<CTASection />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });

        // Click should not throw error
        await expect(user.click(signupButton)).resolves.not.toThrow();
      });

      it('should navigate when sales button is clicked', async () => {
        const user = userEvent.setup();
        render(<CTASection />, { wrapper: createWrapper() });

        const salesButton = screen.getByRole('link', { name: /talk to sales/i });

        // Click should not throw error
        await expect(user.click(salesButton)).resolves.not.toThrow();
      });
    });

    describe('Icon Display', () => {
      it('should display ArrowRight icon on signup button', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });
        const icon = signupButton.querySelector('svg');
        expect(icon).toBeInTheDocument();
      });

      it('should have correct icon size', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });
        const icon = signupButton.querySelector('svg');
        expect(icon).toHaveClass('h-5', 'w-5');
      });
    });

    describe('Styling', () => {
      it('should apply gradient background', () => {
        const { container } = render(<CTASection />, { wrapper: createWrapper() });

        const section = container.querySelector('section');
        expect(section).toHaveClass('bg-gradient-to-br', 'from-brand-600', 'to-brand-700');
      });

      it('should apply correct padding', () => {
        const { container } = render(<CTASection />, { wrapper: createWrapper() });

        const section = container.querySelector('section');
        expect(section).toHaveClass('py-20', 'lg:py-28');
      });

      it('should style signup button as primary CTA', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });
        expect(signupButton).toHaveClass('bg-white', 'text-brand-600');
        expect(signupButton).toHaveClass('hover:bg-brand-50');
      });

      it('should style sales button as secondary CTA', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        const salesButton = screen.getByRole('link', { name: /talk to sales/i });
        expect(salesButton).toHaveClass('bg-white/10', 'text-white');
        expect(salesButton).toHaveClass('hover:bg-white/20');
      });

      it('should have responsive button layout', () => {
        const { container } = render(<CTASection />, { wrapper: createWrapper() });

        const buttonContainer = container.querySelector('.flex.flex-col.sm\\:flex-row');
        expect(buttonContainer).toBeInTheDocument();
      });

      it('should apply shadow to signup button', () => {
        render(<CTASection />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });
        expect(signupButton).toHaveClass('shadow-lg', 'shadow-black/10');
      });
    });

    describe('Background Pattern', () => {
      it('should render decorative background elements', () => {
        const { container } = render(<CTASection />, { wrapper: createWrapper() });

        const backgroundPattern = container.querySelector('.absolute.inset-0');
        expect(backgroundPattern).toBeInTheDocument();
      });
    });
  });

  describe('Minimal Variant', () => {
    describe('Rendering', () => {
      it('should render the minimal CTA section', () => {
        render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const heading = screen.getByRole('heading', { name: /ready to get started/i });
        expect(heading).toBeInTheDocument();
      });

      it('should render CTA text in minimal variant', () => {
        render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const heading = screen.getByRole('heading', { name: /ready to get started/i });
        expect(heading).toBeInTheDocument();

        const subtitle = screen.getByText(/join thousands of businesses/i);
        expect(subtitle).toBeInTheDocument();
      });

      it('should only render one button in minimal variant', () => {
        render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const links = screen.getAllByRole('link');
        expect(links).toHaveLength(1);
      });
    });

    describe('Button/Link Presence', () => {
      it('should render only the signup button', () => {
        render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });
        expect(signupButton).toBeInTheDocument();
      });

      it('should not render the sales button', () => {
        render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const salesButton = screen.queryByRole('link', { name: /talk to sales/i });
        expect(salesButton).not.toBeInTheDocument();
      });

      it('should not render the disclaimer text', () => {
        render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const disclaimer = screen.queryByText(/no credit card required/i);
        expect(disclaimer).not.toBeInTheDocument();
      });
    });

    describe('Navigation', () => {
      it('should have correct href for signup button', () => {
        render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });
        expect(signupButton).toHaveAttribute('href', '/signup');
      });

      it('should navigate when button is clicked', async () => {
        const user = userEvent.setup();
        render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });

        // Click should not throw error
        await expect(user.click(signupButton)).resolves.not.toThrow();
      });
    });

    describe('Icon Display', () => {
      it('should display ArrowRight icon', () => {
        render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });
        const icon = signupButton.querySelector('svg');
        expect(icon).toBeInTheDocument();
      });

      it('should have correct icon size', () => {
        render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });
        const icon = signupButton.querySelector('svg');
        expect(icon).toHaveClass('h-5', 'w-5');
      });
    });

    describe('Styling', () => {
      it('should apply white background', () => {
        const { container } = render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const section = container.querySelector('section');
        expect(section).toHaveClass('bg-white', 'dark:bg-gray-900');
      });

      it('should apply minimal padding', () => {
        const { container } = render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const section = container.querySelector('section');
        expect(section).toHaveClass('py-16');
      });

      it('should use brand colors for button', () => {
        render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const signupButton = screen.getByRole('link', { name: /get started free/i });
        expect(signupButton).toHaveClass('bg-brand-600', 'text-white');
        expect(signupButton).toHaveClass('hover:bg-brand-700');
      });

      it('should have smaller heading size', () => {
        render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const heading = screen.getByRole('heading', { name: /ready to get started/i });
        expect(heading).toHaveClass('text-2xl', 'sm:text-3xl');
      });

      it('should not have gradient background', () => {
        const { container } = render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

        const section = container.querySelector('section');
        expect(section).not.toHaveClass('bg-gradient-to-br');
      });
    });
  });

  describe('Variant Comparison', () => {
    it('should render different layouts for different variants', () => {
      const { container: defaultContainer } = render(<CTASection />, { wrapper: createWrapper() });
      const { container: minimalContainer } = render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

      const defaultSection = defaultContainer.querySelector('section');
      const minimalSection = minimalContainer.querySelector('section');

      expect(defaultSection?.className).not.toEqual(minimalSection?.className);
    });

    it('should use default variant when no variant prop provided', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      // Check for elements unique to default variant
      const salesButton = screen.queryByRole('link', { name: /talk to sales/i });
      expect(salesButton).toBeInTheDocument();
    });

    it('should switch variants correctly', () => {
      const { rerender } = render(<CTASection />, { wrapper: createWrapper() });

      // Should have 2 buttons in default
      let links = screen.getAllByRole('link');
      expect(links).toHaveLength(2);

      rerender(<CTASection variant="minimal" />);

      // Should have 1 button in minimal
      links = screen.getAllByRole('link');
      expect(links).toHaveLength(1);
    });
  });

  describe('Internationalization', () => {
    it('should use translation for heading', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      const heading = screen.getByText('Ready to get started?');
      expect(heading).toBeInTheDocument();
    });

    it('should use translation for subtitle', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      const subtitle = screen.getByText('Join thousands of businesses already using SmoothSchedule.');
      expect(subtitle).toBeInTheDocument();
    });

    it('should use translation for button text', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      const signupButton = screen.getByRole('link', { name: /get started free/i });
      expect(signupButton).toHaveTextContent('Get Started Free');
    });

    it('should use translation for sales button text', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      const salesButton = screen.getByRole('link', { name: /talk to sales/i });
      expect(salesButton).toHaveTextContent('Talk to Sales');
    });

    it('should use translation for disclaimer', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      const disclaimer = screen.getByText('No credit card required');
      expect(disclaimer).toBeInTheDocument();
    });

    it('should translate all text in minimal variant', () => {
      render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

      expect(screen.getByText('Ready to get started?')).toBeInTheDocument();
      expect(screen.getByText('Join thousands of businesses already using SmoothSchedule.')).toBeInTheDocument();
      expect(screen.getByRole('link', { name: /get started free/i })).toHaveTextContent('Get Started Free');
    });
  });

  describe('Accessibility', () => {
    it('should have semantic section element', () => {
      const { container } = render(<CTASection />, { wrapper: createWrapper() });

      const section = container.querySelector('section');
      expect(section).toBeInTheDocument();
    });

    it('should have heading hierarchy', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      const heading = screen.getByRole('heading', { level: 2 });
      expect(heading).toBeInTheDocument();
    });

    it('should have keyboard accessible links', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      const signupButton = screen.getByRole('link', { name: /get started free/i });
      const salesButton = screen.getByRole('link', { name: /talk to sales/i });

      expect(signupButton.tagName).toBe('A');
      expect(salesButton.tagName).toBe('A');
    });

    it('should have descriptive link text', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      const signupButton = screen.getByRole('link', { name: /get started free/i });
      const salesButton = screen.getByRole('link', { name: /talk to sales/i });

      expect(signupButton).toHaveAccessibleName();
      expect(salesButton).toHaveAccessibleName();
    });

    it('should maintain accessibility in minimal variant', () => {
      render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

      const heading = screen.getByRole('heading', { level: 2 });
      const signupButton = screen.getByRole('link', { name: /get started free/i });

      expect(heading).toBeInTheDocument();
      expect(signupButton).toHaveAccessibleName();
    });
  });

  describe('Responsive Design', () => {
    it('should have responsive heading sizes', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      const heading = screen.getByRole('heading', { name: /ready to get started/i });
      expect(heading).toHaveClass('text-3xl', 'sm:text-4xl', 'lg:text-5xl');
    });

    it('should have responsive subtitle size', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      const subtitle = screen.getByText(/join thousands of businesses/i);
      expect(subtitle).toHaveClass('text-lg', 'sm:text-xl');
    });

    it('should have responsive button layout', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      const signupButton = screen.getByRole('link', { name: /get started free/i });
      expect(signupButton).toHaveClass('w-full', 'sm:w-auto');
    });

    it('should have responsive padding in minimal variant', () => {
      render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

      const heading = screen.getByRole('heading', { name: /ready to get started/i });
      expect(heading).toHaveClass('text-2xl', 'sm:text-3xl');
    });
  });

  describe('Integration', () => {
    it('should render correctly with default variant', () => {
      render(<CTASection />, { wrapper: createWrapper() });

      expect(screen.getByRole('heading', { name: /ready to get started/i })).toBeInTheDocument();
      expect(screen.getByText(/join thousands of businesses/i)).toBeInTheDocument();
      expect(screen.getByRole('link', { name: /get started free/i })).toHaveAttribute('href', '/signup');
      expect(screen.getByRole('link', { name: /talk to sales/i })).toHaveAttribute('href', '/contact');
      expect(screen.getByText(/no credit card required/i)).toBeInTheDocument();
    });

    it('should render correctly with minimal variant', () => {
      render(<CTASection variant="minimal" />, { wrapper: createWrapper() });

      expect(screen.getByRole('heading', { name: /ready to get started/i })).toBeInTheDocument();
      expect(screen.getByText(/join thousands of businesses/i)).toBeInTheDocument();
      expect(screen.getByRole('link', { name: /get started free/i })).toHaveAttribute('href', '/signup');
      expect(screen.queryByRole('link', { name: /talk to sales/i })).not.toBeInTheDocument();
      expect(screen.queryByText(/no credit card required/i)).not.toBeInTheDocument();
    });

    it('should maintain structure with all elements in place', () => {
      const { container } = render(<CTASection />, { wrapper: createWrapper() });

      const section = container.querySelector('section');
      const heading = screen.getByRole('heading');
      const subtitle = screen.getByText(/join thousands/i);
      const buttons = screen.getAllByRole('link');

      expect(section).toContainElement(heading);
      expect(section).toContainElement(subtitle);
      buttons.forEach(button => {
        expect(section).toContainElement(button);
      });
    });
  });
});
