/**
 * Add Sensor Screen - Signal Strength UI Tests
 * Tests the WiFiSignalIndicator integration and signal strength display
 */

import React from 'react';
import { render } from '@testing-library/react-native';
import { useLocalSearchParams } from 'expo-router';
import AddSensorScreen from '../[id]/add-sensor';
import { useBLE } from '@/contexts/BLEContext';
import { useBeneficiary } from '@/contexts/BeneficiaryContext';

// Mock dependencies
jest.mock('expo-router', () => ({
  useLocalSearchParams: jest.fn(),
  router: {
    push: jest.fn(),
    back: jest.fn(),
  },
  useFocusEffect: jest.fn((callback) => callback()),
}));

jest.mock('@/contexts/BLEContext', () => ({
  useBLE: jest.fn(),
}));

jest.mock('@/contexts/BeneficiaryContext', () => ({
  useBeneficiary: jest.fn(),
}));

jest.mock('expo-device', () => ({
  isDevice: true,
}));

jest.mock('@/services/analytics', () => ({
  analytics: {
    trackSensorScanStart: jest.fn(),
    trackSensorScanComplete: jest.fn(),
    trackSensorSetupStart: jest.fn(),
  },
}));

describe('AddSensorScreen - Signal Strength UI', () => {
  const mockStopScan = jest.fn();
  const mockScanDevices = jest.fn();
  const mockClearError = jest.fn();

  const createMockDevice = (rssi: number, id: string = 'device-1') => ({
    id,
    name: `WP_497_${id}`,
    mac: id.toUpperCase(),
    rssi,
    wellId: 497,
  });

  beforeEach(() => {
    jest.clearAllMocks();

    (useLocalSearchParams as jest.Mock).mockReturnValue({ id: '1' });

    (useBeneficiary as jest.Mock).mockReturnValue({
      currentBeneficiary: {
        id: 1,
        name: 'Maria',
      },
    });
  });

  const setupMockBLE = (devices: any[] = [], isScanning = false) => {
    (useBLE as jest.Mock).mockReturnValue({
      foundDevices: devices,
      isScanning,
      connectedDevices: new Set(),
      isBLEAvailable: true,
      error: null,
      permissionError: false,
      scanDevices: mockScanDevices,
      stopScan: mockStopScan,
      connectDevice: jest.fn(),
      disconnectDevice: jest.fn(),
      getWiFiList: jest.fn(),
      setWiFi: jest.fn(),
      getCurrentWiFi: jest.fn(),
      rebootDevice: jest.fn(),
      cleanupBLE: jest.fn(),
      clearError: mockClearError,
    });
  };

  describe('Signal strength labels', () => {
    it('displays "Excellent" for strong signals (>= -50 dBm)', () => {
      const devices = [createMockDevice(-45)];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('Excellent')).toBeTruthy();
      expect(getByText('(-45 dBm)')).toBeTruthy();
    });

    it('displays "Good" for good signals (-51 to -60 dBm)', () => {
      const devices = [createMockDevice(-55)];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('Good')).toBeTruthy();
      expect(getByText('(-55 dBm)')).toBeTruthy();
    });

    it('displays "Fair" for fair signals (-61 to -70 dBm)', () => {
      const devices = [createMockDevice(-65)];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('Fair')).toBeTruthy();
      expect(getByText('(-65 dBm)')).toBeTruthy();
    });

    it('displays "Weak" for weak signals (< -70 dBm)', () => {
      const devices = [createMockDevice(-75)];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('Weak')).toBeTruthy();
      expect(getByText('(-75 dBm)')).toBeTruthy();
    });
  });

  describe('Multiple devices with different signal strengths', () => {
    it('displays correct labels for each device', () => {
      const devices = [
        createMockDevice(-45, 'dev1'),
        createMockDevice(-55, 'dev2'),
        createMockDevice(-65, 'dev3'),
        createMockDevice(-80, 'dev4'),
      ];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('Excellent')).toBeTruthy();
      expect(getByText('Good')).toBeTruthy();
      expect(getByText('Fair')).toBeTruthy();
      expect(getByText('Weak')).toBeTruthy();
    });

    it('displays dBm values for each device', () => {
      const devices = [
        createMockDevice(-50, 'dev1'),
        createMockDevice(-60, 'dev2'),
      ];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('(-50 dBm)')).toBeTruthy();
      expect(getByText('(-60 dBm)')).toBeTruthy();
    });
  });

  describe('Device count display', () => {
    it('shows correct device count in section header', () => {
      const devices = [
        createMockDevice(-50, 'dev1'),
        createMockDevice(-60, 'dev2'),
        createMockDevice(-70, 'dev3'),
      ];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('Found Sensors (3)')).toBeTruthy();
    });
  });

  describe('Device selection with signal info', () => {
    it('can select device with signal info displayed', () => {
      const devices = [createMockDevice(-55, 'dev1')];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      // Signal info should be visible
      expect(getByText('Good')).toBeTruthy();
      expect(getByText('(-55 dBm)')).toBeTruthy();
    });
  });

  describe('Boundary RSSI values', () => {
    it('handles exact -50 dBm boundary (Excellent)', () => {
      const devices = [createMockDevice(-50)];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('Excellent')).toBeTruthy();
    });

    it('handles exact -60 dBm boundary (Good)', () => {
      const devices = [createMockDevice(-60)];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('Good')).toBeTruthy();
    });

    it('handles exact -70 dBm boundary (Fair)', () => {
      const devices = [createMockDevice(-70)];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('Fair')).toBeTruthy();
    });

    it('handles -71 dBm (Weak)', () => {
      const devices = [createMockDevice(-71)];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('Weak')).toBeTruthy();
    });
  });

  describe('Extreme RSSI values', () => {
    it('handles very strong signal (-30 dBm)', () => {
      const devices = [createMockDevice(-30)];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('Excellent')).toBeTruthy();
      expect(getByText('(-30 dBm)')).toBeTruthy();
    });

    it('handles very weak signal (-100 dBm)', () => {
      const devices = [createMockDevice(-100)];
      setupMockBLE(devices);

      const { getByText } = render(<AddSensorScreen />);

      expect(getByText('Weak')).toBeTruthy();
      expect(getByText('(-100 dBm)')).toBeTruthy();
    });
  });

  describe('Empty state', () => {
    it('does not show signal UI when no devices found', () => {
      setupMockBLE([]);

      const { queryByText } = render(<AddSensorScreen />);

      expect(queryByText('Excellent')).toBeNull();
      expect(queryByText('Good')).toBeNull();
      expect(queryByText('Fair')).toBeNull();
      expect(queryByText('Weak')).toBeNull();
    });
  });

  describe('Scanning state', () => {
    it('does not show signal UI while scanning', () => {
      setupMockBLE([], true);

      const { getByText, queryByText } = render(<AddSensorScreen />);

      expect(getByText('Scanning for WP sensors...')).toBeTruthy();
      expect(queryByText('Excellent')).toBeNull();
    });
  });
});
