import 'package:p_tits_pas/models/user.dart';
import 'package:p_tits_pas/utils/enfant_status_utils.dart';

/// Enfant tel que renvoyé par `GET /enfants` (dashboard admin).
class EnfantAdminModel {
  final String id;
  final String? firstName;
  final String? lastName;
  final String? gender;
  final String? birthDate;
  final String? dueDate;
  final String status;
  final String? photoUrl;
  final bool consentPhoto;
  final bool isMultiple;
  final List<EnfantParentLink> parentLinks;
  /// Flag API #157 (sinon déduit de [parentLinks]).
  final bool? sansResponsable;

  EnfantAdminModel({
    required this.id,
    this.firstName,
    this.lastName,
    this.gender,
    this.birthDate,
    this.dueDate,
    required this.status,
    this.photoUrl,
    this.consentPhoto = false,
    this.isMultiple = false,
    this.parentLinks = const [],
    this.sansResponsable,
  });

  String get fullName {
    final fn = (firstName ?? '').trim();
    final ln = (lastName ?? '').trim();
    if (fn.isEmpty && ln.isEmpty) return 'Enfant';
    if (ln.isEmpty) return fn;
    return '$fn $ln';
  }

  /// Aucun lien parent valide — ticket #157.
  bool get hasNoResponsable {
    if (sansResponsable != null) return sansResponsable!;
    return !parentLinks.any((l) => l.parentId.trim().isNotEmpty);
  }

  EnfantAdminModel copyWith({
    String? id,
    String? firstName,
    String? lastName,
    String? gender,
    String? birthDate,
    String? dueDate,
    String? status,
    String? photoUrl,
    bool? consentPhoto,
    bool? isMultiple,
    List<EnfantParentLink>? parentLinks,
    bool? sansResponsable,
  }) {
    return EnfantAdminModel(
      id: id ?? this.id,
      firstName: firstName ?? this.firstName,
      lastName: lastName ?? this.lastName,
      gender: gender ?? this.gender,
      birthDate: birthDate ?? this.birthDate,
      dueDate: dueDate ?? this.dueDate,
      status: status ?? this.status,
      photoUrl: photoUrl ?? this.photoUrl,
      consentPhoto: consentPhoto ?? this.consentPhoto,
      isMultiple: isMultiple ?? this.isMultiple,
      parentLinks: parentLinks ?? this.parentLinks,
      sansResponsable: sansResponsable ?? this.sansResponsable,
    );
  }

  factory EnfantAdminModel.fromJson(Map<String, dynamic> json) {
    final linksRaw = json['parentLinks'] as List?;
    final links = <EnfantParentLink>[];
    if (linksRaw != null) {
      for (final item in linksRaw) {
        if (item is Map<String, dynamic>) {
          links.add(EnfantParentLink.fromJson(item));
        }
      }
    }

    final photoUrl = json['photo_url'] as String? ?? json['photoUrl'] as String?;
    final consentPhoto = _parseBool(json['consent_photo']) ||
        _parseBool(json['consentement_photo']) ||
        _parseBool(json['consentPhoto']);

    bool? sansResponsable;
    if (json.containsKey('sans_responsable') ||
        json.containsKey('sansResponsable')) {
      sansResponsable = _parseBool(json['sans_responsable']) ||
          _parseBool(json['sansResponsable']);
    }

    return EnfantAdminModel(
      id: (json['id'] ?? '').toString(),
      firstName: json['first_name'] as String? ?? json['prenom'] as String?,
      lastName: json['last_name'] as String? ?? json['nom'] as String?,
      gender: json['gender'] as String? ?? json['genre'] as String?,
      birthDate: _dateString(json['birth_date'] ?? json['date_naissance']),
      dueDate: _dateString(json['due_date'] ?? json['date_prevue_naissance']),
      status: normalizeEnfantStatus(
        (json['status'] ?? json['statut'])?.toString(),
      ),
      photoUrl: photoUrl,
      consentPhoto: consentPhoto,
      isMultiple: _parseBool(json['is_multiple']) ||
          _parseBool(json['est_multiple']),
      parentLinks: links,
      sansResponsable: sansResponsable,
    );
  }

  Map<String, dynamic> toUpdateJson() {
    return {
      if (firstName != null) 'first_name': firstName,
      if (lastName != null) 'last_name': lastName,
      if (gender != null && gender!.isNotEmpty) 'gender': gender,
      'status': status,
      if (birthDate != null && birthDate!.isNotEmpty) 'birth_date': birthDate,
      if (dueDate != null && dueDate!.isNotEmpty) 'due_date': dueDate,
      'consent_photo': consentPhoto,
      'is_multiple': isMultiple,
    };
  }

  static bool _parseBool(dynamic value) {
    if (value == true || value == 1) return true;
    if (value is String) {
      final s = value.trim().toLowerCase();
      return s == 'true' || s == '1' || s == 't' || s == 'yes';
    }
    return false;
  }

  static String? _dateString(dynamic v) {
    if (v == null) return null;
    if (v is String) return v.split('T').first;
    return v.toString().split('T').first;
  }
}

class EnfantParentLink {
  final String parentId;
  final String? parentName;

  EnfantParentLink({required this.parentId, this.parentName});

  EnfantParentLink copyWith({String? parentId, String? parentName}) {
    return EnfantParentLink(
      parentId: parentId ?? this.parentId,
      parentName: parentName ?? this.parentName,
    );
  }

  factory EnfantParentLink.fromJson(Map<String, dynamic> json) {
    final parentId =
        (json['parentId'] ?? json['id_parent'] ?? '').toString();
    String? name;
    final parent = json['parent'];
    if (parent is Map<String, dynamic>) {
      final user = parent['user'];
      if (user is Map<String, dynamic>) {
        final u = AppUser.fromJson(user);
        name = u.fullName.isNotEmpty ? u.fullName : u.email;
      } else {
        // Parfois le parent est aplati (prenom/nom) sans nested user.
        final prenom = (parent['prenom'] ?? parent['first_name'] ?? '').toString().trim();
        final nom = (parent['nom'] ?? parent['last_name'] ?? '').toString().trim();
        final flat = '$prenom $nom'.trim();
        if (flat.isNotEmpty) name = flat;
      }
    }
    return EnfantParentLink(
      parentId: parentId,
      parentName: name,
    );
  }
}
