import 'package:comwell_key_app/key/repository/key_repository.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:seos_mobile_keys_plugin/app_usage_api.dart';
import 'package:seos_mobile_keys_plugin/seos_mobile_keys_plugin.dart';

import '../booking_details_test/booking_details_repository_test.dart';

class MockAndroidDeviceInfo extends Mock implements AndroidDeviceInfo {}

class MockDeviceInfoPlugin extends Mock implements DeviceInfoPlugin {}

void main() {
  late KeyRepository keyRepository;
  late SeosMobileKeysPlugin mockSeosMobileKeysPlugin;
  late AndroidDeviceInfo mockAndroidDeviceInfo;
  late DeviceInfoPlugin mockDeviceInfoPlugin;

  setUp(() {
    mockSeosMobileKeysPlugin = MockSeosMobileKeysPlugin();
    mockAndroidDeviceInfo = MockAndroidDeviceInfo();
    mockDeviceInfoPlugin = MockDeviceInfoPlugin();
    keyRepository = KeyRepository(mockSeosMobileKeysPlugin);
  });

  group('KeyRepository', () {
    test('checkDeviceInfo calls _checkAndStartScan on Android SDK >= 33', () async {
      when(() => mockDeviceInfoPlugin.androidInfo).thenAnswer((_) async => mockAndroidDeviceInfo);
      when(() => mockAndroidDeviceInfo.version.sdkInt).thenReturn(33);
      when(
        () => Permission.bluetoothScan.request(),
      ).thenAnswer((_) async => PermissionStatus.granted);
      when(
        () => Permission.bluetoothConnect.request(),
      ).thenAnswer((_) async => PermissionStatus.granted);
      when(
        () => Permission.bluetoothAdvertise.request(),
      ).thenAnswer((_) async => PermissionStatus.granted);
      when(
        () => Permission.notification.request(),
      ).thenAnswer((_) async => PermissionStatus.granted);

      await keyRepository.checkDeviceInfo();

      verify(
        () => mockSeosMobileKeysPlugin.startReaderScan(
          MobileKeysScanMode.optimizePerformance,
          [any()],
          [any()],
        ),
      ).called(1);
    });

    test('checkDeviceInfo calls _checkAndStartScan on Android SDK >= 31', () async {
      when(() => mockDeviceInfoPlugin.androidInfo).thenAnswer((_) async => mockAndroidDeviceInfo);
      when(() => mockAndroidDeviceInfo.version.sdkInt).thenReturn(31);
      when(
        () => Permission.bluetoothScan.request(),
      ).thenAnswer((_) async => PermissionStatus.granted);
      when(
        () => Permission.bluetoothConnect.request(),
      ).thenAnswer((_) async => PermissionStatus.granted);
      when(
        () => Permission.bluetoothAdvertise.request(),
      ).thenAnswer((_) async => PermissionStatus.granted);

      await keyRepository.checkDeviceInfo();

      verify(
        () => mockSeosMobileKeysPlugin.startReaderScan(
          MobileKeysScanMode.optimizePerformance,
          [any()],
          [any()],
        ),
      ).called(1);
    });

    test('checkDeviceInfo calls _checkAndStartScan on Android SDK < 31', () async {
      when(() => mockDeviceInfoPlugin.androidInfo).thenAnswer((_) async => mockAndroidDeviceInfo);
      when(() => mockAndroidDeviceInfo.version.sdkInt).thenReturn(30);
      when(() => Permission.location.request()).thenAnswer((_) async => PermissionStatus.granted);

      await keyRepository.checkDeviceInfo();

      verify(
        () => mockSeosMobileKeysPlugin.startReaderScan(
          MobileKeysScanMode.optimizePerformance,
          [any()],
          [any()],
        ),
      ).called(1);
    });

    test('stopScanning calls stopReaderScan', () async {
      await keyRepository.stopScanning();

      verify(() => mockSeosMobileKeysPlugin.stopReaderScan()).called(1);
    });

    test('openClosestReader calls openClosestReader', () async {
      await keyRepository.openClosestReader();

      verify(() => mockSeosMobileKeysPlugin.openClosestReader()).called(1);
    });

    test('_startScanning calls startReaderScan', () async {
      keyRepository.startScanning();

      verify(
        () => mockSeosMobileKeysPlugin.startReaderScan(
          MobileKeysScanMode.optimizePerformance,
          [any()],
          [any()],
        ),
      ).called(1);
    });
  });
}