import 'package:dio/dio.dart';
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart';
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
import 'package:syncrow_web/services/api/api_exception.dart';
import 'package:syncrow_web/services/api/http_service.dart';

class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService {
  const RemoteOccupancyAnalyticsDevicesService(this._httpService);

  final HTTPService _httpService;

  static const _defaultErrorMessage = 'Failed to load analytics devices';

  @override
  Future<List<AnalyticsDevice>> getDevices(GetAnalyticsDevicesParam param) async {
    try {
      final requests = await Future.wait<List<AnalyticsDevice>>(
        param.deviceTypes.map((e) {
          final mappedParam = GetAnalyticsDevicesParam(
            requestType: AnalyticsDeviceRequestType.occupancy,
            spaceUuid: param.spaceUuid,
            deviceTypes: [e],
            communityUuid: param.communityUuid,
          );
          return _makeRequest(mappedParam);
        }).toList(),
      );

      final result = requests.map((e) => e.first).toList();
      return result;
    } on DioException catch (e) {
      final message = e.response?.data as Map<String, dynamic>?;
      final error = message?['error'] as Map<String, dynamic>?;
      final errorMessage = error?['error'] as String? ?? '';
      final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': ');
      throw APIException(formattedErrorMessage);
    } catch (e) {
      final formattedErrorMessage = [_defaultErrorMessage, e.toString()].join(': ');
      throw APIException(formattedErrorMessage);
    }
  }

  Future<List<AnalyticsDevice>> _makeRequest(GetAnalyticsDevicesParam param) async {
    try {
      final projectUuid = await ProjectManager.getProjectUUID();

      final response = await _httpService.get(
        path:
            '/projects/$projectUuid/communities/${param.communityUuid}/spaces/${param.spaceUuid}/devices',
        queryParameters: {
          'communityUuid': param.communityUuid,
          'spaceUuid': param.spaceUuid,
          'productType': param.deviceTypes.first,
        },
        expectedResponseModel: (response) {
          final json = response as Map<String, dynamic>;
          final dailyData = json['data'] as List<dynamic>? ?? <dynamic>[];

          final result = dailyData.map(
            (json) => AnalyticsDevice.fromJson(json as Map<String, dynamic>),
          );
          return result.toList();
        },
      );
      return response;
    } on DioException catch (e) {
      final message = e.response?.data as Map<String, dynamic>?;
      final error = message?['error'] as Map<String, dynamic>?;
      final errorMessage = error?['error'] as String? ?? '';
      final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': ');
      throw APIException(formattedErrorMessage);
    } catch (e) {
      throw APIException('$_defaultErrorMessage: $e');
    }
  }
}
