import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/analytics/models/device_energy_data_model.dart';
import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart';
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_per_device_param.dart';
import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_service.dart';
import 'package:syncrow_web/services/api/api_exception.dart';
import 'package:syncrow_web/services/api/http_service.dart';

class RemoteEnergyConsumptionPerDeviceService
    implements EnergyConsumptionPerDeviceService {
  const RemoteEnergyConsumptionPerDeviceService(this._httpService);

  final HTTPService _httpService;

  static const _defaultErrorMessage = 'Failed to load energy consumption per device';

  @override
  Future<List<DeviceEnergyDataModel>> load(
    GetEnergyConsumptionPerDeviceParam param,
  ) async {
    try {
      final response = await _httpService.get(
        path: '/power-clamp/historical',
        showServerMessage: true,
        queryParameters: param.toJson(),
        expectedResponseModel: _EnergyConsumptionPerDeviceMapper.map,
      );
      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) {
      final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': ');
      throw APIException(formattedErrorMessage);
    }
  }
}

abstract final class _EnergyConsumptionPerDeviceMapper {
  const _EnergyConsumptionPerDeviceMapper._();
  static List<DeviceEnergyDataModel> map(dynamic data) {
    final json = data as Map<String, dynamic>? ?? {};
    final mappedData = json['data'] as List<dynamic>? ?? [];
    return mappedData.map((e) {
      final deviceData = e as Map<String, dynamic>;
      final energyData = deviceData['data'] as List<dynamic>;

      return DeviceEnergyDataModel(
        deviceId: deviceData['deviceUuid'] as String,
        deviceName: deviceData['deviceName'] as String,
        color: Color((DateTime.now().microsecondsSinceEpoch +
                deviceData['deviceUuid'].hashCode) |
            0xFF000000),
        energy: energyData.map((data) {
          final energyJson = data as Map<String, dynamic>;
          return EnergyDataModel(
            date: DateTime.parse(energyJson['date'] as String),
            value: double.parse(energyJson['total_energy_consumed_kw'] as String),
          );
        }).toList(),
      );
    }).toList();
  }
}
