import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import TrialExpired from '../TrialExpired';

// Mock react-i18next
vi.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string, options?: Record<string, unknown>) => {
      if (options?.plan) return `${key} ${options.plan}`;
      return key;
    },
  }),
}));

// Mock react-router-dom hooks
const mockNavigate = vi.fn();
const mockOutletContext = vi.fn();

vi.mock('react-router-dom', async () => {
  const actual = await vi.importActual('react-router-dom');
  return {
    ...actual,
    useNavigate: () => mockNavigate,
    useOutletContext: () => mockOutletContext(),
  };
});

describe('TrialExpired', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    window.confirm = vi.fn(() => true);
  });

  const ownerContext = {
    user: { id: '1', role: 'owner', email: 'owner@test.com' },
    business: {
      id: '1',
      name: 'Test Business',
      plan: 'Professional',
      trialEnd: '2024-01-15'
    },
  };

  const staffContext = {
    user: { id: '2', role: 'staff', email: 'staff@test.com' },
    business: {
      id: '1',
      name: 'Test Business',
      plan: 'Professional',
      trialEnd: '2024-01-15'
    },
  };

  it('renders the trial expired title', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.getByText('trialExpired.title')).toBeInTheDocument();
  });

  it('renders free plan section', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.getByText('trialExpired.freePlan')).toBeInTheDocument();
  });

  it('renders recommended badge on paid tier', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.getByText('trialExpired.recommended')).toBeInTheDocument();
  });

  it('shows upgrade and downgrade buttons for owner', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.getByText('trialExpired.upgradeNow')).toBeInTheDocument();
    expect(screen.getByText('trialExpired.downgradeToFree')).toBeInTheDocument();
  });

  it('does not show buttons for non-owner', () => {
    mockOutletContext.mockReturnValue(staffContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.queryByText('trialExpired.upgradeNow')).not.toBeInTheDocument();
    expect(screen.queryByText('trialExpired.downgradeToFree')).not.toBeInTheDocument();
  });

  it('navigates to payments on upgrade click', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );

    fireEvent.click(screen.getByText('trialExpired.upgradeNow'));
    expect(mockNavigate).toHaveBeenCalledWith('/payments');
  });

  it('shows confirmation on downgrade click', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );

    fireEvent.click(screen.getByText('trialExpired.downgradeToFree'));
    expect(window.confirm).toHaveBeenCalledWith('trialExpired.confirmDowngrade');
  });

  it('renders business name for non-owner', () => {
    mockOutletContext.mockReturnValue(staffContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.getByText('Test Business')).toBeInTheDocument();
  });

  it('renders professional tier features', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.getByText('trialExpired.features.professional.unlimitedAppointments')).toBeInTheDocument();
  });

  it('renders free tier features', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.getByText('trialExpired.features.free.upTo50Appointments')).toBeInTheDocument();
  });

  it('renders support email link', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.getByText('trialExpired.supportEmail')).toBeInTheDocument();
  });

  it('renders business tier features when plan is Business', () => {
    mockOutletContext.mockReturnValue({
      ...ownerContext,
      business: { ...ownerContext.business, plan: 'Business' },
    });
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.getByText('trialExpired.features.business.everythingInProfessional')).toBeInTheDocument();
  });

  it('renders enterprise tier features when plan is Enterprise', () => {
    mockOutletContext.mockReturnValue({
      ...ownerContext,
      business: { ...ownerContext.business, plan: 'Enterprise' },
    });
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.getByText('trialExpired.features.enterprise.everythingInBusiness')).toBeInTheDocument();
  });

  it('shows owner-specific notice for owners', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.getByText('trialExpired.ownerLimitedFunctionality')).toBeInTheDocument();
  });

  it('shows non-owner notice for staff', () => {
    mockOutletContext.mockReturnValue(staffContext);
    render(
      <MemoryRouter>
        <TrialExpired />
      </MemoryRouter>
    );
    expect(screen.getByText('trialExpired.nonOwnerContactOwner')).toBeInTheDocument();
  });
});
