import 'dart:developer';

import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
import 'package:syncrow_web/services/api/http_service.dart';
import 'package:syncrow_web/utils/constants/api_const.dart';

abstract interface class ControlDeviceService {
  Future<bool> controlDevice({
    required String deviceUuid,
    required Status status,
  });
}

final class RemoteControlDeviceService implements ControlDeviceService {
  @override
  Future<bool> controlDevice({
    required String deviceUuid,
    required Status status,
  }) async {
    try {
      final response = await HTTPService().post(
        path: ApiEndpoints.deviceControl.replaceAll('{uuid}', deviceUuid),
        body: status.toMap(),
        showServerMessage: true,
        expectedResponseModel: (json) {
          return (json['success'] as bool?) ?? false;
        },
      );
      return response;
    } catch (e) {
      log('Error fetching  $e', name: 'ControlDeviceService');
      return false;
    }
  }
}

final class DebouncedControlDeviceService implements ControlDeviceService {
  final ControlDeviceService decoratee;
  final Duration debounceDuration;

  DebouncedControlDeviceService({
    required this.decoratee,
    this.debounceDuration = const Duration(milliseconds: 1500),
  });

  final _pendingRequests = <(String deviceUuid, Status status)>[];
  var _isProcessing = false;

  @override
  Future<bool> controlDevice({
    required String deviceUuid,
    required Status status,
  }) async {
    _pendingRequests.add((deviceUuid, status));

    if (_isProcessing) return false;

    _isProcessing = true;

    await Future.delayed(debounceDuration);

    final groupedRequests = <String, (String deviceUuid, Status status)>{};
    for (final request in _pendingRequests) {
      final (_, requestStatus) = request;
      groupedRequests[requestStatus.code] = request;
    }
    _pendingRequests.clear();

    try {
      var allSuccessful = true;
      for (final request in groupedRequests.values) {
        final (lastRequestDeviceUuid, lastRequestStatus) = request;
        final success = await decoratee.controlDevice(
          deviceUuid: lastRequestDeviceUuid,
          status: lastRequestStatus,
        );
        if (!success) allSuccessful = false;
      }
      return allSuccessful;
    } finally {
      _isProcessing = false;
    }
  }
}
