import 'dart:convert';
import 'dart:core';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_entry.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart';
import 'package:syncrow_web/pages/visitor_password/model/device_model.dart';
import 'package:syncrow_web/services/api/http_service.dart';
import 'package:syncrow_web/utils/constants/api_const.dart';

class DevicesManagementApi {
  Future<List<AllDevicesModel>> fetchDevices(
      String communityId, String spaceId, String projectId) async {
    try {
      final response = await HTTPService().get(
        path: communityId.isNotEmpty && spaceId.isNotEmpty
            ? ApiEndpoints.getSpaceDevices
                .replaceAll('{spaceUuid}', spaceId)
                .replaceAll('{communityUuid}', communityId)
                .replaceAll('{projectId}', projectId)
            : ApiEndpoints.getAllDevices.replaceAll('{projectId}', projectId),
        showServerMessage: true,
        expectedResponseModel: (json) {
          List<dynamic> jsonData = json['data'];
          List<AllDevicesModel> devicesList = jsonData.map((jsonItem) {
            return AllDevicesModel.fromJson(jsonItem);
          }).toList();
          return devicesList;
        },
      );
      return response;
    } catch (e) {
      debugPrint('Error fetching device $e');
      return [];
    }
  }

  Future<DeviceStatus> getDeviceStatus(String uuid) async {
    try {
      final response = await HTTPService().get(
        path: ApiEndpoints.getDeviceStatus.replaceAll('{uuid}', uuid),
        showServerMessage: true,
        expectedResponseModel: (json) {
          return DeviceStatus.fromJson(json['data']);
        },
      );
      return response;
    } catch (e) {
      debugPrint('Error fetching  $e');
      return DeviceStatus(
        productUuid: '',
        productType: '',
        status: [],
      );
    }
  }

  Future getPowerClampInfo(String deviceId) async {
    try {
      final response = await HTTPService().get(
        path: ApiEndpoints.getDeviceStatus.replaceAll('{uuid}', deviceId),
        showServerMessage: true,
        expectedResponseModel: (json) {
          return json;
        },
      );
      return response;
    } catch (e) {
      debugPrint('Error fetching  $e');
      return {};
    }
  }

  //deviceControl
  Future<bool> deviceControl(String uuid, Status status) async {
    try {
      final response = await HTTPService().post(
        path: ApiEndpoints.deviceControl.replaceAll('{uuid}', uuid),
        body: status.toMap(),
        showServerMessage: true,
        expectedResponseModel: (json) {
          return json['success'] ?? false;
        },
      );
      return response;
    } catch (e) {
      debugPrint('Error fetching  $e');
      return false;
    }
  }

  Future<bool> deviceBatchControl(
      List<String> uuids, String code, dynamic value) async {
    try {
      final body = {
        'devicesUuid': uuids,
        'code': code,
        'value': value,
        'operationType': 'COMMAND',
      };

      final response = await HTTPService().post(
        path: ApiEndpoints.deviceBatchControl,
        body: body,
        showServerMessage: true,
        expectedResponseModel: (json) {
          return json['success'] ?? false;
        },
      );

      return response;
    } catch (e) {
      debugPrint('Error fetching $e');
      return false;
    }
  }

  static Future<List<DeviceModel>> getDevicesByGatewayId(
      String gatewayId) async {
    final response = await HTTPService().get(
      path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
      showServerMessage: false,
      expectedResponseModel: (json) {
        List<DeviceModel> devices = [];
        if (json == null || json.isEmpty || json == []) {
          return devices;
        }
        for (var device in json['data']['devices']) {
          devices.add(DeviceModel.fromJson(device));
        }
        return devices;
      },
    );
    return response;
  }

  static Future<bool> openDoorLock(String deviceId) async {
    final response = await HTTPService().post(
      path: ApiEndpoints.openDoorLock.replaceAll('{doorLockUuid}', deviceId),
      showServerMessage: false,
      expectedResponseModel: (json) {
        return json['success'] ?? false;
      },
    );
    return response;
  }

  static Future<DeviceReport> getDeviceReports(
    String uuid,
    String code,
  ) async {
    final response = await HTTPService().get(
      path: ApiEndpoints.getDeviceLogs
          .replaceAll('{uuid}', uuid)
          .replaceAll('{code}', code),
      showServerMessage: false,
      expectedResponseModel: (json) {
        return DeviceReport.fromJson(json['data']);
      },
    );
    return response;
  }

  static Future<DeviceReport> getDeviceReportsByDate(String uuid, String code,
      [String? from, String? to]) async {
    final response = await HTTPService().get(
      path: ApiEndpoints.getDeviceLogsByDate
          .replaceAll('{uuid}', uuid)
          .replaceAll('{code}', code)
          .replaceAll('{startTime}', from ?? '')
          .replaceAll('{endTime}', to ?? ''),
      showServerMessage: false,
      expectedResponseModel: (json) {
        return DeviceReport.fromJson(json['data']);
      },
    );
    return response;
  }

  Future<DeviceStatus> getBatchStatus(List<String> uuids) async {
    try {
      final queryParameters = {
        'devicesUuid': uuids.join(','),
      };
      final response = await HTTPService().get(
        path: ApiEndpoints.getBatchStatus,
        queryParameters: queryParameters,
        showServerMessage: true,
        expectedResponseModel: (json) {
          return DeviceStatus.fromJson(json['data']['status']);
        },
      );
      return response;
    } catch (e) {
      debugPrint('Error fetching  $e');
      return DeviceStatus(
        productUuid: '',
        productType: '',
        status: [],
      );
    }
  }

  getPowerStatus(List<String> uuids) async {
    try {
      final queryParameters = {
        'devicesUuid': uuids.join(','),
      };
      final response = await HTTPService().get(
        path: ApiEndpoints.getBatchStatus,
        queryParameters: queryParameters,
        showServerMessage: true,
        expectedResponseModel: (json) {
          return json;
        },
      );
      return response;
    } catch (e) {
      debugPrint('Error fetching  $e');
      return DeviceStatus(
        productUuid: '',
        productType: '',
        status: [],
      );
    }
  }

  Future<bool> addScheduleRecord(
      ScheduleEntry sendSchedule, String uuid) async {
    try {
      final response = await HTTPService().post(
        path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
        body: sendSchedule.toMap(),
        showServerMessage: true,
        expectedResponseModel: (json) {
          return json['success'] ?? false;
        },
      );
      return response;
    } catch (e) {
      debugPrint('Error fetching  $e');
      return false;
    }
  }

  Future<List<ScheduleModel>> getDeviceSchedules(
      String uuid, String category) async {
    try {
      final response = await HTTPService().get(
        path: ApiEndpoints.getScheduleByDeviceId
            .replaceAll('{deviceUuid}', uuid)
            .replaceAll('{category}', category),
        showServerMessage: true,
        expectedResponseModel: (json) {
          List<ScheduleModel> schedules = [];
          for (var schedule in json) {
            schedules.add(ScheduleModel.fromMap(schedule));
          }
          return schedules;
        },
      );
      return response;
    } catch (e) {
      debugPrint('Error fetching  $e');
      return [];
    }
  }

  Future<bool> updateScheduleRecord(
      {required bool enable,
      required String uuid,
      required String scheduleId}) async {
    try {
      final response = await HTTPService().put(
        path: ApiEndpoints.updateScheduleByDeviceId
            .replaceAll('{deviceUuid}', uuid)
            .replaceAll('{scheduleUuid}', scheduleId),
        body: {
          'scheduleId': scheduleId,
          'enable': enable,
        },
        expectedResponseModel: (json) {
          return json['success'] ?? false;
        },
      );
      return response;
    } catch (e) {
      debugPrint('Error fetching  $e');
      return false;
    }
  }

  Future<bool> editScheduleRecord(
      String uuid, ScheduleEntry newSchedule) async {
    try {
      final response = await HTTPService().put(
        path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
        body: newSchedule.toMap(),
        expectedResponseModel: (json) {
          return json['success'] ?? false;
        },
      );
      return response;
    } catch (e) {
      debugPrint('Error fetching  $e');
      return false;
    }
  }

  Future<bool> deleteScheduleRecord(String uuid, String scheduleId) async {
    try {
      final response = await HTTPService().delete(
        path: ApiEndpoints.deleteScheduleByDeviceId
            .replaceAll('{deviceUuid}', uuid)
            .replaceAll('{scheduleUuid}', scheduleId),
        showServerMessage: true,
        expectedResponseModel: (json) {
          return json['success'] ?? false;
        },
      );
      return response;
    } catch (e) {
      debugPrint('Error fetching  $e');
      return false;
    }
  }

  Future<bool> factoryReset(FactoryResetModel factoryReset, String uuid) async {
    try {
      final response = await HTTPService().post(
        path: ApiEndpoints.factoryReset,
        body: factoryReset.toMap(),
        showServerMessage: true,
        expectedResponseModel: (json) {
          return json['success'] ?? false;
        },
      );

      return response;
    } catch (e) {
      debugPrint('Error fetching  $e');
      return false;
    }
  }

  static Future<Map<String, dynamic>> putDeviceName(
      {required String deviceId, required String deviceName}) async {
    try {
      final response = await HTTPService().put(
        path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId),
        body: {"deviceName": deviceName},
        expectedResponseModel: (json) {
          return json['data'];
        },
      );
      return response;
    } catch (e) {
      rethrow;
    }
  }

  static Future getDeviceInfo(String deviceId) async {
    final response = await HTTPService().get(
        path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId),
        showServerMessage: false,
        expectedResponseModel: (json) {
          return json['data'] as Map<String, dynamic>;
        });
    return response;
  }

  static Future resetDevice({
    String? devicesUuid,
  }) async {
    final response = await HTTPService().post(
      path: ApiEndpoints.resetDevice.replaceAll('{deviceUuid}', devicesUuid!),
      showServerMessage: false,
      body: {
        "devicesUuid": [devicesUuid]
      },
      expectedResponseModel: (json) {
        return json;
      },
    );
    return response;
  }

  Future<bool> postSchedule({
    required String category,
    required String deviceId,
    required String time,
    required String code,
    required dynamic value,
    required List<String> days,
  }) async {
    final response = await HTTPService().post(
      path: ApiEndpoints.saveSchedule.replaceAll('{deviceUuid}', deviceId),
      showServerMessage: false,
      body: jsonEncode(
        {
          'category': category,
          'time': time,
          'function': {
            'code': code,
            'value': value,
          },
          'days': days
        },
      ),
      expectedResponseModel: (json) {
        return json['success'] ?? false;
      },
    );
    return response;
  }

}
