import 'dart:convert';
import 'dart:io';

import 'package:http/http.dart' as http;
import 'package:nearle/views/helpers/constants/apiconstants.dart';

class DeliveryProvider {
  final http.Client _client;

  DeliveryProvider({http.Client? client}) : _client = client ?? http.Client();

  Future<http.Response> _getWithRetry(Uri uri, {int maxAttempts = 3}) async {
    int attempt = 0;
    while (true) {
      attempt++;
      try {
        return await _client.get(uri);
      } on SocketException catch (_) {
        if (attempt >= maxAttempts) rethrow;
      } on http.ClientException catch (_) {
        if (attempt >= maxAttempts) rethrow;
      }
      // Exponential backoff: 300ms, 600ms
      final delayMs = 300 * attempt;
      await Future.delayed(Duration(milliseconds: delayMs));
    }
  }

  Future<List<dynamic>> getDeliveryQueues({
    required bool live,
    required int userid,
    String? orderstatus,
  }) async {
    final base = live ? ApiConstants.deliveryQueueLive : ApiConstants.deliveryQueueDev;

    // Get current date in YYYY-MM-DD format
    final now = DateTime.now();
    final mm = now.month.toString().padLeft(2, '0');
    final dd = now.day.toString().padLeft(2, '0');
    final yyyy = now.year.toString();
    final today = "$yyyy-$mm-$dd";

    final qp = <String, String>{
      'userid': userid.toString(),
      'fromdate': today,
      'todate': today,
      't': DateTime.now().millisecondsSinceEpoch.toString(),
    };
    if (orderstatus != null && orderstatus.isNotEmpty) {
      qp['orderstatus'] = orderstatus;
    }
    final uri = Uri.parse(base).replace(queryParameters: qp);

    final res = await _getWithRetry(uri);

    if (res.statusCode >= 200 && res.statusCode < 300) {
      // Log URL and raw status
      // ignore: avoid_print
      print('[DELIVERIES][GET] URL: ${uri.toString()}');
      final decoded = json.decode(res.body);

      final data = decoded is Map<String, dynamic>
          ? (decoded['details'] ?? decoded['data'] ?? decoded)
          : decoded;

      if (data is List) {
        try {
          // Pretty log the list if deliveries are found
          if (data.isNotEmpty) {
            // ignore: avoid_print
            // print('[DELIVERIES][GET] Data: ${json.encode(data)}'); // Heavy log, disabled for performance
          } else {
            // ignore: avoid_print
            // print('[DELIVERIES][GET] Data: []');
          }
        } catch (_) {}
        return data;
      }
      if (data is Map && data['items'] is List) return data['items'] as List;

      return [];
    }

    throw Exception('Failed (${res.statusCode})');
  }

  Future<List<dynamic>> getDeliveryQueuesPicked({
    required bool live,
    required int userid,
  }) async {
    // Use v3 getdeliveries with fromdate/todate as today's date (dynamic)
    final base = live
        ? ApiConstants.currentDeliveryV3Live
        : ApiConstants.currentDeliveryV3Dev;
    // Get current date in YYYY-MM-DD format (dynamically updated each day)
    final now = DateTime.now();
    final mm = now.month.toString().padLeft(2, '0');
    final dd = now.day.toString().padLeft(2, '0');
    final yyyy = now.year.toString();
    final today = "$yyyy-$mm-$dd";

    final qp = <String, String>{
      'userid': userid.toString(),
      'fromdate': today,
      'todate': today,
      't': DateTime.now().millisecondsSinceEpoch.toString(),
    };
    final uri = Uri.parse(base).replace(queryParameters: qp);

    final res = await _getWithRetry(uri);

    if (res.statusCode >= 200 && res.statusCode < 300) {
      // ignore: avoid_print
      print('[DELIVERIES][GET_PICKED] URL: ${uri.toString()}');
      final decoded = json.decode(res.body);

      // The API returns {"code":200,"details":[...],"message":"Success","status":true}
      final data = decoded is Map<String, dynamic>
          ? (decoded['details'] ?? decoded['data'] ?? decoded)
          : decoded;

      if (data is List) {
        try {
          if (data.isNotEmpty) {
            // ignore: avoid_print
            // print('[DELIVERIES][GET_PICKED] Data: ${json.encode(data)}'); // Heavy log, disabled
          } else {
            // ignore: avoid_print
            // print('[DELIVERIES][GET_PICKED] Data: []');
          }
        } catch (_) {}
        return data;
      }
      if (data is Map && data['items'] is List) return data['items'] as List;

      return [];
    }

    throw Exception('Failed (${res.statusCode})');
  }
}
