/**
 * Comprehensive tests for PlatformBusinesses component
 *
 * Tests cover:
 * - Component rendering
 * - Loading states
 * - Error states
 * - Business filtering and search
 * - Active/inactive business separation
 * - Masquerade functionality
 * - Email verification
 * - Business editing and deletion
 * - Tenant invitation
 */

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

// Mock react-i18next
vi.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string, options?: any) => {
      if (key === 'platform.inactiveBusinesses') {
        return `Inactive Businesses (${options?.count || 0})`;
      }
      return key;
    },
  }),
}));

// Mock hooks
const mockBusinesses = vi.fn();
const mockUpdateBusiness = vi.fn();
const mockDeleteBusiness = vi.fn();

vi.mock('../../../hooks/usePlatform', () => ({
  useBusinesses: () => mockBusinesses(),
  useUpdateBusiness: () => mockUpdateBusiness(),
  useDeleteBusiness: () => mockDeleteBusiness(),
}));

// Mock API functions
const mockVerifyUserEmail = vi.fn();

vi.mock('../../../api/platform', () => ({
  verifyUserEmail: (id: number) => mockVerifyUserEmail(id),
  PlatformBusiness: {},
}));

// Mock utility functions
vi.mock('../../../utils/domain', () => ({
  getBaseDomain: () => 'smoothschedule.com',
}));

// Mock components
vi.mock('../components/PlatformListing', () => ({
  default: ({ title, description, data, renderRow, searchTerm, onSearchChange, actionButton, extraContent }: any) => (
    <div data-testid="platform-listing">
      <h1>{title}</h1>
      <p>{description}</p>
      <input
        placeholder="Search"
        value={searchTerm}
        onChange={(e) => onSearchChange(e.target.value)}
      />
      {actionButton}
      <div data-testid="business-list">
        {data.map((business: any) => (
          <div key={business.id}>{renderRow(business)}</div>
        ))}
      </div>
      {extraContent}
    </div>
  ),
}));

vi.mock('../components/PlatformTable', () => ({
  default: ({ data, renderRow }: any) => (
    <div data-testid="platform-table">
      {data.map((item: any) => (
        <div key={item.id}>{renderRow(item)}</div>
      ))}
    </div>
  ),
}));

vi.mock('../components/PlatformListRow', () => ({
  default: ({ primaryText, secondaryText, actions }: any) => (
    <div data-testid="platform-list-row">
      <div>{primaryText}</div>
      {secondaryText && <div>{secondaryText}</div>}
      <div>{actions}</div>
    </div>
  ),
}));

vi.mock('../components/TenantInviteModal', () => ({
  default: ({ isOpen, onClose }: any) =>
    isOpen ? (
      <div data-testid="invite-modal">
        <div>Invite Tenant</div>
        <button onClick={onClose}>Close</button>
      </div>
    ) : null,
}));

vi.mock('../components/EditPlatformEntityModal', () => ({
  default: ({ entity, isOpen, onClose }: any) =>
    isOpen ? (
      <div data-testid="edit-modal">
        <div>Edit Business: {entity?.name}</div>
        <button onClick={onClose}>Close</button>
      </div>
    ) : null,
}));

vi.mock('../../../components/ConfirmationModal', () => ({
  default: ({ isOpen, onClose, onConfirm, title, isLoading }: any) =>
    isOpen ? (
      <div data-testid="confirmation-modal">
        <div>{title}</div>
        <button onClick={onConfirm} disabled={isLoading}>
          Confirm
        </button>
        <button onClick={onClose}>Cancel</button>
      </div>
    ) : null,
}));

// Test data
const mockActiveBusiness = {
  id: 1,
  name: 'Active Business',
  subdomain: 'active-biz',
  tier: 'professional',
  is_active: true,
  owner: {
    id: 10,
    username: 'owner1',
    email: 'owner1@example.com',
    full_name: 'Business Owner',
    role: 'owner',
    email_verified: true,
  },
};

const mockUnverifiedBusiness = {
  id: 2,
  name: 'Unverified Business',
  subdomain: 'unverified-biz',
  tier: 'starter',
  is_active: true,
  owner: {
    id: 11,
    username: 'owner2',
    email: 'owner2@example.com',
    full_name: 'Unverified Owner',
    role: 'owner',
    email_verified: false,
  },
};

const mockInactiveBusiness = {
  id: 3,
  name: 'Inactive Business',
  subdomain: 'inactive-biz',
  tier: 'enterprise',
  is_active: false,
  owner: {
    id: 12,
    username: 'owner3',
    email: 'owner3@example.com',
    full_name: 'Inactive Owner',
    role: 'owner',
    email_verified: true,
  },
};

const mockBusinessWithoutOwner = {
  id: 4,
  name: 'No Owner Business',
  subdomain: 'no-owner',
  tier: 'starter',
  is_active: true,
  owner: null,
};

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

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

describe('PlatformBusinesses', () => {
  const mockOnMasquerade = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
    mockDeleteBusiness.mockReturnValue({
      mutateAsync: vi.fn().mockResolvedValue({}),
      isPending: false,
    });
  });

  describe('Loading State', () => {
    it('should show loading message while fetching data', () => {
      mockBusinesses.mockReturnValue({
        data: undefined,
        isLoading: true,
        error: null,
      });

      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

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

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

      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      expect(screen.getByText('errors.generic')).toBeInTheDocument();
    });
  });

  describe('Component Rendering', () => {
    beforeEach(() => {
      mockBusinesses.mockReturnValue({
        data: [mockActiveBusiness, mockUnverifiedBusiness, mockInactiveBusiness],
        isLoading: false,
        error: null,
      });
    });

    it('should render the page title', () => {
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      expect(screen.getByText('platform.businesses')).toBeInTheDocument();
    });

    it('should render the page description', () => {
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      expect(screen.getByText('platform.businessesDescription')).toBeInTheDocument();
    });

    it('should render search input', () => {
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      expect(screen.getByPlaceholderText('Search')).toBeInTheDocument();
    });

    it('should render invite tenant button', () => {
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      expect(screen.getByText('platform.inviteTenant')).toBeInTheDocument();
    });
  });

  describe('Business Filtering', () => {
    beforeEach(() => {
      mockBusinesses.mockReturnValue({
        data: [mockActiveBusiness, mockUnverifiedBusiness, mockInactiveBusiness],
        isLoading: false,
        error: null,
      });
    });

    it('should separate active and inactive businesses', () => {
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      // Active businesses should be in the main list
      const businessList = screen.getByTestId('business-list');
      expect(within(businessList).getByText('Active Business')).toBeInTheDocument();
      expect(within(businessList).getByText('Unverified Business')).toBeInTheDocument();
      expect(within(businessList).queryByText('Inactive Business')).not.toBeInTheDocument();
    });

    it('should display inactive businesses in separate section', () => {
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      expect(screen.getByText('Inactive Businesses (1)')).toBeInTheDocument();
    });

    it('should not show inactive section when no inactive businesses exist', () => {
      mockBusinesses.mockReturnValue({
        data: [mockActiveBusiness, mockUnverifiedBusiness],
        isLoading: false,
        error: null,
      });

      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      expect(screen.queryByText(/Inactive Businesses/)).not.toBeInTheDocument();
    });
  });

  describe('Search Functionality', () => {
    beforeEach(() => {
      mockBusinesses.mockReturnValue({
        data: [mockActiveBusiness, mockUnverifiedBusiness],
        isLoading: false,
        error: null,
      });
    });

    it('should filter businesses by name', async () => {
      const user = userEvent.setup();
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const searchInput = screen.getByPlaceholderText('Search');
      await user.type(searchInput, 'Active');

      await waitFor(() => {
        expect(screen.getByText('Active Business')).toBeInTheDocument();
        expect(screen.queryByText('Unverified Business')).not.toBeInTheDocument();
      });
    });

    it('should filter businesses by subdomain', async () => {
      const user = userEvent.setup();
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const searchInput = screen.getByPlaceholderText('Search');
      await user.type(searchInput, 'unverified-biz');

      await waitFor(() => {
        expect(screen.queryByText('Active Business')).not.toBeInTheDocument();
        expect(screen.getByText('Unverified Business')).toBeInTheDocument();
      });
    });

    it('should be case-insensitive', async () => {
      const user = userEvent.setup();
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const searchInput = screen.getByPlaceholderText('Search');
      await user.type(searchInput, 'ACTIVE');

      await waitFor(() => {
        expect(screen.getByText('Active Business')).toBeInTheDocument();
      });
    });
  });

  describe('Inactive Businesses Toggle', () => {
    beforeEach(() => {
      mockBusinesses.mockReturnValue({
        data: [mockActiveBusiness, mockInactiveBusiness],
        isLoading: false,
        error: null,
      });
    });

    it('should toggle inactive businesses visibility', async () => {
      const user = userEvent.setup();
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const toggleButton = screen.getByText('Inactive Businesses (1)');
      await user.click(toggleButton);

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

  describe('Email Verification', () => {
    beforeEach(() => {
      mockBusinesses.mockReturnValue({
        data: [mockUnverifiedBusiness],
        isLoading: false,
        error: null,
      });
    });

    it('should show verify button for unverified owner emails', () => {
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      expect(screen.getByText('platform.verify')).toBeInTheDocument();
    });

    it('should not show verify button for verified owner emails', () => {
      mockBusinesses.mockReturnValue({
        data: [mockActiveBusiness],
        isLoading: false,
        error: null,
      });

      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      expect(screen.queryByText('platform.verify')).not.toBeInTheDocument();
    });

    it('should open confirmation modal when clicking verify button', async () => {
      const user = userEvent.setup();
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const verifyButton = screen.getByText('platform.verify');
      await user.click(verifyButton);

      await waitFor(() => {
        expect(screen.getByTestId('confirmation-modal')).toBeInTheDocument();
        expect(screen.getByText('platform.verifyEmail')).toBeInTheDocument();
      });
    });

    it('should call verifyUserEmail API when confirming verification', async () => {
      const user = userEvent.setup();
      mockVerifyUserEmail.mockResolvedValue({});

      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const verifyButton = screen.getByText('platform.verify');
      await user.click(verifyButton);

      const confirmButton = screen.getByText('Confirm');
      await user.click(confirmButton);

      await waitFor(() => {
        expect(mockVerifyUserEmail).toHaveBeenCalledWith(mockUnverifiedBusiness.owner!.id);
      });
    });
  });

  describe('Masquerade Functionality', () => {
    beforeEach(() => {
      mockBusinesses.mockReturnValue({
        data: [mockActiveBusiness],
        isLoading: false,
        error: null,
      });
    });

    it('should show masquerade button for businesses with owners', () => {
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

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

    it('should not show masquerade button for businesses without owners', () => {
      mockBusinesses.mockReturnValue({
        data: [mockBusinessWithoutOwner],
        isLoading: false,
        error: null,
      });

      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      expect(screen.queryByText('common.masquerade')).not.toBeInTheDocument();
    });

    it('should call onMasquerade with owner data when clicking masquerade button', async () => {
      const user = userEvent.setup();
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const masqueradeButton = screen.getByText('common.masquerade');
      await user.click(masqueradeButton);

      expect(mockOnMasquerade).toHaveBeenCalledWith({
        id: mockActiveBusiness.owner!.id,
        username: mockActiveBusiness.owner!.username,
        name: mockActiveBusiness.owner!.full_name,
        email: mockActiveBusiness.owner!.email,
        role: mockActiveBusiness.owner!.role,
      });
    });
  });

  describe('Edit Functionality', () => {
    beforeEach(() => {
      mockBusinesses.mockReturnValue({
        data: [mockActiveBusiness],
        isLoading: false,
        error: null,
      });
    });

    it('should show edit button for each business', () => {
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

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

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

      const editButton = screen.getByText('common.edit');
      await user.click(editButton);

      await waitFor(() => {
        expect(screen.getByTestId('edit-modal')).toBeInTheDocument();
        expect(screen.getByText('Edit Business: Active Business')).toBeInTheDocument();
      });
    });

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

      const editButton = screen.getByText('common.edit');
      await user.click(editButton);

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

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

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

  describe('Delete Functionality', () => {
    beforeEach(() => {
      mockBusinesses.mockReturnValue({
        data: [mockActiveBusiness],
        isLoading: false,
        error: null,
      });
    });

    it('should show delete button for each business', () => {
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

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

    it('should open confirmation modal when clicking delete button', async () => {
      const user = userEvent.setup();
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const deleteButton = screen.getByText('common.delete');
      await user.click(deleteButton);

      await waitFor(() => {
        expect(screen.getByTestId('confirmation-modal')).toBeInTheDocument();
        expect(screen.getByText('platform.deleteTenant')).toBeInTheDocument();
      });
    });

    it('should call deleteBusinessMutation when confirming deletion', async () => {
      const user = userEvent.setup();
      const mutateAsync = vi.fn().mockResolvedValue({});
      mockDeleteBusiness.mockReturnValue({
        mutateAsync,
        isPending: false,
      });

      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const deleteButton = screen.getByText('common.delete');
      await user.click(deleteButton);

      const confirmButton = screen.getByText('Confirm');
      await user.click(confirmButton);

      await waitFor(() => {
        expect(mutateAsync).toHaveBeenCalledWith(mockActiveBusiness.id);
      });
    });

    it('should close modal after successful deletion', async () => {
      const user = userEvent.setup();
      const mutateAsync = vi.fn().mockResolvedValue({});
      mockDeleteBusiness.mockReturnValue({
        mutateAsync,
        isPending: false,
      });

      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const deleteButton = screen.getByText('common.delete');
      await user.click(deleteButton);

      const confirmButton = screen.getByText('Confirm');
      await user.click(confirmButton);

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

  describe('Tenant Invitation', () => {
    beforeEach(() => {
      mockBusinesses.mockReturnValue({
        data: [mockActiveBusiness],
        isLoading: false,
        error: null,
      });
    });

    it('should open invite modal when clicking invite tenant button', async () => {
      const user = userEvent.setup();
      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const inviteButton = screen.getByText('platform.inviteTenant');
      await user.click(inviteButton);

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

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

      const inviteButton = screen.getByText('platform.inviteTenant');
      await user.click(inviteButton);

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

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

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

  describe('Empty State', () => {
    it('should handle empty business list', () => {
      mockBusinesses.mockReturnValue({
        data: [],
        isLoading: false,
        error: null,
      });

      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const businessList = screen.getByTestId('business-list');
      expect(businessList).toBeEmptyDOMElement();
    });

    it('should handle search with no results', async () => {
      const user = userEvent.setup();
      mockBusinesses.mockReturnValue({
        data: [mockActiveBusiness],
        isLoading: false,
        error: null,
      });

      render(<PlatformBusinesses onMasquerade={mockOnMasquerade} />, { wrapper: createWrapper() });

      const searchInput = screen.getByPlaceholderText('Search');
      await user.type(searchInput, 'nonexistent');

      await waitFor(() => {
        const businessList = screen.getByTestId('business-list');
        expect(businessList).toBeEmptyDOMElement();
      });
    });
  });
});
