import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:em2rp/models/equipment_model.dart';

/// Type de container
enum ContainerType {
  flightCase,      // Flight case
  pelicase,        // Pelicase
  bag,             // Sac
  openCrate,       // Caisse ouverte
  toolbox,         // Boîte à outils
}

String containerTypeToString(ContainerType type) {
  switch (type) {
    case ContainerType.flightCase:
      return 'FLIGHT_CASE';
    case ContainerType.pelicase:
      return 'PELICASE';
    case ContainerType.bag:
      return 'BAG';
    case ContainerType.openCrate:
      return 'OPEN_CRATE';
    case ContainerType.toolbox:
      return 'TOOLBOX';
  }
}

ContainerType containerTypeFromString(String? type) {
  switch (type) {
    case 'FLIGHT_CASE':
      return ContainerType.flightCase;
    case 'PELICASE':
      return ContainerType.pelicase;
    case 'BAG':
      return ContainerType.bag;
    case 'OPEN_CRATE':
      return ContainerType.openCrate;
    case 'TOOLBOX':
      return ContainerType.toolbox;
    default:
      return ContainerType.flightCase;
  }
}

String containerTypeLabel(ContainerType type) {
  switch (type) {
    case ContainerType.flightCase:
      return 'Flight Case';
    case ContainerType.pelicase:
      return 'Pelicase';
    case ContainerType.bag:
      return 'Sac';
    case ContainerType.openCrate:
      return 'Caisse Ouverte';
    case ContainerType.toolbox:
      return 'Boîte à Outils';
  }
}

// Extensions pour centraliser les informations d'affichage
extension ContainerTypeExtension on ContainerType {
  /// Retourne le label français du type de container
  String get label {
    switch (this) {
      case ContainerType.flightCase:
        return 'Flight Case';
      case ContainerType.pelicase:
        return 'Pelicase';
      case ContainerType.bag:
        return 'Sac';
      case ContainerType.openCrate:
        return 'Caisse Ouverte';
      case ContainerType.toolbox:
        return 'Boîte à Outils';
    }
  }

  /// Retourne l'icône Material du type de container
  IconData get iconData {
    switch (this) {
      case ContainerType.flightCase:
        return Icons.work;
      case ContainerType.pelicase:
        return Icons.work_outline;
      case ContainerType.bag:
        return Icons.shopping_bag;
      case ContainerType.openCrate:
        return Icons.inventory_2;
      case ContainerType.toolbox:
        return Icons.home_repair_service;
    }
  }

  /// Retourne le chemin de l'icône personnalisée (si disponible)
  String? get customIconPath {
    switch (this) {
      case ContainerType.flightCase:
        return 'assets/icons/flight-case.svg';
      default:
        return null;
    }
  }

  /// Vérifie si une icône personnalisée est disponible
  bool get hasCustomIcon => customIconPath != null;

  /// Retourne l'icône Widget à afficher (unifié pour Material et personnalisé)
  Widget getIcon({double size = 24, Color? color}) {
    final customPath = customIconPath;
    if (customPath != null) {
      // Détection automatique du format (SVG ou PNG)
      final isSvg = customPath.toLowerCase().endsWith('.svg');

      if (isSvg) {
        // SVG : on peut appliquer la couleur sans dégrader la qualité
        return SvgPicture.asset(
          customPath,
          width: size,
          height: size,
          colorFilter: color != null
            ? ColorFilter.mode(color, BlendMode.srcIn)
            : null,
          placeholderBuilder: (context) => Icon(iconData, size: size, color: color),
        );
      } else {
        // PNG : on n'applique PAS le color filter pour préserver la qualité
        return Image.asset(
          customPath,
          width: size,
          height: size,
          filterQuality: FilterQuality.high,
          errorBuilder: (context, error, stackTrace) {
            return Icon(iconData, size: size, color: color);
          },
        );
      }
    }
    return Icon(iconData, size: size, color: color);
  }

  /// Version pour CircleAvatar et contextes similaires
  Widget getIconForAvatar({double size = 24, Color? color}) {
    final customPath = customIconPath;
    if (customPath != null) {
      final isSvg = customPath.toLowerCase().endsWith('.svg');

      if (isSvg) {
        return SvgPicture.asset(
          customPath,
          width: size,
          height: size,
          colorFilter: color != null
            ? ColorFilter.mode(color, BlendMode.srcIn)
            : null,
          placeholderBuilder: (context) => Icon(iconData, size: size, color: color),
        );
      } else {
        return Image.asset(
          customPath,
          width: size,
          height: size,
          filterQuality: FilterQuality.high,
          errorBuilder: (context, error, stackTrace) {
            return Icon(iconData, size: size, color: color);
          },
        );
      }
    }
    return Icon(iconData, size: size, color: color);
  }
}

/// Modèle de container/boîte pour le matériel
class ContainerModel {
  final String id;                          // Identifiant unique (généré comme pour équipement)
  final String name;                        // Nom du container
  final ContainerType type;                 // Type de container
  final EquipmentStatus status;             // Statut actuel (même que équipement)

  // Caractéristiques physiques
  final double? weight;                     // Poids à vide (kg)
  final double? length;                     // Longueur (cm)
  final double? width;                      // Largeur (cm)
  final double? height;                     // Hauteur (cm)

  // Contenu
  final List<String> equipmentIds;          // IDs des équipements contenus

  // Événement
  final String? eventId;                    // ID de l'événement actuel (si en prestation)

  // Métadonnées
  final String? notes;                      // Notes additionnelles
  final DateTime createdAt;                 // Date de création
  final DateTime updatedAt;                 // Date de mise à jour

  // Historique simple (optionnel)
  final List<ContainerHistoryEntry> history; // Historique des modifications

  ContainerModel({
    required this.id,
    required this.name,
    required this.type,
    this.status = EquipmentStatus.available,
    this.weight,
    this.length,
    this.width,
    this.height,
    this.equipmentIds = const [],
    this.eventId,
    this.notes,
    required this.createdAt,
    required this.updatedAt,
    this.history = const [],
  });

  /// Vérifier si le container est vide
  bool get isEmpty => equipmentIds.isEmpty;

  /// Nombre d'équipements dans le container
  int get itemCount => equipmentIds.length;

  /// Calculer le volume (m³)
  double? get volume {
    if (length == null || width == null || height == null) return null;
    return (length! * width! * height!) / 1000000; // cm³ to m³
  }

  /// Calculer le poids total (poids vide + équipements)
  /// Nécessite la liste des équipements
  double calculateTotalWeight(List<EquipmentModel> equipment) {
    double total = weight ?? 0.0;
    for (final eq in equipment) {
      if (equipmentIds.contains(eq.id) && eq.weight != null) {
        total += eq.weight!;
      }
    }
    return total;
  }

  /// Factory depuis Firestore
  factory ContainerModel.fromMap(Map<String, dynamic> map, String id) {
    // Fonction helper pour convertir de manière sécurisée en double
    double? parseDouble(dynamic value) {
      if (value == null) return null;
      if (value is num) return value.toDouble();
      if (value is String) return double.tryParse(value);
      return null;
    }

    // Fonction helper pour convertir Timestamp ou String ISO ou int epoch en DateTime
    DateTime? parseDate(dynamic value) {
      if (value == null) return null;
      if (value is Timestamp) return value.toDate();
      if (value is String) return DateTime.tryParse(value);
      if (value is int) return DateTime.fromMillisecondsSinceEpoch(value);
      return null;
    }

    // Gestion sécurisée de la liste d'IDs d'équipements
    final List<String> equipmentIds = [];
    if (map['equipmentIds'] is List) {
      for (final e in map['equipmentIds'] as List) {
        if (e != null) {
          equipmentIds.add(e.toString());
        }
      }
    }

    // Gestion sécurisée de l'historique
    final List<ContainerHistoryEntry> history = [];
    if (map['history'] is List) {
      for (final e in map['history'] as List) {
        if (e is Map<String, dynamic>) {
          history.add(ContainerHistoryEntry.fromMap(e));
        }
      }
    }

    return ContainerModel(
      id: id,
      name: (map['name'] ?? '').toString(),
      type: containerTypeFromString(map['type']?.toString()),
      status: equipmentStatusFromString(map['status']?.toString()),
      weight: parseDouble(map['weight']),
      length: parseDouble(map['length']),
      width: parseDouble(map['width']),
      height: parseDouble(map['height']),
      equipmentIds: equipmentIds,
      eventId: map['eventId']?.toString(),
      notes: map['notes']?.toString(),
      createdAt: parseDate(map['createdAt']) ?? DateTime.now(),
      updatedAt: parseDate(map['updatedAt']) ?? DateTime.now(),
      history: history,
    );
  }

  /// Convertir en Map pour Firestore
  Map<String, dynamic> toMap() {
    return {
      'name': name,
      'type': containerTypeToString(type),
      'status': equipmentStatusToString(status),
      'weight': weight,
      'length': length,
      'width': width,
      'height': height,
      'equipmentIds': equipmentIds,
      'eventId': eventId,
      'notes': notes,
      'createdAt': Timestamp.fromDate(createdAt),
      'updatedAt': Timestamp.fromDate(updatedAt),
      'history': history.map((e) => e.toMap()).toList(),
    };
  }

  /// Copier avec modifications
  ContainerModel copyWith({
    String? id,
    String? name,
    ContainerType? type,
    EquipmentStatus? status,
    double? weight,
    double? length,
    double? width,
    double? height,
    List<String>? equipmentIds,
    String? eventId,
    String? notes,
    DateTime? createdAt,
    DateTime? updatedAt,
    List<ContainerHistoryEntry>? history,
  }) {
    return ContainerModel(
      id: id ?? this.id,
      name: name ?? this.name,
      type: type ?? this.type,
      status: status ?? this.status,
      weight: weight ?? this.weight,
      length: length ?? this.length,
      width: width ?? this.width,
      height: height ?? this.height,
      equipmentIds: equipmentIds ?? this.equipmentIds,
      eventId: eventId ?? this.eventId,
      notes: notes ?? this.notes,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
      history: history ?? this.history,
    );
  }
}

/// Entrée d'historique pour un container
class ContainerHistoryEntry {
  final DateTime timestamp;
  final String action;                      // 'added', 'removed', 'status_change', etc.
  final String? equipmentId;                // ID de l'équipement concerné (si applicable)
  final String? previousValue;              // Valeur précédente
  final String? newValue;                   // Nouvelle valeur
  final String? userId;                     // ID de l'utilisateur ayant fait la modification

  ContainerHistoryEntry({
    required this.timestamp,
    required this.action,
    this.equipmentId,
    this.previousValue,
    this.newValue,
    this.userId,
  });

  factory ContainerHistoryEntry.fromMap(Map<String, dynamic> map) {
    // Helper pour parser la date
    DateTime parseDate(dynamic value) {
      if (value == null) return DateTime.now();
      if (value is Timestamp) return value.toDate();
      if (value is String) return DateTime.tryParse(value) ?? DateTime.now();
      if (value is int) return DateTime.fromMillisecondsSinceEpoch(value);
      return DateTime.now();
    }

    return ContainerHistoryEntry(
      timestamp: parseDate(map['timestamp']),
      action: (map['action'] ?? '').toString(),
      equipmentId: map['equipmentId']?.toString(),
      previousValue: map['previousValue']?.toString(),
      newValue: map['newValue']?.toString(),
      userId: map['userId']?.toString(),
    );
  }

  Map<String, dynamic> toMap() {
    return {
      'timestamp': Timestamp.fromDate(timestamp),
      'action': action,
      'equipmentId': equipmentId,
      'previousValue': previousValue,
      'newValue': newValue,
      'userId': userId,
    };
  }
}

