import 'package:dio/dio.dart';
import '../core/api_config.dart';

/// Layanan Klien untuk mengirimkan instruksi kontrol hardware (ESP32) ke API Backend.
/// Menangani pemanggilan REST API untuk: pengaturan mode (Auto/Manual), threshold, penyiraman manual, dan penjadwalan.
class ApiControlService {
  final Dio _dio;
  final String deviceId;

  ApiControlService(this.deviceId, [Dio? dio]) : _dio = dio ?? Dio();

  // ── Mode Operasi ─────────────────────────────────────────────
  /// Mengambil mode operasi perangkat saat ini dari backend.
  Future<String> getMode() async {
    try {
      final res = await _dio.get('${ApiConfig.baseUrl}/mode/$deviceId');
      if (res.statusCode == 200 && res.data != null) {
        return res.data['current_mode'] ?? 'auto';
      }
      return 'auto';
    } catch (e) {
      return 'auto';
    }
  }

  /// Mengubah mode operasi perangkat (Otomatis/Manual) di server.
  Future<void> setMode(String mode) async {
    try {
      await _dio.post(
        '${ApiConfig.baseUrl}/mode/$deviceId',
        data: {'mode': mode},
      );
    } catch (e) {
      throw Exception('Gagal mengubah mode: $e');
    }
  }

  /// Mengambil nilai batas threshold sensor suhu dan kelembapan saat ini.
  Future<Map<String, dynamic>> getThreshold() async {
    try {
      final res = await _dio.get('${ApiConfig.baseUrl}/threshold/$deviceId');
      if (res.statusCode == 200 && res.data != null) {
        return res.data;
      }
      throw Exception('Gagal memuat threshold');
    } catch (e) {
      throw Exception('Error: $e');
    }
  }

  /// Memperbarui nilai batas threshold suhu ([tempMin], [tempMax]) dan kelembapan ([humMax]) di server.
  Future<void> updateThreshold(double tempMin, double tempMax, double humMax) async {
    try {
      await _dio.post(
        '${ApiConfig.baseUrl}/threshold/$deviceId',
        data: {
          'temp_min': tempMin,
          'temp_max': tempMax,
          'hum_max': humMax,
        },
      );
    } catch (e) {
      throw Exception('Gagal update threshold: $e');
    }
  }

  // ── Manual Control (Pompa) ───────────────────────────────────
  /// Mengirimkan instruksi menyalakan pompa secara instan selama [durationSeconds] detik.
  Future<void> siramManual(int durationSeconds) async {
    try {
      await _dio.post(
        '${ApiConfig.baseUrl}/schedule/$deviceId/now',
        data: {'duration_s': durationSeconds},
      );
    } catch (e) {
      throw Exception('Gagal menyalakan pompa: $e');
    }
  }

  /// Menghentikan aktivitas pompa secara instan (mematikan pompa).
  Future<void> stopPump() async {
    try {
      await _dio.post('${ApiConfig.baseUrl}/schedule/$deviceId/stop');
    } catch (e) {
      throw Exception('Gagal mematikan pompa: $e');
    }
  }

  // ── Schedules (Jadwal) ───────────────────────────────────────
  /// Mengambil daftar semua jadwal penyiraman otomatis yang terdaftar untuk perangkat ini.
  Future<List<dynamic>> getSchedules() async {
    try {
      final res = await _dio.get('${ApiConfig.baseUrl}/schedule/$deviceId');
      if (res.statusCode == 200 && res.data != null) {
        return res.data as List<dynamic>;
      }
      return [];
    } catch (e) {
      throw Exception('Gagal memuat jadwal: $e');
    }
  }

  /// Menambahkan jadwal penyiraman baru ke backend.
  /// [cron] format string cron UTC, [durationSeconds] durasi siram, [label] penanda nama jadwal.
  Future<Map<String, dynamic>> addSchedule(String cron, int durationSeconds, String label) async {
    try {
      final res = await _dio.post(
        '${ApiConfig.baseUrl}/schedule/$deviceId',
        data: {
          'cron': cron,
          'duration_s': durationSeconds,
          'label': label,
        },
      );
      if (res.statusCode == 200 || res.statusCode == 201) {
        return res.data;
      }
      throw Exception('Gagal menambah jadwal');
    } catch (e) {
      throw Exception('Error tambah jadwal: $e');
    }
  }

  /// Menghapus jadwal tertentu berdasarkan ID.
  Future<void> deleteSchedule(String id) async {
    try {
      await _dio.delete('${ApiConfig.baseUrl}/schedule/$id');
    } catch (e) {
      throw Exception('Gagal menghapus jadwal: $e');
    }
  }

  /// Mengaktifkan atau menonaktifkan saklar jadwal tertentu (toggle status is_active).
  Future<void> toggleSchedule(String id) async {
    try {
      await _dio.patch('${ApiConfig.baseUrl}/schedule/$id/toggle');
    } catch (e) {
      throw Exception('Gagal toggle jadwal: $e');
    }
  }
}
