import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart';
import 'package:http/io_client.dart';
import 'package:flutter/foundation.dart';

// Combined Riderlog providers:

/// Hardcoded known-good IPs for hosts where carrier DNS returns broken nodes.
/// Confirmed by Python test: 66.116.225.226 = 200 OK, 125.21.240.67 = 404.
const _knownGoodIPs = <String, String>{
  'queue.workolik.com': '66.116.225.226',
};

/// Creates an IOClient that:
/// 1. Bypasses SSL certificate errors
/// 2. Forces known-good IPs for hosts where carrier DNS returns broken CDN nodes
/// 3. Manually does TLS upgrade with correct SNI (hostname, not IP)
IOClient _buildSslBypassClient() {
  final httpClient = HttpClient()
    ..badCertificateCallback =
        (X509Certificate cert, String host, int port) => true;

  httpClient.connectionFactory =
      (Uri uri, String? proxyHost, int? proxyPort) async {
    final host = uri.host;
    final port = uri.port;

    // Use known-good IP if available, else resolve normally (prefer IPv4)
    InternetAddress? target;
    final knownIP = _knownGoodIPs[host];
    if (knownIP != null) {
      target = InternetAddress(knownIP);
      debugPrint('[SSL_CLIENT] Using known-good IP: $knownIP for $host');
    } else {
      try {
        final addresses = await InternetAddress.lookup(
          host,
          type: InternetAddressType.IPv4,
        );
        if (addresses.isNotEmpty) target = addresses.first;
      } catch (_) {}
    }

    if (uri.scheme == 'https') {
      final socketFuture =
          Socket.connect(target ?? InternetAddress(host), port)
              .then((plain) => SecureSocket.secure(
                    plain,
                    host: host, // SNI = original hostname for Nginx routing
                    onBadCertificate: (_) => true,
                    supportedProtocols: ['http/1.1'],
                  ))
              .then((s) => s as Socket);
      return ConnectionTask.fromSocket<Socket>(socketFuture, () {});
    }

    return Socket.startConnect(target ?? InternetAddress(host), port);
  };

  return IOClient(httpClient);
}


class CreateRiderLogProvider {
  Future<Map<String, dynamic>?> createRiderLog(
    String urldata,
    Map<String, dynamic> data,
  ) async {
    const maxAttempts = 3;
    try {
      debugPrint('createRiderLog payload ${json.encode(data)}');
    } catch (_) {}

    for (int attempt = 1; attempt <= maxAttempts; attempt++) {
      final client = _buildSslBypassClient();
      try {
        final url = Uri.parse(urldata);
        final response = await client.post(
          url,
          body: json.encode(data),
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
          },
        );
        debugPrint('createRiderLog url $urldata (attempt $attempt)');
        debugPrint('createRiderLog status ${response.statusCode}');
        debugPrint('createRiderLog response ${response.body}');

        if (response.statusCode >= 200 && response.statusCode < 300) {
          return json.decode(response.body.toString()) as Map<String, dynamic>;
        } else {
          debugPrint(
            'createRiderLog failed: HTTP ${response.statusCode} (attempt $attempt/$maxAttempts)',
          );
          // On 404/5xx, wait and retry to potentially hit a different CDN node
          if (attempt < maxAttempts) {
            await Future.delayed(const Duration(seconds: 1));
          }
        }
      } catch (e) {
        debugPrint('createRiderLog exception (attempt $attempt): $e');
        if (attempt < maxAttempts) {
          await Future.delayed(const Duration(seconds: 1));
        }
      } finally {
        client.close();
      }
    }

    debugPrint('createRiderLog failed after $maxAttempts attempts');
    return null;
  }
}


class UpdateRiderLogProvider {
  Future<Map<String, dynamic>?> updateRiderLog(
    String urldata,
    Map<String, dynamic> data,
  ) async {
    try {
      final url = Uri.parse(urldata);
      final response = await put(
        url,
        body: json.encode(data),
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
        },
      );

      debugPrint('updateRiderLog url: $urldata');
      debugPrint('updateRiderLog response: ${response.body}');

      if (response.statusCode >= 200 && response.statusCode < 300) {
        final decoded = json.decode(response.body);
        if (decoded is Map<String, dynamic>) {
          return decoded;
        } else {
          debugPrint('⚠️ updateRiderLog: Expected Map but got ${decoded.runtimeType}');
          return {};
        }
      } else {
        debugPrint('❌ updateRiderLog failed with code ${response.statusCode}');
        return {};
      }
    } catch (e) {
      debugPrint('❌ Exception in updateRiderLog: $e');
      return {};
    }
  }
}

class GetRiderLogProvider {
  Future<Map<String, dynamic>?> getRiderLog(String urldata) async {
    Map<String, dynamic>? getRiderLogResponse;
    try {
      final url = Uri.parse(urldata);
      final response = await get(url, headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      });
      debugPrint('getRiderLog response ${response.body}');
      debugPrint('getRiderLog url ${urldata.toString()}');
      getRiderLogResponse =
          json.decode(response.body.toString()) as Map<String, dynamic>;
    } catch (e) {
      debugPrint(e.toString());
    }
    return getRiderLogResponse;
  }

  Future<Map<String, dynamic>?> getRiderCount(String urldata) async {
    Map<String, dynamic>? getRiderCountResponse;
    try {
      final url = Uri.parse(urldata);
      final response = await get(url, headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      });
      debugPrint('getRiderCount response ${response.body}');
      debugPrint('getRiderCount url ${urldata.toString()}');
      getRiderCountResponse =
          json.decode(response.body.toString()) as Map<String, dynamic>;
    } catch (e) {
      debugPrint(e.toString());
    }
    return getRiderCountResponse;
  }
}

class BreakRiderLogProvider {
  Future<Map<String, dynamic>?> createBreakRiderLog(
    String urldata,
    Map<String, dynamic> data,
  ) async {
    Map<String, dynamic>? breakLogResponse;
    try {
      final url = Uri.parse(urldata);
      final response = await post(
        url,
        body: json.encode(data),
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
        },
      );
      debugPrint('createBreakRiderLog url $urldata');
      debugPrint('createBreakRiderLog response ${response.body}');
      breakLogResponse =
          json.decode(response.body.toString()) as Map<String, dynamic>;
    } catch (e) {
      debugPrint(e.toString());
    }
    return breakLogResponse;
  }

  Future<Map<String, dynamic>?> updateBreakRiderLog(
    String urldata,
    Map<String, dynamic> data,
  ) async {
    Map<String, dynamic>? breakLogResponse;
    try {
      final url = Uri.parse(urldata);
      final response = await put(
        url,
        body: json.encode(data),
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
        },
      );
      debugPrint('updateBreakRiderLog url $urldata');
      debugPrint('updateBreakRiderLog response ${response.body}');
      breakLogResponse =
          json.decode(response.body.toString()) as Map<String, dynamic>;
    } catch (e) {
      debugPrint(e.toString());
    }
    return breakLogResponse;
  }
}
