/**
 * Comprehensive tests for PlatformSupport component
 *
 * Tests cover:
 * - Component rendering
 * - Loading states
 * - Error states
 * - Ticket filtering by status
 * - Ticket display
 * - User interactions (new ticket, refresh emails)
 * - Status tabs
 * - Empty states
 */

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import PlatformSupport from '../PlatformSupport';
import toast from 'react-hot-toast';

// Mock react-i18next
vi.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string, fallback?: string) => fallback || key,
  }),
}));

// Mock hooks
const mockTickets = vi.fn();
const mockRefreshTicketEmails = vi.fn();
const mockTicketWebSocket = vi.fn();

vi.mock('../../../hooks/useTickets', () => ({
  useTickets: () => mockTickets(),
  useRefreshTicketEmails: () => mockRefreshTicketEmails(),
}));

vi.mock('../../../hooks/useTicketWebSocket', () => ({
  useTicketWebSocket: () => mockTicketWebSocket(),
}));

// Mock toast
vi.mock('react-hot-toast', () => ({
  default: {
    success: vi.fn(),
    error: vi.fn(),
  },
}));

// Mock components
vi.mock('../../../components/TicketModal', () => ({
  default: ({ ticket, onClose }: any) => (
    <div data-testid="ticket-modal">
      <div>Ticket: {ticket?.subject || 'New Ticket'}</div>
      <button onClick={onClose}>Close Modal</button>
    </div>
  ),
}));

vi.mock('../../../components/Portal', () => ({
  default: ({ children }: any) => <div data-testid="portal">{children}</div>,
}));

// Test data
const mockOpenTicket = {
  id: '1',
  subject: 'Login Issue',
  creatorEmail: 'user@example.com',
  creatorFullName: 'John Doe',
  status: 'OPEN' as const,
  priority: 'HIGH',
  ticketType: 'PLATFORM',
  category: 'TECHNICAL',
  createdAt: '2024-12-01T10:00:00Z',
  isOverdue: false,
  assigneeFullName: null,
  source_email_address: {
    display_name: 'Support',
    color: '#3B82F6',
  },
};

const mockInProgressTicket = {
  id: '2',
  subject: 'Payment Problem',
  creatorEmail: 'customer@example.com',
  creatorFullName: 'Jane Smith',
  status: 'IN_PROGRESS' as const,
  priority: 'URGENT',
  ticketType: 'CUSTOMER',
  category: 'BILLING',
  createdAt: '2024-12-02T14:30:00Z',
  isOverdue: true,
  assigneeFullName: 'Support Staff',
  source_email_address: null,
};

const mockResolvedTicket = {
  id: '3',
  subject: 'Feature Request',
  creatorEmail: 'business@example.com',
  creatorFullName: 'Business Owner',
  status: 'RESOLVED' as const,
  priority: 'LOW',
  ticketType: 'BUSINESS',
  category: 'FEATURE_REQUEST',
  createdAt: '2024-11-25T09:15:00Z',
  isOverdue: false,
  assigneeFullName: 'Platform Manager',
  source_email_address: null,
};

// Test wrapper
const createWrapper = () => {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: { retry: false },
    },
  });

  return ({ children }: { children: React.ReactNode }) => (
    <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  );
};

describe('PlatformSupport', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    mockTicketWebSocket.mockReturnValue({});
    mockRefreshTicketEmails.mockReturnValue({
      mutateAsync: vi.fn().mockResolvedValue({ processed: 0 }),
      isPending: false,
    });
  });

  describe('Loading State', () => {
    it('should show loading spinner while fetching tickets', () => {
      mockTickets.mockReturnValue({
        data: undefined,
        isLoading: true,
        error: null,
        refetch: vi.fn(),
      });

      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('common.loading')).toBeInTheDocument();
    });
  });

  describe('Error State', () => {
    it('should display error message when data fetch fails', () => {
      mockTickets.mockReturnValue({
        data: undefined,
        isLoading: false,
        error: new Error('Failed to load'),
        refetch: vi.fn(),
      });

      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('tickets.errorLoading')).toBeInTheDocument();
    });
  });

  describe('Component Rendering', () => {
    beforeEach(() => {
      mockTickets.mockReturnValue({
        data: [mockOpenTicket, mockInProgressTicket, mockResolvedTicket],
        isLoading: false,
        error: null,
        refetch: vi.fn(),
      });
    });

    it('should render the page header', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('platform.supportTickets')).toBeInTheDocument();
      expect(screen.getByText('platform.supportDescription')).toBeInTheDocument();
    });

    it('should render the check emails button', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('Check Emails')).toBeInTheDocument();
    });

    it('should render the new ticket button', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('tickets.newTicket')).toBeInTheDocument();
    });
  });

  describe('Status Tabs', () => {
    beforeEach(() => {
      mockTickets.mockReturnValue({
        data: [mockOpenTicket, mockInProgressTicket, mockResolvedTicket],
        isLoading: false,
        error: null,
        refetch: vi.fn(),
      });
    });

    it('should render all status tabs', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('All')).toBeInTheDocument();
      expect(screen.getByText('Open')).toBeInTheDocument();
      expect(screen.getByText('In Progress')).toBeInTheDocument();
      expect(screen.getByText('Awaiting')).toBeInTheDocument();
      expect(screen.getByText('Resolved')).toBeInTheDocument();
      expect(screen.getByText('Closed')).toBeInTheDocument();
    });

    it('should display correct ticket counts in tabs', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      // All tab should show 3
      const allTab = screen.getByText('All').closest('button');
      expect(allTab).toHaveTextContent('3');

      // Open tab should show 1
      const openTab = screen.getByText('Open').closest('button');
      expect(openTab).toHaveTextContent('1');

      // In Progress tab should show 1
      const inProgressTab = screen.getByText('In Progress').closest('button');
      expect(inProgressTab).toHaveTextContent('1');

      // Resolved tab should show 1
      const resolvedTab = screen.getByText('Resolved').closest('button');
      expect(resolvedTab).toHaveTextContent('1');
    });

    it('should filter tickets when clicking status tab', async () => {
      const user = userEvent.setup();
      render(<PlatformSupport />, { wrapper: createWrapper() });

      // Initially shows all tickets
      expect(screen.getByText('Login Issue')).toBeInTheDocument();
      expect(screen.getByText('Payment Problem')).toBeInTheDocument();
      expect(screen.getByText('Feature Request')).toBeInTheDocument();

      // Click "Open" tab
      const openTab = screen.getByText('Open').closest('button');
      await user.click(openTab!);

      // Should only show open ticket
      expect(screen.getByText('Login Issue')).toBeInTheDocument();
      expect(screen.queryByText('Payment Problem')).not.toBeInTheDocument();
      expect(screen.queryByText('Feature Request')).not.toBeInTheDocument();
    });

    it('should highlight active tab', async () => {
      const user = userEvent.setup();
      render(<PlatformSupport />, { wrapper: createWrapper() });

      const openTab = screen.getByText('Open').closest('button');
      await user.click(openTab!);

      expect(openTab).toHaveClass('bg-brand-600');
    });
  });

  describe('Ticket Display', () => {
    beforeEach(() => {
      mockTickets.mockReturnValue({
        data: [mockOpenTicket, mockInProgressTicket, mockResolvedTicket],
        isLoading: false,
        error: null,
        refetch: vi.fn(),
      });
    });

    it('should display ticket subjects', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('Login Issue')).toBeInTheDocument();
      expect(screen.getByText('Payment Problem')).toBeInTheDocument();
      expect(screen.getByText('Feature Request')).toBeInTheDocument();
    });

    it('should display ticket IDs', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('#1')).toBeInTheDocument();
      expect(screen.getByText('#2')).toBeInTheDocument();
      expect(screen.getByText('#3')).toBeInTheDocument();
    });

    it('should display ticket creator information', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('John Doe')).toBeInTheDocument();
      expect(screen.getByText('Jane Smith')).toBeInTheDocument();
      expect(screen.getByText('Business Owner')).toBeInTheDocument();
    });

    it('should display ticket priorities', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('tickets.priorities.high')).toBeInTheDocument();
      expect(screen.getByText('tickets.priorities.urgent')).toBeInTheDocument();
      expect(screen.getByText('tickets.priorities.low')).toBeInTheDocument();
    });

    it('should display ticket types', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('tickets.types.platform')).toBeInTheDocument();
      expect(screen.getByText('tickets.types.customer')).toBeInTheDocument();
      expect(screen.getByText('tickets.types.business')).toBeInTheDocument();
    });

    it('should display assignee information', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      // Check for assignee info in the rendered content
      // The assignee names are displayed as part of ticket details
      const ticketDetails = screen.getByText('Jane Smith');
      expect(ticketDetails).toBeInTheDocument();

      // Check that tickets with assignees are rendered
      expect(screen.getByText('Payment Problem')).toBeInTheDocument();
      expect(screen.getByText('Feature Request')).toBeInTheDocument();
    });

    it('should display overdue indicator', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('Overdue')).toBeInTheDocument();
    });

    it('should display source email address', () => {
      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('Support')).toBeInTheDocument();
    });
  });

  describe('Empty States', () => {
    it('should display empty state when no tickets exist', () => {
      mockTickets.mockReturnValue({
        data: [],
        isLoading: false,
        error: null,
        refetch: vi.fn(),
      });

      render(<PlatformSupport />, { wrapper: createWrapper() });

      expect(screen.getByText('tickets.noTicketsFound')).toBeInTheDocument();
    });

    it('should display empty state for filtered status with no tickets', async () => {
      const user = userEvent.setup();
      mockTickets.mockReturnValue({
        data: [mockOpenTicket],
        isLoading: false,
        error: null,
        refetch: vi.fn(),
      });

      render(<PlatformSupport />, { wrapper: createWrapper() });

      // Click "Closed" tab which has no tickets
      const closedTab = screen.getByText('Closed').closest('button');
      await user.click(closedTab!);

      expect(screen.getByText('tickets.noTicketsFound')).toBeInTheDocument();
    });
  });

  describe('User Interactions', () => {
    beforeEach(() => {
      mockTickets.mockReturnValue({
        data: [mockOpenTicket],
        isLoading: false,
        error: null,
        refetch: vi.fn(),
      });
    });

    it('should open ticket modal when clicking a ticket', async () => {
      const user = userEvent.setup();
      render(<PlatformSupport />, { wrapper: createWrapper() });

      const ticket = screen.getByText('Login Issue');
      await user.click(ticket);

      await waitFor(() => {
        expect(screen.getByTestId('ticket-modal')).toBeInTheDocument();
        expect(screen.getByText('Ticket: Login Issue')).toBeInTheDocument();
      });
    });

    it('should open new ticket modal when clicking new ticket button', async () => {
      const user = userEvent.setup();
      render(<PlatformSupport />, { wrapper: createWrapper() });

      const newTicketButton = screen.getByText('tickets.newTicket');
      await user.click(newTicketButton);

      await waitFor(() => {
        expect(screen.getByTestId('ticket-modal')).toBeInTheDocument();
        expect(screen.getByText('Ticket: New Ticket')).toBeInTheDocument();
      });
    });

    it('should close modal when clicking close button', async () => {
      const user = userEvent.setup();
      render(<PlatformSupport />, { wrapper: createWrapper() });

      const ticket = screen.getByText('Login Issue');
      await user.click(ticket);

      await waitFor(() => {
        expect(screen.getByTestId('ticket-modal')).toBeInTheDocument();
      });

      const closeButton = screen.getByText('Close Modal');
      await user.click(closeButton);

      await waitFor(() => {
        expect(screen.queryByTestId('ticket-modal')).not.toBeInTheDocument();
      });
    });
  });

  describe('Email Refresh Functionality', () => {
    beforeEach(() => {
      mockTickets.mockReturnValue({
        data: [mockOpenTicket],
        isLoading: false,
        error: null,
        refetch: vi.fn(),
      });
    });

    it('should call refresh emails mutation when clicking check emails button', async () => {
      const user = userEvent.setup();
      const mutateAsync = vi.fn().mockResolvedValue({ processed: 2 });
      mockRefreshTicketEmails.mockReturnValue({
        mutateAsync,
        isPending: false,
      });

      render(<PlatformSupport />, { wrapper: createWrapper() });

      const checkEmailsButton = screen.getByText('Check Emails');
      await user.click(checkEmailsButton);

      await waitFor(() => {
        expect(mutateAsync).toHaveBeenCalled();
      });
    });

    it('should show success toast when emails are processed', async () => {
      const user = userEvent.setup();
      const mutateAsync = vi.fn().mockResolvedValue({ processed: 3 });
      mockRefreshTicketEmails.mockReturnValue({
        mutateAsync,
        isPending: false,
      });

      render(<PlatformSupport />, { wrapper: createWrapper() });

      const checkEmailsButton = screen.getByText('Check Emails');
      await user.click(checkEmailsButton);

      await waitFor(() => {
        expect(toast.success).toHaveBeenCalledWith('Processed 3 new email(s)');
      });
    });

    it('should show success toast when no new emails found', async () => {
      const user = userEvent.setup();
      const mutateAsync = vi.fn().mockResolvedValue({ processed: 0 });
      mockRefreshTicketEmails.mockReturnValue({
        mutateAsync,
        isPending: false,
      });

      render(<PlatformSupport />, { wrapper: createWrapper() });

      const checkEmailsButton = screen.getByText('Check Emails');
      await user.click(checkEmailsButton);

      await waitFor(() => {
        expect(toast.success).toHaveBeenCalledWith('No new emails found');
      });
    });

    it('should show error toast when refresh fails', async () => {
      const user = userEvent.setup();
      const mutateAsync = vi.fn().mockRejectedValue({
        response: { data: { error: 'Connection failed' } },
      });
      mockRefreshTicketEmails.mockReturnValue({
        mutateAsync,
        isPending: false,
      });

      render(<PlatformSupport />, { wrapper: createWrapper() });

      const checkEmailsButton = screen.getByText('Check Emails');
      await user.click(checkEmailsButton);

      await waitFor(() => {
        expect(toast.error).toHaveBeenCalledWith('Connection failed');
      });
    });

    it('should disable button while refreshing', () => {
      mockRefreshTicketEmails.mockReturnValue({
        mutateAsync: vi.fn(),
        isPending: true,
      });

      render(<PlatformSupport />, { wrapper: createWrapper() });

      const checkEmailsButton = screen.getByText('Checking...');
      expect(checkEmailsButton).toBeDisabled();
    });
  });

  describe('WebSocket Integration', () => {
    it('should initialize ticket websocket', () => {
      mockTickets.mockReturnValue({
        data: [],
        isLoading: false,
        error: null,
        refetch: vi.fn(),
      });

      render(<PlatformSupport />, { wrapper: createWrapper() });

      // Just verify the websocket hook was called
      expect(mockTicketWebSocket).toHaveBeenCalled();
    });
  });
});
