import 'package:flutter/material.dart';
import 'package:p_tits_pas/models/assistante_maternelle_model.dart';
import 'package:p_tits_pas/models/enfant_admin_model.dart';
import 'package:p_tits_pas/services/api/api_config.dart';
import 'package:p_tits_pas/services/auth_service.dart';
import 'package:p_tits_pas/services/user_service.dart';
import 'package:p_tits_pas/utils/date_display_utils.dart';
import 'package:p_tits_pas/utils/enfant_status_utils.dart';
import 'package:p_tits_pas/widgets/admin/common/admin_am_edit_modal.dart';
import 'package:p_tits_pas/widgets/admin/common/admin_am_photo_frame.dart';
import 'package:p_tits_pas/widgets/admin/common/admin_parent_edit_modal.dart';
import 'package:p_tits_pas/widgets/admin/common/validation_detail_section.dart';
import 'package:p_tits_pas/widgets/admin/validation_modal_theme.dart';
import 'package:p_tits_pas/widgets/common/auth_network_image.dart';

/// Fiche enfant consultation / édition (ticket #138) — format paysage comme fiche AM.
class AdminChildDetailModal extends StatefulWidget {
  final EnfantAdminModel enfant;
  final VoidCallback? onSaved;
  final VoidCallback? onDeleted;

  const AdminChildDetailModal({
    super.key,
    required this.enfant,
    this.onSaved,
    this.onDeleted,
  });

  @override
  State<AdminChildDetailModal> createState() => _AdminChildDetailModalState();
}

class _AdminChildDetailModalState extends State<AdminChildDetailModal> {
  late final TextEditingController _prenomCtrl;
  late final TextEditingController _nomCtrl;
  late final TextEditingController _birthCtrl;
  late final TextEditingController _dueCtrl;
  late String _status;
  late String _gender;
  late bool _consentPhoto;
  late bool _isMultiple;
  bool _dirty = false;
  bool _saving = false;
  bool _deleting = false;
  bool _loadingAm = true;
  String? _currentUserRole;
  AssistanteMaternelleModel? _linkedAm;
  /// AM rattachée au chargement (pour sync différé au Sauvegarder).
  String? _baselineAmUserId;

  static const double _modalWidth = 930;
  static const double _mainRowHeight = 380;
  static const double _placementHeight = 96;
  static const double _fieldHeight = 44;
  static const double _photoProGap = 24;
  static const double _proColumnMinWidth = 260;
  static const double _photoColumnMinWidth = 160;
  static const double _photoColumnMaxWidth = 280;
  static const List<int> _fieldsRowLayout = [2, 2, 1];

  bool get _isUnborn => _status == 'a_naitre';
  bool get _isScolarise => _status == 'scolarise';
  bool get _isSansGarde => _status == 'sans_garde';
  bool get _showsAmPlacement => !_isScolarise;

  List<String> get _availableGenders =>
      _isUnborn ? const ['H', 'F', 'Autre'] : const ['H', 'F'];

  TextEditingController get _activeDateCtrl =>
      _isUnborn ? _dueCtrl : _birthCtrl;

  String get _dateFieldLabel =>
      _isUnborn ? 'Date prévisionnelle' : 'Date de naissance';

  bool get _canDelete =>
      (_currentUserRole ?? '').toLowerCase() == 'super_admin';

  bool get _busy => _saving || _deleting;

  @override
  void initState() {
    super.initState();
    final e = widget.enfant;
    _prenomCtrl = TextEditingController(text: e.firstName ?? '');
    _nomCtrl = TextEditingController(text: e.lastName ?? '');
    _birthCtrl = TextEditingController(
      text: formatIsoDateFr(e.birthDate, ifEmpty: ''),
    );
    _dueCtrl = TextEditingController(
      text: formatIsoDateFr(e.dueDate, ifEmpty: ''),
    );
    _status = normalizeEnfantStatus(e.status);
    if (!enfantStatusValues.contains(_status)) {
      _status = 'sans_garde';
    }
    _gender = _normalizeGender(e.gender, allowUnknown: _isUnborn);
    _consentPhoto = e.consentPhoto;
    _isMultiple = e.isMultiple;
    for (final c in [_prenomCtrl, _nomCtrl, _birthCtrl, _dueCtrl]) {
      c.addListener(_markDirty);
    }
    _prenomCtrl.addListener(_onNameChanged);
    _nomCtrl.addListener(_onNameChanged);
    _loadCurrentUserRole();
    _loadLinkedAm();
  }

  void _onNameChanged() => setState(() {});

  Future<void> _loadLinkedAm() async {
    setState(() => _loadingAm = true);
    try {
      final am = await UserService.findAmForEnfant(widget.enfant.id);
      if (!mounted) return;
      setState(() {
        _linkedAm = am;
        _baselineAmUserId = am?.user.id;
        _loadingAm = false;
      });
    } catch (_) {
      if (!mounted) return;
      setState(() {
        _baselineAmUserId = null;
        _loadingAm = false;
      });
    }
  }

  Future<void> _loadCurrentUserRole() async {
    final cached = await AuthService.getCurrentUser();
    if (!mounted) return;
    if (cached != null) {
      setState(() => _currentUserRole = cached.role);
      return;
    }
    final refreshed = await AuthService.refreshCurrentUser();
    if (!mounted || refreshed == null) return;
    setState(() => _currentUserRole = refreshed.role);
  }

  @override
  void dispose() {
    for (final c in [_prenomCtrl, _nomCtrl, _birthCtrl, _dueCtrl]) {
      c.dispose();
    }
    super.dispose();
  }

  static String _normalizeGender(String? raw, {required bool allowUnknown}) {
    final g = (raw ?? '').trim();
    if (g == 'M') return 'H';
    if (g == 'F' || g == 'H') return g;
    if (g == 'Autre' && allowUnknown) return 'Autre';
    return 'H';
  }

  void _coerceGenderForStatus() {
    if (!_availableGenders.contains(_gender)) {
      _gender = 'H';
    }
  }

  void _markDirty() {
    if (!_dirty) setState(() => _dirty = true);
  }

  String? _dateToIso(String text) => parseFrDateToIso(text);

  String _headerTitle() {
    final fn = _prenomCtrl.text.trim();
    final ln = _nomCtrl.text.trim();
    if (fn.isEmpty && ln.isEmpty) {
      final fallback = widget.enfant.fullName.trim();
      return fallback.isNotEmpty ? fallback : 'Enfant';
    }
    return '$fn $ln'.trim();
  }

  List<EnfantParentLink> get _parentLinks => widget.enfant.parentLinks
      .where((l) => l.parentId.trim().isNotEmpty)
      .toList();

  Future<void> _openParent(EnfantParentLink link) async {
    if (_busy) return;
    final id = link.parentId.trim();
    if (id.isEmpty) return;

    try {
      final parent = await UserService.getParent(id);
      if (!mounted) return;
      await showDialog<void>(
        context: context,
        builder: (ctx) => AdminParentEditModal(
          parent: parent,
          onSaved: () => widget.onSaved?.call(),
        ),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(e.toString().replaceFirst('Exception: ', ''))),
      );
    }
  }

  Widget? _parentsSubtitle() {
    final links = _parentLinks;
    if (links.isEmpty) return null;

    return Wrap(
      crossAxisAlignment: WrapCrossAlignment.center,
      children: [
        const Text(
          'Responsables : ',
          style: TextStyle(fontSize: 13, color: Colors.black54),
        ),
        for (var i = 0; i < links.length; i++) ...[
          if (i > 0)
            const Text(
              ', ',
              style: TextStyle(fontSize: 13, color: Colors.black54),
            ),
          _parentNameLink(links[i]),
        ],
      ],
    );
  }

  Widget _parentNameLink(EnfantParentLink link) {
    final name = (link.parentName ?? '').trim();
    final label = name.isNotEmpty ? name : 'Parent rattaché';
    return InkWell(
      onTap: _busy ? null : () => _openParent(link),
      borderRadius: BorderRadius.circular(4),
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 2),
        child: Text(
          label,
          style: TextStyle(
            fontSize: 13,
            fontWeight: FontWeight.w600,
            color: ValidationModalTheme.primaryActionBackground,
            decoration: TextDecoration.underline,
            decorationColor: ValidationModalTheme.primaryActionBackground
                .withValues(alpha: 0.5),
          ),
        ),
      ),
    );
  }

  Future<void> _save() async {
    if (!_dirty) return;
    setState(() => _saving = true);
    try {
      await _syncAmPlacement();

      await UserService.updateEnfant(
        enfantId: widget.enfant.id,
        body: {
          'first_name': _prenomCtrl.text.trim(),
          'last_name': _nomCtrl.text.trim(),
          'status': _status,
          'gender': _gender,
          if (_isUnborn)
            if (_dateToIso(_dueCtrl.text) != null)
              'due_date': _dateToIso(_dueCtrl.text)
          else if (_dateToIso(_birthCtrl.text) != null)
            'birth_date': _dateToIso(_birthCtrl.text),
          'consent_photo': _consentPhoto,
          'is_multiple': _isMultiple,
        },
      );
      if (!mounted) return;
      setState(() {
        _dirty = false;
        _saving = false;
        _baselineAmUserId = _linkedAm?.user.id;
      });
      widget.onSaved?.call();
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Fiche enfant enregistrée')),
      );
    } catch (e) {
      if (!mounted) return;
      setState(() => _saving = false);
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(e.toString().replaceFirst('Exception: ', ''))),
      );
    }
  }

  /// Applique rattachement / détachement AM (différé jusqu'au Sauvegarder).
  Future<void> _syncAmPlacement() async {
    final baselineId = _baselineAmUserId;
    final currentId = _linkedAm?.user.id;

    if (baselineId != null && baselineId != currentId) {
      await UserService.detachEnfantFromAm(
        amUserId: baselineId,
        enfantId: widget.enfant.id,
      );
    }
    if (currentId != null && currentId != baselineId) {
      await UserService.attachEnfantToAm(
        amUserId: currentId,
        enfantId: widget.enfant.id,
      );
    }
  }

  Future<void> _delete() async {
    if (!_canDelete || _deleting) return;

    final name = _headerTitle();
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Supprimer l\'enfant'),
        content: Text(
          'Supprimer définitivement la fiche de $name ?\n'
          'Cette action est irréversible.',
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(ctx, false),
            child: const Text('Annuler'),
          ),
          ElevatedButton(
            onPressed: () => Navigator.pop(ctx, true),
            style: ElevatedButton.styleFrom(
              backgroundColor: Colors.red.shade700,
              foregroundColor: Colors.white,
            ),
            child: const Text('Supprimer'),
          ),
        ],
      ),
    );
    if (confirmed != true || !mounted) return;

    setState(() => _deleting = true);
    try {
      await UserService.deleteEnfant(widget.enfant.id);
      if (!mounted) return;
      widget.onDeleted?.call();
      widget.onSaved?.call();
      Navigator.of(context).pop();
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Fiche enfant supprimée')),
      );
    } catch (e) {
      if (!mounted) return;
      setState(() => _deleting = false);
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(e.toString().replaceFirst('Exception: ', ''))),
      );
    }
  }

  Future<void> _openLinkedAm() async {
    final am = _linkedAm;
    if (am == null) return;
    await showDialog<void>(
      context: context,
      builder: (ctx) => AdminAmEditModal(
        assistante: am,
        onSaved: () async {
          await _reloadPlacementFromServer();
          widget.onSaved?.call();
        },
      ),
    );
  }

  /// Recharge AM + statut après une modale externe (ex. fiche AM).
  Future<void> _reloadPlacementFromServer() async {
    try {
      final results = await Future.wait([
        UserService.findAmForEnfant(widget.enfant.id),
        UserService.getEnfant(widget.enfant.id),
      ]);
      if (!mounted) return;
      final am = results[0] as AssistanteMaternelleModel?;
      final enfant = results[1] as EnfantAdminModel;
      setState(() {
        _linkedAm = am;
        _baselineAmUserId = am?.user.id;
        _status = normalizeEnfantStatus(enfant.status);
        if (!enfantStatusValues.contains(_status)) {
          _status = 'sans_garde';
        }
        _coerceGenderForStatus();
      });
    } catch (_) {
      if (!mounted) return;
      await _loadLinkedAm();
    }
  }

  Future<void> _attachAm() async {
    List<AssistanteMaternelleModel> all;
    try {
      all = await UserService.getAssistantesMaternelles();
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(e.toString().replaceFirst('Exception: ', ''))),
      );
      return;
    }

    if (_linkedAm != null && !_isSansGarde) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Détachez l\'assistante actuelle avant d\'en choisir une autre'),
        ),
      );
      return;
    }

    if (all.isEmpty) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Aucune assistante maternelle disponible')),
      );
      return;
    }

    if (!mounted) return;
    final selected = await showDialog<AssistanteMaternelleModel>(
      context: context,
      builder: (ctx) => SimpleDialog(
        title: const Text('Choisir une assistante maternelle'),
        children: all
            .map(
              (am) => SimpleDialogOption(
                onPressed: () => Navigator.pop(ctx, am),
                child: Text(am.user.fullName),
              ),
            )
            .toList(),
      ),
    );
    if (selected == null || !mounted) return;

    setState(() {
      _linkedAm = selected;
      if (_status == 'sans_garde') {
        _status = 'garde';
      }
      _dirty = true;
    });
  }

  Future<void> _detachAm() async {
    final am = _linkedAm;
    if (am == null) return;

    final confirmed = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Détacher l\'assistante'),
        content: Text(
          'Retirer ${am.user.fullName} de la garde de cet enfant ?\n'
          '(Effectif après Sauvegarder.)',
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(ctx, false),
            child: const Text('Annuler'),
          ),
          ElevatedButton(
            onPressed: () => Navigator.pop(ctx, true),
            style: ValidationModalTheme.primaryElevatedStyle,
            child: const Text('Détacher'),
          ),
        ],
      ),
    );
    if (confirmed != true || !mounted) return;

    setState(() {
      _linkedAm = null;
      if (_status != 'a_naitre' && _status != 'scolarise') {
        _status = 'sans_garde';
      }
      _dirty = true;
    });
  }

  /// Passe en « Sans garde » : cadre vide local (détachement au Sauvegarder).
  void _applySansGardeStatus() {
    if (_linkedAm == null) return;
    setState(() {
      _linkedAm = null;
      _dirty = true;
    });
  }

  InputDecoration _inputDecoration({String? hint}) {
    return ValidationFieldDecoration.input(hint: hint).copyWith(
      isDense: false,
      contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
    );
  }

  Widget _dropdownField({
    Key? key,
    required String value,
    required List<MapEntry<String, String>> items,
    required ValueChanged<String> onChanged,
  }) {
    final safeValue =
        items.any((e) => e.key == value) ? value : items.first.key;
    return SizedBox(
      height: _fieldHeight,
      child: DropdownButtonFormField<String>(
        key: key,
        value: safeValue,
        isExpanded: true,
        decoration: _inputDecoration(),
      items: items
          .map((e) => DropdownMenuItem(value: e.key, child: Text(e.value)))
          .toList(),
      onChanged: _busy ? null : (v) {
        if (v != null) onChanged(v);
      },
      ),
    );
  }

  Widget _textField(TextEditingController controller, {String? hint, Key? key}) {
    return SizedBox(
      height: _fieldHeight,
      child: TextField(
        key: key,
        controller: controller,
        textAlignVertical: TextAlignVertical.center,
        style: const TextStyle(color: Colors.black87, fontSize: 14),
        decoration: _inputDecoration(hint: hint),
      ),
    );
  }

  Widget _fieldsGrid() {
    return ValidationEditableSection(
      rowLayout: _fieldsRowLayout,
      fields: [
        ValidationLabeledField(
          label: 'Prénom',
          field: _textField(_prenomCtrl),
        ),
        ValidationLabeledField(
          label: 'Nom',
          field: _textField(_nomCtrl),
        ),
        ValidationLabeledField(
          label: _dateFieldLabel,
          field: _textField(
            _activeDateCtrl,
            hint: 'jj/mm/aaaa',
            key: ValueKey(_status),
          ),
        ),
        ValidationLabeledField(
          label: 'Statut',
          field: _dropdownField(
            value: _status,
            items: enfantStatusValues
                .map(
                  (s) => MapEntry(
                    s,
                    enfantStatusLabel(s, gender: _gender),
                  ),
                )
                .toList(),
            onChanged: (v) {
              setState(() {
                _status = v;
                _coerceGenderForStatus();
                _dirty = true;
              });
              if (v == 'sans_garde') {
                _applySansGardeStatus();
              }
            },
          ),
        ),
        ValidationLabeledField(
          label: 'Genre',
          field: _dropdownField(
            key: ValueKey('genre-$_status'),
            value: _gender,
            items: _availableGenders
                .map((g) => MapEntry(g, _genderLabel(g)))
                .toList(),
            onChanged: (v) => setState(() {
              _gender = v;
              _dirty = true;
            }),
          ),
        ),
      ],
    );
  }

  Widget _consentPhotoSwitch() {
    return SwitchListTile(
      contentPadding: EdgeInsets.zero,
      dense: true,
      visualDensity: VisualDensity.compact,
      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
      title: const Text(
        'Consentement photo',
        style: TextStyle(fontSize: 13),
      ),
      value: _consentPhoto,
      onChanged: _busy
          ? null
          : (v) => setState(() {
                _consentPhoto = v;
                _dirty = true;
              }),
    );
  }

  Widget _mainRow() {
    return LayoutBuilder(
      builder: (context, c) {
        final maxRowW = c.maxWidth;
        final maxRowH = c.maxHeight;
        final idealPhotoW =
            maxRowH * AdminAmPhotoFrame.idPhotoAspectRatio + 16;
        final maxPhotoW = (maxRowW - _photoProGap - _proColumnMinWidth)
            .clamp(0.0, double.infinity);
        var photoW = idealPhotoW.clamp(_photoColumnMinWidth, _photoColumnMaxWidth);
        if (photoW > maxPhotoW) photoW = maxPhotoW;

        return Row(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(
              width: photoW,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  Expanded(
                    child: AdminAmPhotoFrame(
                      photoUrl: widget.enfant.photoUrl,
                    ),
                  ),
                  const SizedBox(height: 8),
                  _consentPhotoSwitch(),
                ],
              ),
            ),
            const SizedBox(width: _photoProGap),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  _fieldsGrid(),
                  Expanded(
                    child: Padding(
                      padding: const EdgeInsets.only(top: 16),
                      child: Align(
                        alignment: Alignment.bottomCenter,
                        child: _placementBlock(),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        );
      },
    );
  }

  Widget _scolariseCard() {
    return Container(
      height: _placementHeight,
      width: double.infinity,
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [
            const Color(0xFFE8F4FD),
            const Color(0xFFDCEEFB),
          ],
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
        ),
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: const Color(0xFF90CAF9)),
      ),
      padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
      child: Row(
        children: [
          Container(
            width: 56,
            height: 56,
            decoration: BoxDecoration(
              color: Colors.white.withValues(alpha: 0.85),
              borderRadius: BorderRadius.circular(12),
            ),
            child: Icon(
              Icons.school_rounded,
              size: 32,
              color: Colors.blue.shade700,
            ),
          ),
          const SizedBox(width: 16),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  enfantStatusLabel('scolarise', gender: _gender),
                  style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.w700,
                    color: Colors.blue.shade900,
                  ),
                ),
                const SizedBox(height: 4),
                Text(
                  'Enfant scolarisé — pas de garde chez une assistante maternelle',
                  style: TextStyle(
                    fontSize: 13,
                    color: Colors.blue.shade800.withValues(alpha: 0.85),
                  ),
                ),
              ],
            ),
          ),
          Icon(Icons.auto_stories_outlined, size: 28, color: Colors.blue.shade400),
        ],
      ),
    );
  }

  Widget _emptyAmSlot() {
    return Material(
      color: Colors.transparent,
      child: InkWell(
        onTap: _busy ? null : _attachAm,
        borderRadius: BorderRadius.circular(10),
        child: Container(
          height: _placementHeight,
          width: double.infinity,
          decoration: BoxDecoration(
            color: Colors.grey.shade50,
            borderRadius: BorderRadius.circular(10),
            border: Border.all(color: Colors.grey.shade300),
          ),
          padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
          child: Row(
            children: [
              Container(
                width: 56,
                height: 56,
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(12),
                  border: Border.all(color: Colors.grey.shade200),
                ),
                child: Icon(
                  Icons.face_outlined,
                  size: 30,
                  color: Colors.grey.shade400,
                ),
              ),
              const SizedBox(width: 16),
              Expanded(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Aucune assistante maternelle',
                      style: TextStyle(
                        fontSize: 15,
                        fontWeight: FontWeight.w700,
                        color: Colors.grey.shade800,
                      ),
                    ),
                    const SizedBox(height: 4),
                    Text(
                      'Cliquer pour choisir une assistante',
                      style: TextStyle(
                        fontSize: 13,
                        color: Colors.grey.shade600,
                      ),
                    ),
                  ],
                ),
              ),
              Icon(Icons.add_circle_outline, color: Colors.grey.shade500),
            ],
          ),
        ),
      ),
    );
  }

  Widget _linkedAmCard() {
    final am = _linkedAm!;
    final zone = (am.residenceCity ?? '').trim();
    final agrement = (am.approvalNumber ?? '').trim();
    final subtitle = [
      if (zone.isNotEmpty) 'Zone : $zone',
      if (agrement.isNotEmpty) 'Agrément : $agrement',
    ].join('  ·  ');

    return Material(
      color: Colors.transparent,
      child: InkWell(
        onTap: _busy ? null : _openLinkedAm,
        borderRadius: BorderRadius.circular(10),
        child: Container(
          height: _placementHeight,
          width: double.infinity,
          decoration: BoxDecoration(
            color: const Color(0xFFF7F3FC),
            borderRadius: BorderRadius.circular(10),
            border: Border.all(color: const Color(0xFFD4C4EF)),
          ),
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
          child: Row(
            children: [
              _amAvatar(am.user.photoUrl),
              const SizedBox(width: 16),
              Expanded(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      am.user.fullName,
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      style: const TextStyle(
                        fontSize: 15,
                        fontWeight: FontWeight.w700,
                        color: Color(0xFF4A2F7A),
                      ),
                    ),
                    if (subtitle.isNotEmpty) ...[
                      const SizedBox(height: 4),
                      Text(
                        subtitle,
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                        style: TextStyle(
                          fontSize: 13,
                          color: Colors.grey.shade700,
                        ),
                      ),
                    ],
                  ],
                ),
              ),
              IconButton(
                icon: const Icon(Icons.open_in_new, size: 20),
                tooltip: 'Ouvrir la fiche AM',
                onPressed: _busy ? null : _openLinkedAm,
              ),
              IconButton(
                icon: Icon(Icons.link_off, size: 20, color: Colors.orange.shade800),
                tooltip: 'Détacher',
                onPressed: _busy ? null : _detachAm,
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _amAvatar(String? photoUrl) {
    const size = 56.0;
    const bg = Color(0xFFEDE5FA);
    const iconColor = Color(0xFF6B3FA0);
    final url = ApiConfig.absoluteMediaUrl(photoUrl);

    if (url.isEmpty) {
      return Container(
        width: size,
        height: size,
        decoration: BoxDecoration(
          color: bg,
          borderRadius: BorderRadius.circular(12),
        ),
        child: const Icon(Icons.face, size: 30, color: iconColor),
      );
    }

    return ClipRRect(
      borderRadius: BorderRadius.circular(12),
      child: AuthNetworkImage(
        url: url,
        width: size,
        height: size,
        fit: BoxFit.cover,
        errorBuilder: (_, __, ___) => Container(
          width: size,
          height: size,
          color: bg,
          child: const Icon(Icons.face, size: 30, color: iconColor),
        ),
      ),
    );
  }

  String get _placementTitle =>
      _isScolarise ? 'Scolarisation' : 'Assistante maternelle';

  Widget _placementBlock() {
    return Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        Text(
          _placementTitle,
          style: TextStyle(
            fontSize: 14,
            fontWeight: FontWeight.w600,
            color: Colors.grey.shade800,
          ),
        ),
        const SizedBox(height: 8),
        _placementSection(),
      ],
    );
  }

  Widget _placementSection() {
    if (!_showsAmPlacement) return _scolariseCard();

    if (_loadingAm) {
      return SizedBox(
        height: _placementHeight,
        width: double.infinity,
        child: Center(
          child: SizedBox(
            width: 24,
            height: 24,
            child: CircularProgressIndicator(
              strokeWidth: 2,
              color: Colors.grey.shade600,
            ),
          ),
        ),
      );
    }

    // Sans garde : toujours le cadre vide (comme après détachement AM).
    if (_isSansGarde) return _emptyAmSlot();
    if (_linkedAm != null) return _linkedAmCard();
    return _emptyAmSlot();
  }

  Widget _buildFooter() {
    return Row(
      children: [
        if (_canDelete)
          OutlinedButton(
            onPressed: _busy ? null : _delete,
            style: OutlinedButton.styleFrom(
              foregroundColor: Colors.red.shade700,
            ),
            child: _deleting
                ? const SizedBox(
                    width: 16,
                    height: 16,
                    child: CircularProgressIndicator(strokeWidth: 2),
                  )
                : const Text('Supprimer'),
          ),
        const Spacer(),
        TextButton(
          onPressed: _busy ? null : () => Navigator.of(context).pop(),
          child: const Text('Fermer'),
        ),
        const SizedBox(width: 12),
        ElevatedButton(
          style: ValidationModalTheme.primaryElevatedStyle,
          onPressed: !_dirty || _busy ? null : _save,
          child: _saving
              ? const SizedBox(
                  width: 18,
                  height: 18,
                  child: CircularProgressIndicator(
                    strokeWidth: 2,
                    color: Colors.white,
                  ),
                )
              : Text(_dirty ? 'Sauvegarder' : 'Aucune modification'),
        ),
      ],
    );
  }

  String _genderLabel(String gender) {
    switch (gender) {
      case 'H':
        return 'Garçon';
      case 'F':
        return 'Fille';
      case 'Autre':
        return 'Inconnu';
      default:
        return gender;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Dialog(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
      child: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: _modalWidth),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Padding(
              padding: const EdgeInsets.fromLTRB(18, 16, 4, 0),
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          _headerTitle(),
                          style: const TextStyle(
                            fontSize: 18,
                            fontWeight: FontWeight.w700,
                          ),
                        ),
                        if (_parentsSubtitle() != null) ...[
                          const SizedBox(height: 4),
                          _parentsSubtitle()!,
                        ],
                      ],
                    ),
                  ),
                  IconButton(
                    padding: EdgeInsets.zero,
                    constraints: const BoxConstraints(
                      minWidth: 40,
                      minHeight: 40,
                    ),
                    icon: const Icon(Icons.close),
                    onPressed: _busy ? null : () => Navigator.of(context).pop(),
                    tooltip: 'Fermer',
                  ),
                ],
              ),
            ),
            const Divider(height: 1),
            Padding(
              padding: const EdgeInsets.fromLTRB(20, 12, 20, 12),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  SizedBox(height: _mainRowHeight, child: _mainRow()),
                  const SizedBox(height: 12),
                  _buildFooter(),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
