import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart';
import 'package:geosector_app/core/data/models/user_model.dart';

part 'membre_model.g.dart';

/// Modèle représentant un membre d'une amicale.
///
/// IMPORTANT : Ce modèle représente TOUS les membres d'une amicale,
/// pas seulement l'utilisateur connecté. Pour l'utilisateur connecté, voir UserModel.
///
/// La box Hive 'membres' contient plusieurs enregistrements (tous les membres de l'amicale).
///
/// Relations avec les autres modèles :
/// - UserModel : représente uniquement l'utilisateur connecté (current user)
/// - UserSectorModel : utilise MembreModel.id pour associer les membres aux secteurs
///   ATTENTION : UserSectorModel.id = MembreModel.id (pas UserModel.id)
///
/// ⚠️ IMPORTANT : Distinction des IDs
/// - id : ID de la table centrale `users` (pour gestion des membres)
/// - opeUserId : ID de la table `ope_users` (pour lier avec passages/secteurs de l'opération active)
///
/// Chaque membre a son propre ID unique qui est utilisé pour :
/// - L'attribution aux secteurs (via UserSectorModel)
/// - La gestion des passages (via MembreModel.opeUserId == PassageModel.fkUser)
/// - Les statistiques par membre
@HiveType(typeId: 5) // Utilisation d'un typeId unique
class MembreModel extends HiveObject {
  @HiveField(0)
  final int id;

  @HiveField(1)
  int? fkEntite;
  @HiveField(2)
  final int role;

  @HiveField(3)
  int? fkTitre;
  @HiveField(4)
  String? name;

  @HiveField(5)
  String? firstName;
  @HiveField(6)
  String? username;
  @HiveField(7)
  String? sectName;
  @HiveField(8)
  final String email;

  @HiveField(9)
  String? phone;
  @HiveField(10)
  String? mobile;
  @HiveField(11)
  DateTime? dateNaissance;
  @HiveField(12)
  DateTime? dateEmbauche;
  @HiveField(13)
  final DateTime createdAt;
  @HiveField(14)
  bool isActive;

  @HiveField(15)
  int? opeUserId; // ID dans ope_users pour l'opération active

  MembreModel({
    required this.id,
    this.fkEntite,
    required this.role,
    this.fkTitre,
    this.name,
    this.firstName,
    this.username,
    this.sectName,
    required this.email,
    this.phone,
    this.mobile,
    this.dateNaissance,
    this.dateEmbauche,
    required this.createdAt,
    required this.isActive,
    this.opeUserId,
  });

  // Factory pour convertir depuis JSON (API)
  factory MembreModel.fromJson(Map<String, dynamic> json) {
    try {
      // Convertir l'ID en int, qu'il soit déjà int ou string
      final dynamic rawId = json['id'];
      final int id = rawId is String ? int.parse(rawId) : rawId as int;

      // Convertir le rôle en int (ATTENTION: le champ JSON est 'fk_role' pas 'role')
      final dynamic rawRole = json['fk_role']; // Correction ici !
      final int role = rawRole is String ? int.parse(rawRole) : rawRole as int;

      // Convertir fkEntite en int si présent
      int? fkEntite;
      if (json['fk_entite'] != null) {
        final dynamic rawEntite = json['fk_entite'];
        fkEntite = rawEntite is String ? int.parse(rawEntite) : rawEntite as int;
      }

      // Convertir fkTitre en int si présent
      int? fkTitre;
      if (json['fk_titre'] != null) {
        final dynamic rawTitre = json['fk_titre'];
        fkTitre = rawTitre is String ? int.parse(rawTitre) : rawTitre as int;
      }

      // Gérer les dates nulles ou avec des valeurs invalides comme "0000-00-00"
      DateTime? parseDate(String? dateStr) {
        if (dateStr == null || dateStr.isEmpty || dateStr == "0000-00-00") {
          return null;
        }
        try {
          return DateTime.parse(dateStr);
        } catch (e) {
          return null;
        }
      }

      // Convertir ope_user_id en int si présent
      int? opeUserId;
      if (json['ope_user_id'] != null) {
        final dynamic rawOpeUserId = json['ope_user_id'];
        opeUserId = rawOpeUserId is String ? int.parse(rawOpeUserId) : rawOpeUserId as int;
      }

      return MembreModel(
        id: id,
        fkEntite: fkEntite,
        role: role,
        fkTitre: fkTitre,
        name: json['name'] ?? '', // ← Fallback pour champs manquants
        firstName: json['first_name'] ?? '', // ← Fallback pour champs manquants
        username: json['username'] ?? '', // ← Fallback pour champs manquants
        sectName: json['sect_name'] ?? '',
        email: json['email'] ?? '', // ← Déjà OK mais renforcé
        phone: json['phone'],
        mobile: json['mobile'],
        dateNaissance: parseDate(json['date_naissance']),
        dateEmbauche: parseDate(json['date_embauche']),
        createdAt: DateTime.now(), // ← Simplifié car created_at n'existe pas dans l'API
        // Le champ JSON est 'chk_active' pas 'is_active'
        isActive: json['chk_active'] == 1 || json['chk_active'] == true,
        opeUserId: opeUserId,
      );
    } catch (e) {
      debugPrint('❌ Erreur parsing MembreModel: $e');
      debugPrint('❌ Données JSON: $json');
      rethrow;
    }
  }

  // Convertir en JSON pour l'API
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'ope_user_id': opeUserId,
      'fk_entite': fkEntite,
      'fk_role': role, // Changé pour correspondre à l'API
      'fk_titre': fkTitre,
      'name': name,
      'first_name': firstName,
      'username': username,
      'sect_name': sectName,
      'email': email,
      'phone': phone,
      'mobile': mobile,
      'date_naissance': dateNaissance?.toIso8601String(),
      'date_embauche': dateEmbauche?.toIso8601String(),
      'created_at': createdAt.toIso8601String(),
      'chk_active': isActive ? 1 : 0, // Changé pour correspondre à l'API
    };
  }

  // Copier avec de nouvelles valeurs
  MembreModel copyWith({
    int? fkEntite,
    int? role,
    int? fkTitre,
    String? name,
    String? firstName,
    String? username,
    String? sectName,
    String? email,
    String? phone,
    String? mobile,
    DateTime? dateNaissance,
    DateTime? dateEmbauche,
    DateTime? createdAt,
    bool? isActive,
    int? opeUserId,
  }) {
    return MembreModel(
      id: id,
      fkEntite: fkEntite ?? this.fkEntite,
      role: role ?? this.role,
      fkTitre: fkTitre ?? this.fkTitre,
      name: name ?? this.name,
      firstName: firstName ?? this.firstName,
      username: username ?? this.username,
      sectName: sectName ?? this.sectName,
      email: email ?? this.email,
      phone: phone ?? this.phone,
      mobile: mobile ?? this.mobile,
      dateNaissance: dateNaissance ?? this.dateNaissance,
      dateEmbauche: dateEmbauche ?? this.dateEmbauche,
      createdAt: createdAt ?? this.createdAt,
      isActive: isActive ?? this.isActive,
      opeUserId: opeUserId ?? this.opeUserId,
    );
  }

  // Convertir un MembreModel vers UserModel pour l'édition
  UserModel toUserModel() {
    return UserModel(
      id: id,
      email: email,
      name: name,
      username: username,
      firstName: firstName,
      role: role,
      createdAt: createdAt,
      lastSyncedAt: DateTime.now(),
      isActive: isActive,
      isSynced: false,
      fkEntite: fkEntite,
      fkTitre: fkTitre,
      phone: phone,
      mobile: mobile,
      dateNaissance: dateNaissance,
      dateEmbauche: dateEmbauche,
      sectName: sectName,
      opeUserId: opeUserId,
    );
  }

  // Créer un MembreModel depuis un UserModel mis à jour
  static MembreModel fromUserModel(UserModel user, MembreModel originalMembre) {
    return originalMembre.copyWith(
      name: user.name,
      firstName: user.firstName,
      username: user.username,
      email: user.email,
      fkEntite: user.fkEntite,
      role: user.role,
      sectName: user.sectName,
      fkTitre: user.fkTitre,
      phone: user.phone,
      mobile: user.mobile,
      dateNaissance: user.dateNaissance,
      dateEmbauche: user.dateEmbauche,
      isActive: user.isActive,
      opeUserId: user.opeUserId,
    );
  }
}
