/**
 * Unit tests for WidgetConfigModal component
 *
 * Tests cover:
 * - Component rendering and visibility
 * - Modal open/close behavior
 * - Widget list display
 * - Widget toggle functionality
 * - Active widget highlighting
 * - Reset layout functionality
 * - Widget icons display
 * - Internationalization (i18n)
 * - Accessibility
 * - Backdrop click handling
 */

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

// Mock react-i18next
vi.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string) => {
      const translations: Record<string, string> = {
        'dashboard.configureWidgets': 'Configure Widgets',
        'dashboard.configureWidgetsDescription': 'Choose which widgets to display on your dashboard',
        'dashboard.resetToDefault': 'Reset to Default',
        'dashboard.done': 'Done',
        // Widget titles
        'dashboard.widgetTitles.appointmentsMetric': 'Total Appointments',
        'dashboard.widgetTitles.customersMetric': 'Active Customers',
        'dashboard.widgetTitles.servicesMetric': 'Services',
        'dashboard.widgetTitles.resourcesMetric': 'Resources',
        'dashboard.widgetTitles.revenueChart': 'Revenue',
        'dashboard.widgetTitles.appointmentsChart': 'Appointments Trend',
        'dashboard.widgetTitles.openTickets': 'Open Tickets',
        'dashboard.widgetTitles.recentActivity': 'Recent Activity',
        'dashboard.widgetTitles.capacityUtilization': 'Capacity Utilization',
        'dashboard.widgetTitles.noShowRate': 'No-Show Rate',
        'dashboard.widgetTitles.customerBreakdown': 'New vs Returning',
        // Widget descriptions
        'dashboard.widgetDescriptions.appointmentsMetric': 'Shows appointment count with weekly and monthly growth',
        'dashboard.widgetDescriptions.customersMetric': 'Shows customer count with weekly and monthly growth',
        'dashboard.widgetDescriptions.servicesMetric': 'Shows number of services offered',
        'dashboard.widgetDescriptions.resourcesMetric': 'Shows number of resources available',
        'dashboard.widgetDescriptions.revenueChart': 'Weekly revenue bar chart',
        'dashboard.widgetDescriptions.appointmentsChart': 'Weekly appointments line chart',
        'dashboard.widgetDescriptions.openTickets': 'Shows open support tickets requiring attention',
        'dashboard.widgetDescriptions.recentActivity': 'Timeline of recent business events',
        'dashboard.widgetDescriptions.capacityUtilization': 'Shows how booked your resources are this week',
        'dashboard.widgetDescriptions.noShowRate': 'Percentage of appointments marked as no-show',
        'dashboard.widgetDescriptions.customerBreakdown': 'Customer breakdown this month',
      };
      return translations[key] || key;
    },
  }),
}));

describe('WidgetConfigModal', () => {
  const mockOnClose = vi.fn();
  const mockOnToggleWidget = vi.fn();
  const mockOnResetLayout = vi.fn();

  const defaultProps = {
    isOpen: true,
    onClose: mockOnClose,
    activeWidgets: ['appointments-metric', 'customers-metric', 'revenue-chart'],
    onToggleWidget: mockOnToggleWidget,
    onResetLayout: mockOnResetLayout,
  };

  beforeEach(() => {
    vi.clearAllMocks();
  });

  describe('Modal Visibility', () => {
    it('should render when isOpen is true', () => {
      render(<WidgetConfigModal {...defaultProps} />);
      expect(screen.getByText('Configure Widgets')).toBeInTheDocument();
    });

    it('should not render when isOpen is false', () => {
      render(<WidgetConfigModal {...defaultProps} isOpen={false} />);
      expect(screen.queryByText('Configure Widgets')).not.toBeInTheDocument();
    });

    it('should return null when not open', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} isOpen={false} />);
      expect(container.firstChild).toBeNull();
    });
  });

  describe('Modal Header', () => {
    it('should render modal title', () => {
      render(<WidgetConfigModal {...defaultProps} />);
      const title = screen.getByText('Configure Widgets');
      expect(title).toBeInTheDocument();
      expect(title).toHaveClass('text-lg', 'font-semibold');
    });

    it('should render close button in header', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      // Close button (X icon) should be present
      const closeButtons = container.querySelectorAll('button');
      expect(closeButtons.length).toBeGreaterThan(0);
    });

    it('should call onClose when header close button is clicked', async () => {
      const user = userEvent.setup();
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      // Find the X button in header
      const buttons = container.querySelectorAll('button');
      const closeButton = Array.from(buttons).find(btn =>
        btn.querySelector('svg')
      ) as HTMLElement;

      if (closeButton) {
        await user.click(closeButton);
        expect(mockOnClose).toHaveBeenCalledTimes(1);
      }
    });
  });

  describe('Modal Content', () => {
    it('should render description text', () => {
      render(<WidgetConfigModal {...defaultProps} />);
      expect(screen.getByText('Choose which widgets to display on your dashboard')).toBeInTheDocument();
    });

    it('should render all widget options', () => {
      render(<WidgetConfigModal {...defaultProps} />);

      // Check for widget titles
      expect(screen.getByText('Total Appointments')).toBeInTheDocument();
      expect(screen.getByText('Active Customers')).toBeInTheDocument();
      expect(screen.getByText('Services')).toBeInTheDocument();
      expect(screen.getByText('Resources')).toBeInTheDocument();
      expect(screen.getByText('Revenue')).toBeInTheDocument();
      expect(screen.getByText('Appointments Trend')).toBeInTheDocument();
      expect(screen.getByText('Open Tickets')).toBeInTheDocument();
      expect(screen.getByText('Recent Activity')).toBeInTheDocument();
      expect(screen.getByText('Capacity Utilization')).toBeInTheDocument();
      expect(screen.getByText('No-Show Rate')).toBeInTheDocument();
      expect(screen.getByText('New vs Returning')).toBeInTheDocument();
    });

    it('should render widget descriptions', () => {
      render(<WidgetConfigModal {...defaultProps} />);

      expect(screen.getByText('Shows appointment count with weekly and monthly growth')).toBeInTheDocument();
      expect(screen.getByText('Timeline of recent business events')).toBeInTheDocument();
    });

    it('should render widget icons', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      // Should have multiple SVG icons
      const svgs = container.querySelectorAll('svg');
      expect(svgs.length).toBeGreaterThan(10); // At least one per widget
    });
  });

  describe('Widget Selection', () => {
    it('should highlight active widgets', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      // Active widgets should have brand-500 border
      const activeWidgets = container.querySelectorAll('.border-brand-500');
      expect(activeWidgets.length).toBe(defaultProps.activeWidgets.length);
    });

    it('should show checkmark on active widgets', () => {
      render(<WidgetConfigModal {...defaultProps} />);

      // Check icons should be present for active widgets
      const { container } = render(<WidgetConfigModal {...defaultProps} />);
      const svgs = container.querySelectorAll('svg');

      // Should have check icons (hard to test exact count due to other icons)
      expect(svgs.length).toBeGreaterThan(0);
    });

    it('should not highlight inactive widgets', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      // Inactive widgets should have gray border
      const inactiveWidgets = container.querySelectorAll('.border-gray-200');
      expect(inactiveWidgets.length).toBeGreaterThan(0);
    });

    it('should call onToggleWidget when widget is clicked', async () => {
      const user = userEvent.setup();
      render(<WidgetConfigModal {...defaultProps} />);

      const widget = screen.getByText('Total Appointments').closest('button');
      expect(widget).toBeInTheDocument();

      if (widget) {
        await user.click(widget);
        expect(mockOnToggleWidget).toHaveBeenCalledWith('appointments-metric');
      }
    });

    it('should call onToggleWidget with correct widget ID', async () => {
      const user = userEvent.setup();
      render(<WidgetConfigModal {...defaultProps} />);

      const revenueWidget = screen.getByText('Revenue').closest('button');
      if (revenueWidget) {
        await user.click(revenueWidget);
        expect(mockOnToggleWidget).toHaveBeenCalledWith('revenue-chart');
      }

      const ticketsWidget = screen.getByText('Open Tickets').closest('button');
      if (ticketsWidget) {
        await user.click(ticketsWidget);
        expect(mockOnToggleWidget).toHaveBeenCalledWith('open-tickets');
      }
    });

    it('should allow toggling multiple widgets', async () => {
      const user = userEvent.setup();
      render(<WidgetConfigModal {...defaultProps} />);

      const widget1 = screen.getByText('Services').closest('button');
      const widget2 = screen.getByText('Resources').closest('button');

      if (widget1) await user.click(widget1);
      if (widget2) await user.click(widget2);

      expect(mockOnToggleWidget).toHaveBeenCalledTimes(2);
    });
  });

  describe('Active Widget Styling', () => {
    it('should apply active styling to selected widgets', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      // Active widgets should have brand colors
      const brandBg = container.querySelectorAll('.bg-brand-50');
      expect(brandBg.length).toBeGreaterThan(0);
    });

    it('should apply inactive styling to unselected widgets', () => {
      const { container } = render(
        <WidgetConfigModal
          {...defaultProps}
          activeWidgets={['appointments-metric']} // Only one active
        />
      );

      // Many widgets should have gray styling
      const grayBorders = container.querySelectorAll('.border-gray-200');
      expect(grayBorders.length).toBeGreaterThan(5);
    });

    it('should apply different icon colors for active vs inactive', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      // Active widgets should have brand icon colors
      const brandIcons = container.querySelectorAll('.text-brand-600');
      expect(brandIcons.length).toBeGreaterThan(0);

      // Inactive widgets should have gray icon colors
      const grayIcons = container.querySelectorAll('.text-gray-500');
      expect(grayIcons.length).toBeGreaterThan(0);
    });
  });

  describe('Modal Footer', () => {
    it('should render reset button', () => {
      render(<WidgetConfigModal {...defaultProps} />);
      expect(screen.getByText('Reset to Default')).toBeInTheDocument();
    });

    it('should render done button', () => {
      render(<WidgetConfigModal {...defaultProps} />);
      expect(screen.getByText('Done')).toBeInTheDocument();
    });

    it('should call onResetLayout when reset button is clicked', async () => {
      const user = userEvent.setup();
      render(<WidgetConfigModal {...defaultProps} />);

      const resetButton = screen.getByText('Reset to Default');
      await user.click(resetButton);

      expect(mockOnResetLayout).toHaveBeenCalledTimes(1);
    });

    it('should call onClose when done button is clicked', async () => {
      const user = userEvent.setup();
      render(<WidgetConfigModal {...defaultProps} />);

      const doneButton = screen.getByText('Done');
      await user.click(doneButton);

      expect(mockOnClose).toHaveBeenCalledTimes(1);
    });
  });

  describe('Backdrop Interaction', () => {
    it('should render backdrop', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      // Backdrop div with bg-black/50
      const backdrop = container.querySelector('.bg-black\\/50');
      expect(backdrop).toBeInTheDocument();
    });

    it('should call onClose when backdrop is clicked', async () => {
      const user = userEvent.setup();
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      const backdrop = container.querySelector('.bg-black\\/50') as HTMLElement;
      expect(backdrop).toBeInTheDocument();

      if (backdrop) {
        await user.click(backdrop);
        expect(mockOnClose).toHaveBeenCalledTimes(1);
      }
    });

    it('should not call onClose when modal content is clicked', async () => {
      const user = userEvent.setup();
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      // Click on modal content, not backdrop
      const modalContent = container.querySelector('.bg-white') as HTMLElement;
      if (modalContent) {
        await user.click(modalContent);
        expect(mockOnClose).not.toHaveBeenCalled();
      }
    });
  });

  describe('Widget Grid Layout', () => {
    it('should display widgets in a grid', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      // Grid container should exist
      const grid = container.querySelector('.grid');
      expect(grid).toBeInTheDocument();
      expect(grid).toHaveClass('grid-cols-1', 'sm:grid-cols-2');
    });

    it('should render all 11 widgets', () => {
      render(<WidgetConfigModal {...defaultProps} />);

      // Count widget buttons
      const widgetButtons = screen.getAllByRole('button');
      // Should have 11 widget buttons + 2 footer buttons + 1 close button = 14 total
      expect(widgetButtons.length).toBeGreaterThanOrEqual(11);
    });
  });

  describe('Styling', () => {
    it('should apply modal container styles', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      const modal = container.querySelector('.bg-white');
      expect(modal).toHaveClass(
        'bg-white',
        'rounded-xl',
        'shadow-xl',
        'max-w-2xl',
        'w-full'
      );
    });

    it('should apply dark mode styles', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      const modal = container.querySelector('.dark\\:bg-gray-800');
      expect(modal).toBeInTheDocument();
    });

    it('should make modal scrollable', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      const scrollableContent = container.querySelector('.overflow-y-auto');
      expect(scrollableContent).toBeInTheDocument();
    });

    it('should apply max height to modal', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      const modal = container.querySelector('.max-h-\\[80vh\\]');
      expect(modal).toBeInTheDocument();
    });
  });

  describe('Accessibility', () => {
    it('should have semantic HTML structure', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      const headings = container.querySelectorAll('h2');
      expect(headings.length).toBeGreaterThan(0);
    });

    it('should have accessible buttons', () => {
      render(<WidgetConfigModal {...defaultProps} />);

      const buttons = screen.getAllByRole('button');
      expect(buttons.length).toBeGreaterThan(0);
    });

    it('should have clear button text', () => {
      render(<WidgetConfigModal {...defaultProps} />);

      expect(screen.getByText('Done')).toBeInTheDocument();
      expect(screen.getByText('Reset to Default')).toBeInTheDocument();
    });

    it('should have descriptive widget names', () => {
      render(<WidgetConfigModal {...defaultProps} />);

      expect(screen.getByText('Total Appointments')).toBeInTheDocument();
      expect(screen.getByText('Recent Activity')).toBeInTheDocument();
    });
  });

  describe('Widget Descriptions', () => {
    it('should show description for each widget', () => {
      render(<WidgetConfigModal {...defaultProps} />);

      // Check a few widget descriptions
      expect(screen.getByText('Shows appointment count with weekly and monthly growth')).toBeInTheDocument();
      expect(screen.getByText('Timeline of recent business events')).toBeInTheDocument();
      expect(screen.getByText('Shows how booked your resources are this week')).toBeInTheDocument();
    });

    it('should display descriptions in smaller text', () => {
      const { container } = render(<WidgetConfigModal {...defaultProps} />);

      const descriptions = container.querySelectorAll('.text-xs');
      expect(descriptions.length).toBeGreaterThan(0);
    });
  });

  describe('Edge Cases', () => {
    it('should handle empty activeWidgets array', () => {
      render(<WidgetConfigModal {...defaultProps} activeWidgets={[]} />);

      // Should still render all widgets, just none selected
      expect(screen.getByText('Total Appointments')).toBeInTheDocument();

      // No checkmarks should be visible
      const { container } = render(<WidgetConfigModal {...defaultProps} activeWidgets={[]} />);
      const activeWidgets = container.querySelectorAll('.border-brand-500');
      expect(activeWidgets.length).toBe(0);
    });

    it('should handle all widgets active', () => {
      const allWidgets = [
        'appointments-metric',
        'customers-metric',
        'services-metric',
        'resources-metric',
        'revenue-chart',
        'appointments-chart',
        'open-tickets',
        'recent-activity',
        'capacity-utilization',
        'no-show-rate',
        'customer-breakdown',
      ];

      const { container } = render(
        <WidgetConfigModal {...defaultProps} activeWidgets={allWidgets} />
      );

      // All widgets should have active styling
      const activeWidgets = container.querySelectorAll('.border-brand-500');
      expect(activeWidgets.length).toBe(11);
    });

    it('should handle rapid widget toggling', async () => {
      const user = userEvent.setup();
      render(<WidgetConfigModal {...defaultProps} />);

      const widget = screen.getByText('Services').closest('button');

      if (widget) {
        await user.click(widget);
        await user.click(widget);
        await user.click(widget);

        expect(mockOnToggleWidget).toHaveBeenCalledTimes(3);
      }
    });
  });

  describe('Internationalization', () => {
    it('should use translations for modal title', () => {
      render(<WidgetConfigModal {...defaultProps} />);
      expect(screen.getByText('Configure Widgets')).toBeInTheDocument();
    });

    it('should use translations for widget titles', () => {
      render(<WidgetConfigModal {...defaultProps} />);
      expect(screen.getByText('Total Appointments')).toBeInTheDocument();
      expect(screen.getByText('Recent Activity')).toBeInTheDocument();
    });

    it('should use translations for widget descriptions', () => {
      render(<WidgetConfigModal {...defaultProps} />);
      expect(screen.getByText('Timeline of recent business events')).toBeInTheDocument();
    });

    it('should use translations for buttons', () => {
      render(<WidgetConfigModal {...defaultProps} />);
      expect(screen.getByText('Done')).toBeInTheDocument();
      expect(screen.getByText('Reset to Default')).toBeInTheDocument();
    });
  });

  describe('Integration', () => {
    it('should render correctly with all props', () => {
      const handleClose = vi.fn();
      const handleToggle = vi.fn();
      const handleReset = vi.fn();

      render(
        <WidgetConfigModal
          isOpen={true}
          onClose={handleClose}
          activeWidgets={['appointments-metric', 'revenue-chart']}
          onToggleWidget={handleToggle}
          onResetLayout={handleReset}
        />
      );

      expect(screen.getByText('Configure Widgets')).toBeInTheDocument();
      expect(screen.getByText('Total Appointments')).toBeInTheDocument();
      expect(screen.getByText('Done')).toBeInTheDocument();
    });

    it('should support complete user workflow', async () => {
      const user = userEvent.setup();
      const handleClose = vi.fn();
      const handleToggle = vi.fn();
      const handleReset = vi.fn();

      render(
        <WidgetConfigModal
          isOpen={true}
          onClose={handleClose}
          activeWidgets={['appointments-metric']}
          onToggleWidget={handleToggle}
          onResetLayout={handleReset}
        />
      );

      // User toggles a widget
      const widget = screen.getByText('Revenue').closest('button');
      if (widget) await user.click(widget);
      expect(handleToggle).toHaveBeenCalledWith('revenue-chart');

      // User resets layout
      const resetButton = screen.getByText('Reset to Default');
      await user.click(resetButton);
      expect(handleReset).toHaveBeenCalledTimes(1);

      // User closes modal
      const doneButton = screen.getByText('Done');
      await user.click(doneButton);
      expect(handleClose).toHaveBeenCalledTimes(1);
    });
  });
});
