import 'package:hive/hive.dart';

part 'user_model.g.dart';

/// Modèle représentant l'utilisateur actuellement connecté (current user).
/// 
/// IMPORTANT : Ce modèle est utilisé UNIQUEMENT pour l'utilisateur connecté,
/// pas pour les membres de l'amicale. Pour les membres, utilisez MembreModel.
/// 
/// La box Hive 'users' ne contient qu'un seul enregistrement : l'utilisateur actuel.
/// 
/// Relations avec les autres modèles :
/// - MembreModel : représente TOUS les membres d'une amicale (y compris l'utilisateur actuel s'il est membre)
/// - UserSectorModel : associe les membres (pas les users) aux secteurs
@HiveType(typeId: 0)
class UserModel extends HiveObject {
  @HiveField(0)
  final int id;

  @HiveField(1)
  final String email;

  @HiveField(2)
  String? name;

  @HiveField(11)
  String? username;

  @HiveField(10)
  String? firstName;

  @HiveField(3)
  final int role;

  @HiveField(4)
  final DateTime createdAt;

  @HiveField(5)
  DateTime lastSyncedAt;

  @HiveField(6)
  bool isActive;

  @HiveField(7)
  bool isSynced;

  @HiveField(8)
  String? sessionId;

  @HiveField(9)
  DateTime? sessionExpiry;

  @HiveField(12)
  String? lastPath;

  @HiveField(13)
  String? sectName;

  @HiveField(14)
  int? fkEntite;

  @HiveField(15)
  int? fkTitre;

  @HiveField(16)
  String? phone;

  @HiveField(17)
  String? mobile;

  @HiveField(18)
  DateTime? dateNaissance;

  @HiveField(19)
  DateTime? dateEmbauche;

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

  UserModel({
    required this.id,
    required this.email,
    this.name,
    this.username,
    this.firstName,
    required this.role,
    required this.createdAt,
    required this.lastSyncedAt,
    this.isActive = true,
    this.isSynced = false,
    this.sessionId,
    this.sessionExpiry,
    this.lastPath,
    this.sectName,
    this.fkEntite,
    this.fkTitre,
    this.phone,
    this.mobile,
    this.dateNaissance,
    this.dateEmbauche,
    this.opeUserId,
  });

  // Factory pour convertir depuis JSON (API)
  factory UserModel.fromJson(Map<String, dynamic> json) {
    // 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, qu'il soit déjà int ou string
    final dynamic rawRole = json['role'] ?? json['fk_role'];
    final int role = rawRole is String ? int.parse(rawRole) : rawRole as int;

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

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

    // Traiter les dates si présentes
    DateTime? dateNaissance;
    if (json['date_naissance'] != null && json['date_naissance'] != '') {
      try {
        dateNaissance = DateTime.parse(json['date_naissance']);
      } catch (e) {
        dateNaissance = null;
      }
    }

    DateTime? dateEmbauche;
    if (json['date_embauche'] != null && json['date_embauche'] != '') {
      try {
        dateEmbauche = DateTime.parse(json['date_embauche']);
      } catch (e) {
        dateEmbauche = null;
      }
    }

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

    return UserModel(
      id: id,
      email: json['email'] ?? '',
      name: json['name'],
      username: json['username'],
      firstName: json['first_name'],
      role: role,
      createdAt: json['created_at'] != null
          ? DateTime.parse(json['created_at'])
          : DateTime.now(),
      lastSyncedAt: DateTime.now(),
      isActive: json['is_active'] ?? true,
      isSynced: true,
      sessionId: json['session_id'],
      sessionExpiry: json['session_expiry'] != null
          ? DateTime.parse(json['session_expiry'])
          : null,
      sectName: json['sect_name'],
      fkEntite: fkEntite,
      fkTitre: fkTitre,
      phone: json['phone'],
      mobile: json['mobile'],
      dateNaissance: dateNaissance,
      dateEmbauche: dateEmbauche,
      opeUserId: opeUserId,
    );
  }

  // Convertir en JSON pour l'API
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'email': email,
      'name': name,
      'username': username,
      'first_name': firstName,
      'role': role,
      'created_at': createdAt.toIso8601String(),
      'is_active': isActive,
      'session_id': sessionId,
      'session_expiry': sessionExpiry?.toIso8601String(),
      'last_path': lastPath,
      'sect_name': sectName,
      'fk_entite': fkEntite,
      'fk_titre': fkTitre,
      'phone': phone,
      'mobile': mobile,
      'date_naissance': dateNaissance?.toIso8601String(),
      'date_embauche': dateEmbauche?.toIso8601String(),
      'ope_user_id': opeUserId,
    };
  }

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

  // Vérifier si la session est valide
  bool get hasValidSession {
    if (sessionId == null || sessionExpiry == null) {
      return false;
    }
    return sessionExpiry!.isAfter(DateTime.now());
  }

  // Effacer les données de session
  UserModel clearSession() {
    return copyWith(
      sessionId: null,
      sessionExpiry: null,
    );
  }
}
