import 'camera_device.dart';
import 'camera_device_type.dart';
import 'camera_position.dart';
import 'vital_sign_camera.dart';

///  Queries the best available [CameraDevice] with [CameraDeviceType].
Future<Map<CameraPosition, CameraDevice?>> queryCameraDevices(
    CameraDeviceType type) async {
  final devices = await availableCameraDevices();

  final result = devices.where((element) {
    if (element.devices.length == 1) {
      return element.devices[0] == type;
    }

    final hasWide = element.devices.contains(CameraDeviceType.wideAngleCamera);
    final hasUltra =
        element.devices.contains(CameraDeviceType.ultraWideAngleCamera);
    final hasTele = element.devices.contains(CameraDeviceType.telephotoCamera);

    if (hasTele &&
        hasWide &&
        hasUltra &&
        type == CameraDeviceType.tripleCamera) {
      return true;
    }
    if (hasWide && hasUltra && type == CameraDeviceType.dualWideCamera) {
      return true;
    }
    if (hasWide && hasTele && type == CameraDeviceType.dualCamera) {
      return true;
    }

    return false;
  });

  CameraDevice? deviceWithPosition(CameraPosition position) {
    final list = result.where((element) => element.position == position);
    return list.isNotEmpty ? list.first : null;
  }

  return <CameraPosition, CameraDevice?>{
    CameraPosition.back: deviceWithPosition(CameraPosition.back),
    CameraPosition.front: deviceWithPosition(CameraPosition.front),
    CameraPosition.external: deviceWithPosition(CameraPosition.external),
    CameraPosition.unspecified: deviceWithPosition(CameraPosition.unspecified)
  };
}

/// Query the camera device with [CameraPosition].
Future<CameraDevice?> queryCameraDevice(CameraPosition position) async {
  var device =
      (await queryCameraDevices(CameraDeviceType.wideAngleCamera))[position];
  if (device == null) {
    for (var type in CameraDeviceType.values) {
      device = (await queryCameraDevices(type))[position];
      if (device != null) {
        return device;
      }
    }
  }
  return device;
}
