import 'dart:convert';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:http/http.dart' as http;
import 'package:em2rp/config/api_config.dart';
import 'package:em2rp/models/depot_model.dart';
import 'package:em2rp/models/route_result_model.dart';
import 'package:em2rp/utils/debug_log.dart';

class TravelService {
  final FirebaseFirestore _db = FirebaseFirestore.instance;

  // ─── Auth token ───────────────────────────────────────────
  Future<String?> _getToken() async {
    final user = FirebaseAuth.instance.currentUser;
    return await user?.getIdToken();
  }

  Future<Map<String, String>> _headers() async {
    final token = await _getToken();
    return {
      'Content-Type': 'application/json',
      if (token != null) 'Authorization': 'Bearer $token',
    };
  }

  // ─── Autocomplétion d'adresses ────────────────────────────
  Future<List<String>> autocompleteAddress(String query) async {
    if (query.trim().length < 3) return [];
    try {
      final headers = await _headers();
      final url = Uri.parse('${ApiConfig.baseUrl}/googleMapsAutocomplete');
      final response = await http.post(
        url,
        headers: headers,
        body: jsonEncode({'data': {'query': query}}),
      );
      if (response.statusCode != 200) return [];
      final data = jsonDecode(response.body) as Map<String, dynamic>;
      final predictions = data['predictions'] as List<dynamic>? ?? [];
      return predictions
          .map((p) => (p['description'] ?? '').toString())
          .where((s) => s.isNotEmpty)
          .toList();
    } catch (e) {
      DebugLog.error('[Travel] autocompleteAddress error', e);
      return [];
    }
  }

  // ─── Calcul des itinéraires ───────────────────────────────
  Future<List<RouteResult>> computeRoutes({
    required String origin,
    required String destination,
    int vehicleTollCategory = 2,
  }) async {
    try {
      final headers = await _headers();
      final url = Uri.parse('${ApiConfig.baseUrl}/googleMapsComputeRoute');
      final response = await http.post(
        url,
        headers: headers,
        body: jsonEncode({
          'data': {
            'origin': origin,
            'destination': destination,
            'vehicleTollCategory': vehicleTollCategory,
          },
        }),
      );

      if (response.statusCode != 200) {
        final err = jsonDecode(response.body);
        throw Exception('googleMapsComputeRoute: ${err['error']}');
      }

      final data = jsonDecode(response.body) as Map<String, dynamic>;
      final routes = data['routes'] as List<dynamic>? ?? [];
      return routes
          .map((r) => RouteResult.fromMap(r as Map<String, dynamic>))
          .toList();
    } catch (e) {
      DebugLog.error('[Travel] computeRoutes error', e);
      rethrow;
    }
  }

  // ─── Prix des carburants ───────────────────────────────────
  Future<FuelPrices> getFuelPrices() async {
    try {
      final doc = await _db.collection('app_config').doc('fuel_prices').get();
      if (!doc.exists) return const FuelPrices();
      return FuelPrices.fromMap(doc.data()!);
    } catch (e) {
      return const FuelPrices();
    }
  }

  Future<void> saveFuelPrices(FuelPrices prices) async {
    await _db.collection('app_config').doc('fuel_prices').set(prices.toMap());
  }

  // ─── Dépôts ───────────────────────────────────────────────
  Future<List<DepotModel>> getDepots() async {
    final snap = await _db.collection('depots').orderBy('name').get();
    return snap.docs.map((d) => DepotModel.fromFirestore(d)).toList();
  }

  Stream<List<DepotModel>> watchDepots() {
    return _db
        .collection('depots')
        .orderBy('name')
        .snapshots()
        .map((s) => s.docs.map((d) => DepotModel.fromFirestore(d)).toList());
  }

  Future<String> addDepot(DepotModel depot) async {
    final ref = await _db.collection('depots').add(depot.toMap());
    return ref.id;
  }

  Future<void> updateDepot(DepotModel depot) async {
    final map = depot.toMap();
    map.remove('createdAt');
    await _db.collection('depots').doc(depot.id).update(map);
  }

  Future<void> deleteDepot(String depotId) async {
    await _db.collection('depots').doc(depotId).delete();
  }
}

/// Instance singleton
final travelService = TravelService();
