import 'dart:convert';
import 'package:cloud_firestore/cloud_firestore.dart';

class Trip {
  final String? id;
  final String title;
  final String description;
  final String location;
  final DateTime startDate;
  final DateTime endDate;
  final double? budget;
  final List<String> participants;
  final String createdBy;
  final DateTime createdAt;
  final DateTime updatedAt;
  final String status;

  Trip({
    this.id,
    required this.title,
    required this.description,
    required this.location,
    required this.startDate,
    required this.endDate,
    this.budget,
    required this.participants,
    required this.createdBy,
    required this.createdAt,
    required this.updatedAt,
    this.status = 'draft',
  });

  // NOUVELLE MÉTHODE HELPER pour convertir n'importe quel format de date
  static DateTime _parseDateTime(dynamic value) {
    if (value == null) return DateTime.now();
    
    // Si c'est déjà un Timestamp Firebase
    if (value is Timestamp) {
      return value.toDate();
    }
    
    // Si c'est un int (millisecondes depuis epoch)
    if (value is int) {
      return DateTime.fromMillisecondsSinceEpoch(value);
    }
    
    // Si c'est un String (ISO 8601)
    if (value is String) {
      return DateTime.parse(value);
    }
    
    // Si c'est déjà un DateTime
    if (value is DateTime) {
      return value;
    }
    
    // Par défaut
    return DateTime.now();
  }

  // Constructeur pour créer un Trip depuis un Map (utile pour Firebase)
  factory Trip.fromMap(Map<String, dynamic> map, String id) {
    try {
      return Trip(
        id: id,
        title: map['title'] as String? ?? '',
        description: map['description'] as String? ?? '',
        location: map['location'] as String? ?? '',
        startDate: _parseDateTime(map['startDate']),
        endDate: _parseDateTime(map['endDate']),
        budget: (map['budget'] as num?)?.toDouble(),
        createdBy: map['createdBy'] as String? ?? '',
        participants: List<String>.from(map['participants'] as List? ?? []),
        createdAt: _parseDateTime(map['createdAt']),
        updatedAt: _parseDateTime(map['updatedAt']),
        status: map['status'] as String? ?? 'draft',
      );
    } catch (e) {
      print('❌ Erreur parsing Trip: $e');
      print('Map reçue: $map');
      rethrow;
    }
  }

  // MODIFIÉ : Convertir en Map avec Timestamp pour Firestore
  Map<String, dynamic> toMap() {
    return {
      'title': title,
      'description': description,
      'location': location,
      'startDate': Timestamp.fromDate(startDate),
      'endDate': Timestamp.fromDate(endDate),
      'budget': budget,
      'participants': participants,
      'createdBy': createdBy,
      'createdAt': Timestamp.fromDate(createdAt),
      'updatedAt': Timestamp.fromDate(updatedAt),
      'status': status,
    };
  }

  // Méthode pour convertir un Trip en JSON
  String toJson() {
    return json.encode(toMap());
  }

  // Méthode pour créer une copie avec des modifications
  Trip copyWith({
    String? id,
    String? title,
    String? description,
    String? location,
    DateTime? startDate,
    DateTime? endDate,
    double? budget,
    List<String>? participants,
    String? createdBy,
    DateTime? createdAt,
    DateTime? updatedAt,
    String? status,
  }) {
    return Trip(
      id: id ?? this.id,
      title: title ?? this.title,
      description: description ?? this.description,
      location: location ?? this.location,
      startDate: startDate ?? this.startDate,
      endDate: endDate ?? this.endDate,
      budget: budget ?? this.budget,
      participants: participants ?? this.participants,
      createdBy: createdBy ?? this.createdBy,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
      status: status ?? this.status,
    );
  }

  // Méthode pour obtenir la durée du voyage en jours
  int get durationInDays {
    return endDate.difference(startDate).inDays + 1;
  }

  // Méthode pour vérifier si le voyage est en cours
  bool get isActive {
    final now = DateTime.now();
    return status == 'active' &&
        now.isAfter(startDate) &&
        now.isBefore(endDate.add(Duration(days: 1)));
  }

  // Méthode pour vérifier si le voyage est à venir
  bool get isUpcoming {
    final now = DateTime.now();
    return status == 'active' && now.isBefore(startDate);
  }

  // Méthode pour vérifier si le voyage est terminé
  bool get isCompleted {
    final now = DateTime.now();
    return status == 'completed' ||
        (status == 'active' && now.isAfter(endDate));
  }

  // Méthode pour obtenir le budget par participant
  double? get budgetPerParticipant {
    if (budget == null || participants.isEmpty) return null;
    return budget! / (participants.length + 1);
  }

  // Méthode pour obtenir le nombre total de participants (incluant le créateur)
  int get totalParticipants {
    return participants.length + 1;
  }

  // Méthode pour formater les dates
  String get formattedDates {
    return '${startDate.day}/${startDate.month}/${startDate.year} - ${endDate.day}/${endDate.month}/${endDate.year}';
  }

  // Méthode pour obtenir le statut formaté
  String get formattedStatus {
    switch (status) {
      case 'draft':
        return 'Brouillon';
      case 'active':
        return 'Actif';
      case 'completed':
        return 'Terminé';
      case 'cancelled':
        return 'Annulé';
      default:
        return 'Inconnu';
    }
  }

  @override
  String toString() {
    return 'Trip(id: $id, title: $title, location: $location, status: $status)';
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is Trip && other.id == id;
  }

  @override
  int get hashCode => id.hashCode;
}