import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:device_info_plus/device_info_plus.dart';
import 'package:crypto/crypto.dart';
import '../data/models/shot.dart';
import '../data/models/target_type.dart';
import 'wallet_identity_service.dart';

class AiExportService {
  // Utilise 10.0.2.2 pour l'émulateur Android, sinon localhost.
  // Pour un appareil physique, il faudra utiliser l'IP locale du PC (ex: 192.168.1.X).
  static String get _defaultApiUrl {
    if (Platform.isAndroid) {
      return 'http://10.0.2.2:3000/api/upload';
    }
    return 'http://localhost:3000/api/upload';
  }

  /// Extrait les informations de l'appareil
  Future<Map<String, dynamic>> _getDeviceInfo() async {
    final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
    Map<String, dynamic> deviceData = {'model': 'Unknown', 'os': 'Unknown'};

    try {
      if (Platform.isAndroid) {
        final androidInfo = await deviceInfoPlugin.androidInfo;
        deviceData['model'] = '${androidInfo.brand} ${androidInfo.model}';
        deviceData['os'] = 'Android ${androidInfo.version.release}';
      } else if (Platform.isIOS) {
        final iosInfo = await deviceInfoPlugin.iosInfo;
        deviceData['model'] = iosInfo.name;
        deviceData['os'] = '${iosInfo.systemName} ${iosInfo.systemVersion}';
      } else if (Platform.isWindows) {
        final windowsInfo = await deviceInfoPlugin.windowsInfo;
        deviceData['model'] = 'Windows PC';
        deviceData['os'] = 'Windows ${windowsInfo.majorVersion}.${windowsInfo.minorVersion}';
      }
    } catch (e) {
      debugPrint('Erreur lors de la récupération des infos appareil: $e');
    }

    return deviceData;
  }

  /// Exporte l'image et les données de plotting vers le serveur
  Future<bool> exportData({
    required String imagePath,
    required String sessionId,
    required TargetType targetType,
    required double targetCenterX,
    required double targetCenterY,
    required double targetRadius,
    required List<Shot> shots,
    String? apiUrl,
  }) async {
    try {
      final url = Uri.parse(apiUrl ?? _defaultApiUrl);
      final request = http.MultipartRequest('POST', url);

      // 1. Prepare image
      final file = File(imagePath);
      if (!await file.exists()) {
        throw Exception('Le fichier image n\'existe pas');
      }

      // Read image metadata (approximate dimensions since decoding image can be heavy)
      // On the frontend we usually have aspectRatio, here we use generic values if not available.
      final deviceData = await _getDeviceInfo();

      // We approximate the target corners from center and radius
      // radius is relative (0 to 1). We need image width/height to get pixels.
      // But we can just pass relative corners as well, or a normalized bounding box.
      // Let's create normalized corners (0 to 1).
      final corners = [
        {"norm_x": targetCenterX - targetRadius, "norm_y": targetCenterY - targetRadius},
        {"norm_x": targetCenterX + targetRadius, "norm_y": targetCenterY - targetRadius},
        {"norm_x": targetCenterX + targetRadius, "norm_y": targetCenterY + targetRadius},
        {"norm_x": targetCenterX - targetRadius, "norm_y": targetCenterY + targetRadius},
      ];

      // Format the impacts
      final formattedImpacts = shots.asMap().entries.map((entry) {
        final index = entry.key;
        final shot = entry.value;
        return {
          "id": index + 1,
          "label": "bullet_hole",
          "score": shot.score,
          "coords": {
            "norm_x": shot.x,
            "norm_y": shot.y
          }
        };
      }).toList();

      // Get and hash the wallet identity
      final walletService = WalletIdentityService();
      final phrase = await walletService.getIdentityPhrase();
      final phraseBytes = utf8.encode(phrase);
      final walletHash = sha256.convert(phraseBytes).toString();

      // Build JSON payload
      final plottingJson = {
        "session_id": sessionId,
        "wallet_hash": walletHash,
        "timestamp": DateTime.now().toIso8601String(),
        "device_info": deviceData,
        "target_metadata": {
          "type": targetType.name,
          "distance_meters": 25, // Default/placeholder
          "weapon": "Unknown", // Default/placeholder
          // The backend could extract exact width/height from the image. 
        },
        "plotting": {
          "target_corners": corners,
          "impacts": formattedImpacts
        }
      };

      // Add fields to request
      request.fields['plotting'] = jsonEncode(plottingJson);

      // Add file
      request.files.add(
        await http.MultipartFile.fromPath('photo', imagePath),
      );

      // Send request
      final response = await request.send();

      if (response.statusCode == 200) {
        final responseData = await response.stream.bytesToString();
        debugPrint('Export réussi: $responseData');
        return true;
      } else {
        final errorData = await response.stream.bytesToString();
        debugPrint('Erreur d\'export: ${response.statusCode} - $errorData');
        return false;
      }
    } catch (e) {
      debugPrint('Exception lors de l\'export: $e');
      return false;
    }
  }
}
