/// Bottom sheet d'ajout de membre — Design UnionFlow V2
library add_member_dialog;

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:get_it/get_it.dart';
import 'package:intl/intl.dart';
import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../authentication/data/models/user_role.dart';
import '../../../authentication/presentation/bloc/auth_bloc.dart';
import '../../../organizations/domain/repositories/organization_repository.dart';
import '../../../../shared/design_system/tokens/unionflow_colors.dart';
import '../../bloc/membres_bloc.dart';
import '../../bloc/membres_event.dart';
import '../../bloc/membres_state.dart';
import '../../data/models/membre_complete_model.dart';

/// Ouvre le bottom sheet d'ajout de membre.
/// Doit être appelé depuis un contexte qui a accès à [MembresBloc] et [AuthBloc].
void showAddMemberSheet(BuildContext context) {
  final membresBloc = context.read<MembresBloc>();
  final authState = context.read<AuthBloc>().state;

  showModalBottomSheet<void>(
    context: context,
    isScrollControlled: true,
    backgroundColor: Colors.transparent,
    builder: (_) => BlocProvider.value(
      value: membresBloc,
      child: AddMemberSheet(
        authState: authState,
        onCreated: (membre) => _showPasswordDialog(context, membre),
      ),
    ),
  );
}

// ─── Helpers credentials ─────────────────────────────────────────────────────

/// Formate le bloc de credentials en texte brut partageable
String _credentialText(String nomComplet, String email, String password) =>
    '''
Identifiants UnionFlow
─────────────────────────────
Membre        $nomComplet
Email         $email
Mot de passe  $password
─────────────────────────────
⚠ Changez le mot de passe à la première connexion.
'''
        .trim();

// ─── Dialog credentials ───────────────────────────────────────────────────────

/// Point d'entrée public — utilisable depuis n'importe quel widget (ex: reset mot de passe)
void showCredentialsDialog(BuildContext context, MembreCompletModel membre) =>
    _showPasswordDialog(context, membre);

void _showPasswordDialog(BuildContext context, MembreCompletModel membre) {
  final username = membre.email;
  final password = membre.motDePasseTemporaire;
  final nomComplet = '${membre.prenom} ${membre.nom}';
  final credText = password != null
      ? _credentialText(nomComplet, username, password)
      : null;

  showDialog<void>(
    context: context,
    barrierDismissible: false,
    builder: (dialogCtx) => _CredentialsDialog(
      membre: membre,
      username: username,
      password: password,
      credText: credText,
    ),
  );
}

// ─── Widget dialog ────────────────────────────────────────────────────────────

class _CredentialsDialog extends StatefulWidget {
  final MembreCompletModel membre;
  final String username;
  final String? password;
  final String? credText;

  const _CredentialsDialog({
    required this.membre,
    required this.username,
    this.password,
    this.credText,
  });

  @override
  State<_CredentialsDialog> createState() => _CredentialsDialogState();
}

class _CredentialsDialogState extends State<_CredentialsDialog> {
  bool _copied = false;

  void _copyAll() {
    if (widget.credText == null) return;
    Clipboard.setData(ClipboardData(text: widget.credText!));
    setState(() => _copied = true);
    Future.delayed(const Duration(seconds: 2),
        () { if (mounted) setState(() => _copied = false); });
  }

  Future<void> _shareViaSms() async {
    if (widget.credText == null) return;
    await Share.share(widget.credText!, subject: 'Identifiants UnionFlow');
  }

  Future<void> _shareViaEmail() async {
    if (widget.credText == null) return;
    final subject = Uri.encodeComponent('Vos identifiants UnionFlow');
    final body = Uri.encodeComponent(widget.credText!);
    final uri = Uri.parse('mailto:${widget.membre.email}?subject=$subject&body=$body');
    if (await canLaunchUrl(uri)) {
      await launchUrl(uri);
    }
  }

  @override
  Widget build(BuildContext context) {
    final nomComplet = '${widget.membre.prenom} ${widget.membre.nom}';

    return Dialog(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
      insetPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 40),
      child: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(20),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // ── Header ──────────────────────────────────────────────
              Row(
                children: [
                  Container(
                    padding: const EdgeInsets.all(8),
                    decoration: BoxDecoration(
                      color: UnionFlowColors.successPale,
                      borderRadius: BorderRadius.circular(10),
                    ),
                    child: const Icon(Icons.check_circle_rounded,
                        color: UnionFlowColors.success, size: 22),
                  ),
                  const SizedBox(width: 12),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        const Text('Compte créé',
                            style: TextStyle(
                                fontSize: 15,
                                fontWeight: FontWeight.w700,
                                color: UnionFlowColors.textPrimary)),
                        Text(nomComplet,
                            style: const TextStyle(
                                fontSize: 12,
                                color: UnionFlowColors.textSecondary)),
                      ],
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 16),

              // ── Cas sans mot de passe ────────────────────────────────
              if (widget.password == null) ...[
                Container(
                  padding: const EdgeInsets.all(12),
                  decoration: BoxDecoration(
                    color: UnionFlowColors.infoPale,
                    borderRadius: BorderRadius.circular(10),
                    border: Border.all(color: UnionFlowColors.infoLight),
                  ),
                  child: const Row(
                    children: [
                      Icon(Icons.info_outline_rounded,
                          size: 15, color: UnionFlowColors.info),
                      SizedBox(width: 8),
                      Expanded(
                        child: Text(
                          'Provisionnement Keycloak non bloquant — mot de passe à définir manuellement via la console.',
                          style: TextStyle(
                              fontSize: 12,
                              color: UnionFlowColors.textSecondary,
                              height: 1.4),
                        ),
                      ),
                    ],
                  ),
                ),
              ],

              // ── Bloc credentials ─────────────────────────────────────
              if (widget.password != null) ...[
                const Text(
                  'IDENTIFIANTS À COMMUNIQUER',
                  style: TextStyle(
                      fontSize: 10,
                      fontWeight: FontWeight.w700,
                      color: UnionFlowColors.textTertiary,
                      letterSpacing: 1),
                ),
                const SizedBox(height: 8),

                // Bloc code sombre
                Container(
                  width: double.infinity,
                  decoration: BoxDecoration(
                    color: const Color(0xFF0D1428), // navy sombre terminal
                    borderRadius: BorderRadius.circular(12),
                    border: Border.all(color: const Color(0xFF2D3554)),
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      // Barre titre du bloc
                      Container(
                        padding: const EdgeInsets.fromLTRB(14, 10, 10, 10),
                        decoration: const BoxDecoration(
                          color: Color(0xFF060A14),
                          borderRadius:
                              BorderRadius.vertical(top: Radius.circular(11)),
                          border: Border(
                              bottom: BorderSide(color: Color(0xFF2D3554))),
                        ),
                        child: Row(
                          children: [
                            const Icon(Icons.terminal_rounded,
                                size: 13, color: Color(0xFF297FFF)),
                            const SizedBox(width: 6),
                            const Text(
                              'credentials.txt',
                              style: TextStyle(
                                  fontSize: 11,
                                  fontWeight: FontWeight.w600,
                                  color: Color(0xFF69B7FF),
                                  fontFamily: 'monospace'),
                            ),
                            const Spacer(),
                            GestureDetector(
                              onTap: _copyAll,
                              child: AnimatedSwitcher(
                                duration: const Duration(milliseconds: 200),
                                child: _copied
                                    ? const Row(
                                        key: ValueKey('copied'),
                                        children: [
                                          Icon(Icons.check_rounded,
                                              size: 13,
                                              color: Color(0xFF22C55E)),
                                          SizedBox(width: 4),
                                          Text('Copié',
                                              style: TextStyle(
                                                  fontSize: 11,
                                                  color: Color(0xFF22C55E),
                                                  fontFamily: 'monospace')),
                                        ],
                                      )
                                    : const Row(
                                        key: ValueKey('copy'),
                                        children: [
                                          Icon(Icons.copy_rounded,
                                              size: 13,
                                              color: Color(0xFF69B7FF)),
                                          SizedBox(width: 4),
                                          Text('Copier tout',
                                              style: TextStyle(
                                                  fontSize: 11,
                                                  color: Color(0xFF69B7FF),
                                                  fontFamily: 'monospace')),
                                        ],
                                      ),
                              ),
                            ),
                          ],
                        ),
                      ),

                      // Corps du bloc
                      Padding(
                        padding: const EdgeInsets.all(16),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            _credLine('# Identifiants UnionFlow',
                                color: const Color(0xFF5C8DB5),
                                isComment: true),
                            const SizedBox(height: 8),
                            _credLine('email       ',
                                value: widget.username,
                                labelColor: const Color(0xFF9CDCFE),
                                valueColor: const Color(0xFFCE9178)),
                            const SizedBox(height: 6),
                            _credLine('mot_de_passe',
                                value: widget.password!,
                                labelColor: const Color(0xFF9CDCFE),
                                valueColor: const Color(0xFFD4D4D4),
                                isPassword: true),
                            const SizedBox(height: 12),
                            _credLine(
                                '# Changez le mot de passe à la 1ère connexion',
                                color: const Color(0xFF5C8DB5),
                                isComment: true),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
                const SizedBox(height: 16),

                // ── Boutons partage ──────────────────────────────────
                const Text(
                  'PARTAGER LES IDENTIFIANTS',
                  style: TextStyle(
                      fontSize: 10,
                      fontWeight: FontWeight.w700,
                      color: UnionFlowColors.textTertiary,
                      letterSpacing: 1),
                ),
                const SizedBox(height: 8),
                Row(
                  children: [
                    Expanded(
                      child: _shareButton(
                        icon: Icons.sms_rounded,
                        label: 'SMS',
                        color: UnionFlowColors.unionGreen,
                        onTap: _shareViaSms,
                      ),
                    ),
                    const SizedBox(width: 10),
                    Expanded(
                      child: _shareButton(
                        icon: Icons.email_rounded,
                        label: 'Email',
                        color: UnionFlowColors.info,
                        onTap: _shareViaEmail,
                      ),
                    ),
                    const SizedBox(width: 10),
                    Expanded(
                      child: _shareButton(
                        icon: Icons.share_rounded,
                        label: 'Partager',
                        color: UnionFlowColors.amber,
                        onTap: _shareViaSms, // opens share sheet
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 14),

                // ── Note prochaine étape ─────────────────────────────
                Container(
                  padding: const EdgeInsets.symmetric(
                      horizontal: 12, vertical: 10),
                  decoration: BoxDecoration(
                    color: UnionFlowColors.warningPale,
                    borderRadius: BorderRadius.circular(10),
                    border: Border.all(color: UnionFlowColors.warningLight),
                  ),
                  child: const Row(
                    children: [
                      Icon(Icons.info_outline_rounded,
                          size: 14, color: UnionFlowColors.warning),
                      SizedBox(width: 8),
                      Expanded(
                        child: Text(
                          'Pensez à valider l\'adhésion du membre pour activer son accès complet.',
                          style: TextStyle(
                              fontSize: 11,
                              color: UnionFlowColors.textSecondary,
                              height: 1.4),
                        ),
                      ),
                    ],
                  ),
                ),
              ],

              const SizedBox(height: 20),

              // ── Action ───────────────────────────────────────────────
              SizedBox(
                width: double.infinity,
                child: FilledButton(
                  onPressed: () => Navigator.pop(context),
                  style: FilledButton.styleFrom(
                    backgroundColor: UnionFlowColors.unionGreen,
                    padding: const EdgeInsets.symmetric(vertical: 13),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10)),
                  ),
                  child: const Text('Compris',
                      style: TextStyle(fontWeight: FontWeight.w600)),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _credLine(
    String label, {
    String? value,
    Color? color,
    Color? labelColor,
    Color? valueColor,
    bool isComment = false,
    bool isPassword = false,
  }) {
    if (isComment) {
      return Text(
        label,
        style: TextStyle(
            fontFamily: 'monospace',
            fontSize: 11,
            color: color ?? const Color(0xFF5C8DB5),
            height: 1.4),
      );
    }

    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          label,
          style: TextStyle(
              fontFamily: 'monospace',
              fontSize: 13,
              color: labelColor ?? const Color(0xFF9CDCFE),
              fontWeight: FontWeight.w600),
        ),
        const Text('  ',
            style: TextStyle(fontFamily: 'monospace', fontSize: 13)),
        Expanded(
          child: SelectableText(
            value ?? '',
            style: TextStyle(
              fontFamily: 'monospace',
              fontSize: isPassword ? 15 : 13,
              color: valueColor ?? const Color(0xFFD4D4D4),
              fontWeight:
                  isPassword ? FontWeight.w700 : FontWeight.normal,
              letterSpacing: isPassword ? 1.5 : 0,
            ),
          ),
        ),
      ],
    );
  }

  Widget _shareButton({
    required IconData icon,
    required String label,
    required Color color,
    required VoidCallback onTap,
  }) {
    return InkWell(
      onTap: onTap,
      borderRadius: BorderRadius.circular(10),
      child: Container(
        padding: const EdgeInsets.symmetric(vertical: 10),
        decoration: BoxDecoration(
          color: color.withOpacity(0.08),
          borderRadius: BorderRadius.circular(10),
          border: Border.all(color: color.withOpacity(0.25)),
        ),
        child: Column(
          children: [
            Icon(icon, size: 18, color: color),
            const SizedBox(height: 4),
            Text(label,
                style: TextStyle(
                    fontSize: 11,
                    fontWeight: FontWeight.w600,
                    color: color)),
          ],
        ),
      ),
    );
  }
}

// ─── Bottom sheet ─────────────────────────────────────────────────────────────

class AddMemberSheet extends StatefulWidget {
  final AuthState authState;
  final void Function(MembreCompletModel) onCreated;

  const AddMemberSheet({
    super.key,
    required this.authState,
    required this.onCreated,
  });

  @override
  State<AddMemberSheet> createState() => _AddMemberSheetState();
}

class _AddMemberSheetState extends State<AddMemberSheet> {
  final _formKey = GlobalKey<FormState>();

  // Requis
  final _prenomCtrl = TextEditingController();
  final _nomCtrl = TextEditingController();
  final _emailCtrl = TextEditingController();
  DateTime? _dateNaissance;
  bool _dateMissing = false;

  // Optionnels
  final _telephoneCtrl = TextEditingController();
  final _telephoneWaveCtrl = TextEditingController();
  final _professionCtrl = TextEditingController();
  final _nationaliteCtrl = TextEditingController();
  final _numeroIdentiteCtrl = TextEditingController();
  String? _statutMatrimonial;
  String? _typeIdentite;

  bool _showOptional = false;
  bool _isSubmitting = false;
  String? _errorMessage;

  // Sélection organisation (superadmin uniquement)
  String? _selectedOrganisationId;
  String? _selectedOrganisationNom;
  List<Map<String, String>> _organisations = [];
  bool _loadingOrgs = false;

  bool get _isSuperAdmin {
    final auth = widget.authState;
    return auth is AuthAuthenticated &&
        auth.user.primaryRole == UserRole.superAdmin;
  }

  @override
  void initState() {
    super.initState();
    if (_isSuperAdmin) _loadOrganisations();
  }

  Future<void> _loadOrganisations() async {
    setState(() => _loadingOrgs = true);
    try {
      final repo = GetIt.instance<IOrganizationRepository>();
      final orgs = await repo.getOrganizations(page: 0, size: 100);
      if (mounted) {
        setState(() {
          _organisations = orgs
              .where((o) => o.id != null && o.id!.isNotEmpty)
              .map((o) => {'id': o.id!, 'nom': o.nomAffichage})
              .toList();
        });
      }
    } catch (e) {
      // Non bloquant : le sélecteur affichera un message d'erreur
    } finally {
      if (mounted) setState(() => _loadingOrgs = false);
    }
  }

  static const _statutOptions = [
    'CELIBATAIRE',
    'MARIE',
    'DIVORCE',
    'VEUF',
  ];
  static const _statutLabels = {
    'CELIBATAIRE': 'Célibataire',
    'MARIE': 'Marié(e)',
    'DIVORCE': 'Divorcé(e)',
    'VEUF': 'Veuf / Veuve',
  };

  static const _identiteOptions = [
    'CNI',
    'PASSEPORT',
    'PERMIS_CONDUIRE',
    'TITRE_SEJOUR',
  ];
  static const _identiteLabels = {
    'CNI': "Carte Nationale d'Identité",
    'PASSEPORT': 'Passeport',
    'PERMIS_CONDUIRE': 'Permis de conduire',
    'TITRE_SEJOUR': 'Titre de séjour',
  };

  @override
  void dispose() {
    _prenomCtrl.dispose();
    _nomCtrl.dispose();
    _emailCtrl.dispose();
    _telephoneCtrl.dispose();
    _telephoneWaveCtrl.dispose();
    _professionCtrl.dispose();
    _nationaliteCtrl.dispose();
    _numeroIdentiteCtrl.dispose();
    super.dispose();
  }

  String? _resolveOrganisationId() {
    // Superadmin : utilise l'org sélectionnée dans le sélecteur
    if (_isSuperAdmin) return _selectedOrganisationId;

    final auth = widget.authState;
    if (auth is AuthAuthenticated) {
      return auth.user.organizationContexts.isNotEmpty
          ? auth.user.organizationContexts.first.organizationId
          : null;
    }
    if (auth is AuthPendingOnboarding) return auth.organisationId;
    return null;
  }

  void _submit() {
    final formValid = _formKey.currentState!.validate();
    final dateValid = _dateNaissance != null;
    final orgValid = !_isSuperAdmin || _selectedOrganisationId != null;

    setState(() {
      _dateMissing = !dateValid;
      if (!orgValid) _errorMessage = 'Veuillez sélectionner une organisation.';
    });

    if (!formValid || !dateValid || !orgValid) return;

    setState(() {
      _isSubmitting = true;
      _errorMessage = null;
    });

    final membre = MembreCompletModel(
      prenom: _prenomCtrl.text.trim(),
      nom: _nomCtrl.text.trim(),
      email: _emailCtrl.text.trim().toLowerCase(),
      dateNaissance: _dateNaissance,
      telephone: _val(_telephoneCtrl),
      telephoneWave: _val(_telephoneWaveCtrl),
      profession: _val(_professionCtrl),
      nationalite: _val(_nationaliteCtrl),
      statutMatrimonial: _statutMatrimonial,
      typeIdentite: _typeIdentite,
      numeroIdentite: _val(_numeroIdentiteCtrl),
      organisationId: _resolveOrganisationId(),
      statut: StatutMembre.actif,
    );

    context.read<MembresBloc>().add(CreateMembre(membre));
  }

  String? _val(TextEditingController ctrl) {
    final v = ctrl.text.trim();
    return v.isNotEmpty ? v : null;
  }

  @override
  Widget build(BuildContext context) {
    return BlocListener<MembresBloc, MembresState>(
      listener: (ctx, state) {
        if (state is MembresLoading) {
          if (mounted) setState(() => _isSubmitting = true);
        } else if (state is MembreCreated) {
          // Fermer la sheet puis afficher le dialog credentials (gère mot de passe null ou non)
          Navigator.pop(ctx);
          widget.onCreated(state.membre);
        } else if (state is MembresError || state is MembresValidationError) {
          final msg = state is MembresValidationError
              ? state.validationErrors.values.join(' · ')
              : (state as MembresError).message;
          if (mounted) {
            setState(() {
              _isSubmitting = false;
              _errorMessage = msg;
            });
          }
        } else {
          if (mounted) setState(() => _isSubmitting = false);
        }
      },
      child: DraggableScrollableSheet(
        initialChildSize: 0.92,
        maxChildSize: 0.97,
        minChildSize: 0.5,
        builder: (_, scrollCtrl) => Container(
          decoration: const BoxDecoration(
            color: UnionFlowColors.surface,
            borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
          ),
          child: Column(
            children: [
              _buildHandle(),
              _buildHeader(),
              const Divider(height: 1, color: UnionFlowColors.border),
              if (_errorMessage != null) _buildErrorBanner(),
              Expanded(child: _buildForm(scrollCtrl)),
              _buildFooter(),
            ],
          ),
        ),
      ),
    );
  }

  // ── Handle ─────────────────────────────────────────────────────────────────

  Widget _buildHandle() => Center(
        child: Container(
          margin: const EdgeInsets.only(top: 12, bottom: 6),
          width: 36,
          height: 4,
          decoration: BoxDecoration(
            color: UnionFlowColors.border,
            borderRadius: BorderRadius.circular(2),
          ),
        ),
      );

  // ── Header ─────────────────────────────────────────────────────────────────

  Widget _buildHeader() => Padding(
        padding: const EdgeInsets.fromLTRB(20, 6, 8, 14),
        child: Row(
          children: [
            Container(
              width: 38,
              height: 38,
              decoration: BoxDecoration(
                color: UnionFlowColors.unionGreenPale,
                borderRadius: BorderRadius.circular(10),
              ),
              child: const Icon(Icons.person_add_rounded,
                  color: UnionFlowColors.unionGreen, size: 20),
            ),
            const SizedBox(width: 12),
            const Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  'Nouveau membre',
                  style: TextStyle(
                      fontSize: 16,
                      fontWeight: FontWeight.w700,
                      color: UnionFlowColors.textPrimary),
                ),
                Text(
                  'Compte Keycloak provisionné automatiquement',
                  style: TextStyle(
                      fontSize: 11, color: UnionFlowColors.textSecondary),
                ),
              ],
            ),
            const Spacer(),
            IconButton(
              icon: const Icon(Icons.close_rounded,
                  size: 20, color: UnionFlowColors.textSecondary),
              onPressed: () => Navigator.pop(context),
            ),
          ],
        ),
      );

  // ── Bannière erreur ────────────────────────────────────────────────────────

  Widget _buildErrorBanner() => Container(
        margin: const EdgeInsets.fromLTRB(16, 8, 16, 0),
        padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
        decoration: BoxDecoration(
          color: UnionFlowColors.errorPale,
          borderRadius: BorderRadius.circular(10),
          border: Border.all(color: UnionFlowColors.errorLight),
        ),
        child: Row(
          children: [
            const Icon(Icons.error_outline_rounded,
                size: 16, color: UnionFlowColors.error),
            const SizedBox(width: 8),
            Expanded(
              child: Text(
                _errorMessage!,
                style: const TextStyle(
                    fontSize: 12, color: UnionFlowColors.error),
              ),
            ),
          ],
        ),
      );

  // ── Formulaire ─────────────────────────────────────────────────────────────

  Widget _buildOrgPicker() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _sectionLabel('Organisation', required: true),
        const SizedBox(height: 10),
        if (_loadingOrgs)
          const Center(
            child: Padding(
              padding: EdgeInsets.symmetric(vertical: 12),
              child: CircularProgressIndicator(strokeWidth: 2),
            ),
          )
        else if (_organisations.isEmpty)
          Container(
            padding: const EdgeInsets.all(12),
            decoration: BoxDecoration(
              color: UnionFlowColors.warningPale,
              borderRadius: BorderRadius.circular(10),
              border: Border.all(color: UnionFlowColors.warning.withOpacity(0.4)),
            ),
            child: const Text(
              'Aucune organisation disponible. Créez d\'abord une organisation.',
              style: TextStyle(fontSize: 12, color: UnionFlowColors.textSecondary),
            ),
          )
        else
          DropdownButtonFormField<String>(
            value: _selectedOrganisationId,
            decoration: InputDecoration(
              prefixIcon: const Icon(Icons.business_outlined, size: 18,
                  color: UnionFlowColors.textSecondary),
              hintText: 'Sélectionner une organisation',
              hintStyle: const TextStyle(fontSize: 13, color: UnionFlowColors.textTertiary),
              contentPadding: const EdgeInsets.symmetric(vertical: 13, horizontal: 14),
              border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(12),
                borderSide: BorderSide(color: UnionFlowColors.border.withOpacity(0.4)),
              ),
              enabledBorder: OutlineInputBorder(
                borderRadius: BorderRadius.circular(12),
                borderSide: BorderSide(color: UnionFlowColors.border.withOpacity(0.4)),
              ),
              focusedBorder: OutlineInputBorder(
                borderRadius: BorderRadius.circular(12),
                borderSide: const BorderSide(color: UnionFlowColors.unionGreen, width: 1.5),
              ),
              filled: true,
              fillColor: UnionFlowColors.surfaceVariant.withOpacity(0.3),
            ),
            isExpanded: true,
            items: _organisations
                .map((org) => DropdownMenuItem<String>(
                      value: org['id'],
                      child: Text(
                        org['nom']!,
                        style: const TextStyle(fontSize: 13, color: UnionFlowColors.textPrimary),
                        overflow: TextOverflow.ellipsis,
                      ),
                    ))
                .toList(),
            onChanged: (val) => setState(() {
              _selectedOrganisationId = val;
              _selectedOrganisationNom = _organisations
                  .firstWhere((o) => o['id'] == val, orElse: () => {})['nom'];
              _errorMessage = null;
            }),
            validator: (v) => v == null ? 'Obligatoire' : null,
          ),
        const SizedBox(height: 20),
      ],
    );
  }

  Widget _buildForm(ScrollController scrollCtrl) => SingleChildScrollView(
        controller: scrollCtrl,
        padding: const EdgeInsets.fromLTRB(20, 16, 20, 8),
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // Sélecteur organisation — superadmin uniquement
              if (_isSuperAdmin) _buildOrgPicker(),

              // Identité — requis
              _sectionLabel('Identité', required: true),
              const SizedBox(height: 12),

              Row(
                children: [
                  Expanded(
                    child: _field(_prenomCtrl, 'Prénom',
                        required: true, icon: Icons.badge_outlined),
                  ),
                  const SizedBox(width: 10),
                  Expanded(
                    child: _field(_nomCtrl, 'Nom', required: true),
                  ),
                ],
              ),
              const SizedBox(height: 10),

              _field(
                _emailCtrl,
                'Adresse email',
                required: true,
                icon: Icons.alternate_email_rounded,
                keyboard: TextInputType.emailAddress,
                validator: (v) {
                  if (v == null || v.trim().isEmpty) return 'Obligatoire';
                  if (!RegExp(r'^[\w.+\-]+@[\w\-]+\.[a-z]{2,}$')
                      .hasMatch(v.trim())) {
                    return 'Format invalide';
                  }
                  return null;
                },
              ),
              const SizedBox(height: 10),

              _datePicker(),

              const SizedBox(height: 20),

              // Section optionnelle — accordéon
              _optionalToggle(),

              if (_showOptional) ...[
                const SizedBox(height: 16),

                _sectionLabel('Contact'),
                const SizedBox(height: 10),

                _field(_telephoneCtrl, 'Téléphone',
                    icon: Icons.phone_outlined,
                    keyboard: TextInputType.phone,
                    hint: 'ex: +22507XXXXXXXX',
                    maxLength: 20,
                    validator: (v) {
                      if (v == null || v.trim().isEmpty) return null;
                      if (!RegExp(r'^\+[1-9][0-9]{6,14}$').hasMatch(v.trim())) {
                        return 'Format E.164 requis (ex: +22507XXXXXXXX)';
                      }
                      return null;
                    }),
                const SizedBox(height: 10),

                _field(_telephoneWaveCtrl, 'Numéro Wave',
                    icon: Icons.waves_rounded,
                    keyboard: TextInputType.phone,
                    hint: 'ex: +22507XXXXXXXX',
                    maxLength: 20,
                    validator: (v) {
                      if (v == null || v.trim().isEmpty) return null;
                      if (!RegExp(r'^\+[1-9][0-9]{6,14}$').hasMatch(v.trim())) {
                        return 'Format E.164 requis (ex: +22507XXXXXXXX)';
                      }
                      return null;
                    }),

                const SizedBox(height: 18),
                _sectionLabel('Profil'),
                const SizedBox(height: 10),

                _field(_professionCtrl, 'Profession',
                    icon: Icons.work_outline_rounded, maxLength: 100),
                const SizedBox(height: 10),

                _field(_nationaliteCtrl, 'Nationalité',
                    icon: Icons.flag_outlined, maxLength: 100),
                const SizedBox(height: 10),

                _dropdown(
                  label: 'Statut matrimonial',
                  value: _statutMatrimonial,
                  items: _statutOptions,
                  labels: _statutLabels,
                  icon: Icons.favorite_border_rounded,
                  onChanged: (v) => setState(() => _statutMatrimonial = v),
                ),

                const SizedBox(height: 18),
                _sectionLabel("Pièce d'identité"),
                const SizedBox(height: 10),

                _dropdown(
                  label: 'Type de pièce',
                  value: _typeIdentite,
                  items: _identiteOptions,
                  labels: _identiteLabels,
                  icon: Icons.credit_card_rounded,
                  onChanged: (v) => setState(() => _typeIdentite = v),
                ),
                const SizedBox(height: 10),

                _field(_numeroIdentiteCtrl, 'Numéro',
                    icon: Icons.numbers_rounded, maxLength: 100),
              ],

              const SizedBox(height: 12),
            ],
          ),
        ),
      );

  // ── Pied de page ───────────────────────────────────────────────────────────

  Widget _buildFooter() => Container(
        padding: EdgeInsets.fromLTRB(
            20, 12, 20, 16 + MediaQuery.of(context).viewInsets.bottom),
        decoration: const BoxDecoration(
          color: UnionFlowColors.surface,
          border: Border(top: BorderSide(color: UnionFlowColors.border)),
        ),
        child: Row(
          children: [
            Expanded(
              child: OutlinedButton(
                onPressed: _isSubmitting ? null : () => Navigator.pop(context),
                style: OutlinedButton.styleFrom(
                  padding: const EdgeInsets.symmetric(vertical: 14),
                  side: const BorderSide(color: UnionFlowColors.border),
                  foregroundColor: UnionFlowColors.textSecondary,
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10)),
                ),
                child: const Text('Annuler'),
              ),
            ),
            const SizedBox(width: 10),
            Expanded(
              flex: 2,
              child: FilledButton(
                onPressed: _isSubmitting ? null : _submit,
                style: FilledButton.styleFrom(
                  backgroundColor: UnionFlowColors.unionGreen,
                  padding: const EdgeInsets.symmetric(vertical: 14),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10)),
                ),
                child: _isSubmitting
                    ? const SizedBox(
                        width: 18,
                        height: 18,
                        child: CircularProgressIndicator(
                            strokeWidth: 2, color: Colors.white),
                      )
                    : const Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Icon(Icons.person_add_rounded, size: 16),
                          SizedBox(width: 8),
                          Text('Créer le membre',
                              style: TextStyle(fontWeight: FontWeight.w600)),
                        ],
                      ),
              ),
            ),
          ],
        ),
      );

  // ── Composants internes ────────────────────────────────────────────────────

  Widget _sectionLabel(String label, {bool required = false}) => Row(
        children: [
          Text(
            label.toUpperCase(),
            style: const TextStyle(
              fontSize: 10,
              fontWeight: FontWeight.w700,
              color: UnionFlowColors.textTertiary,
              letterSpacing: 1,
            ),
          ),
          if (required) ...[
            const SizedBox(width: 4),
            const Text('*',
                style: TextStyle(
                    color: UnionFlowColors.error,
                    fontSize: 12,
                    fontWeight: FontWeight.w700)),
          ],
        ],
      );

  Widget _optionalToggle() => InkWell(
        onTap: () => setState(() => _showOptional = !_showOptional),
        borderRadius: BorderRadius.circular(10),
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 11),
          decoration: BoxDecoration(
            color: UnionFlowColors.surfaceVariant,
            borderRadius: BorderRadius.circular(10),
            border: Border.all(color: UnionFlowColors.border),
          ),
          child: Row(
            children: [
              const Icon(Icons.tune_rounded,
                  size: 16, color: UnionFlowColors.textSecondary),
              const SizedBox(width: 8),
              const Text(
                'Informations complémentaires',
                style: TextStyle(
                    fontSize: 13,
                    fontWeight: FontWeight.w600,
                    color: UnionFlowColors.textSecondary),
              ),
              const Spacer(),
              Text(
                _showOptional ? 'Réduire' : 'Développer',
                style: const TextStyle(
                    fontSize: 11, color: UnionFlowColors.unionGreen),
              ),
              Icon(
                _showOptional ? Icons.expand_less : Icons.expand_more,
                size: 18,
                color: UnionFlowColors.unionGreen,
              ),
            ],
          ),
        ),
      );

  InputDecoration _inputDeco(String label,
      {IconData? icon, String? hint, int? maxLength, bool required = false}) {
    return InputDecoration(
      labelText: required ? '$label *' : label,
      hintText: hint,
      counterText: '',
      prefixIcon: icon != null
          ? Icon(icon, size: 18, color: UnionFlowColors.textTertiary)
          : null,
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(10),
        borderSide: const BorderSide(color: UnionFlowColors.border),
      ),
      enabledBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(10),
        borderSide: const BorderSide(color: UnionFlowColors.border),
      ),
      focusedBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(10),
        borderSide:
            const BorderSide(color: UnionFlowColors.unionGreen, width: 1.5),
      ),
      errorBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(10),
        borderSide: const BorderSide(color: UnionFlowColors.error),
      ),
      focusedErrorBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(10),
        borderSide:
            const BorderSide(color: UnionFlowColors.error, width: 1.5),
      ),
      contentPadding:
          const EdgeInsets.symmetric(horizontal: 14, vertical: 13),
      filled: true,
      fillColor: UnionFlowColors.surface,
      labelStyle:
          const TextStyle(fontSize: 13, color: UnionFlowColors.textSecondary),
    );
  }

  Widget _field(
    TextEditingController ctrl,
    String label, {
    bool required = false,
    IconData? icon,
    TextInputType? keyboard,
    String? Function(String?)? validator,
    String? hint,
    int? maxLength,
  }) {
    return TextFormField(
      controller: ctrl,
      keyboardType: keyboard,
      maxLength: maxLength,
      style:
          const TextStyle(fontSize: 14, color: UnionFlowColors.textPrimary),
      decoration: _inputDeco(label,
          icon: icon, hint: hint, maxLength: maxLength, required: required),
      validator: validator ??
          (required
              ? (v) =>
                  (v == null || v.trim().isEmpty) ? 'Champ obligatoire' : null
              : null),
    );
  }

  Widget _dropdown({
    required String label,
    required String? value,
    required List<String> items,
    required Map<String, String> labels,
    required IconData icon,
    required void Function(String?) onChanged,
  }) {
    return DropdownButtonFormField<String>(
      value: value,
      isExpanded: true,
      decoration: _inputDeco(label, icon: icon),
      style:
          const TextStyle(fontSize: 14, color: UnionFlowColors.textPrimary),
      items: items
          .map((k) => DropdownMenuItem(
                value: k,
                child: Text(labels[k] ?? k,
                    style: const TextStyle(fontSize: 14)),
              ))
          .toList(),
      onChanged: onChanged,
    );
  }

  Widget _datePicker() => Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          InkWell(
            onTap: _pickDate,
            borderRadius: BorderRadius.circular(10),
            child: InputDecorator(
              decoration: InputDecoration(
                labelText: 'Date de naissance *',
                prefixIcon: const Icon(Icons.calendar_today_rounded,
                    size: 18, color: UnionFlowColors.textTertiary),
                suffixIcon: const Icon(Icons.chevron_right_rounded,
                    size: 18, color: UnionFlowColors.textTertiary),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(10),
                  borderSide: BorderSide(
                    color: _dateMissing
                        ? UnionFlowColors.error
                        : UnionFlowColors.border,
                  ),
                ),
                enabledBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(10),
                  borderSide: BorderSide(
                    color: _dateMissing
                        ? UnionFlowColors.error
                        : _dateNaissance != null
                            ? UnionFlowColors.unionGreen
                            : UnionFlowColors.border,
                  ),
                ),
                contentPadding:
                    const EdgeInsets.symmetric(horizontal: 14, vertical: 13),
                filled: true,
                fillColor: UnionFlowColors.surface,
                labelStyle: const TextStyle(
                    fontSize: 13, color: UnionFlowColors.textSecondary),
              ),
              child: Text(
                _dateNaissance != null
                    ? DateFormat('dd MMMM yyyy', 'fr').format(_dateNaissance!)
                    : 'Sélectionner une date',
                style: TextStyle(
                  fontSize: 14,
                  color: _dateNaissance != null
                      ? UnionFlowColors.textPrimary
                      : UnionFlowColors.textTertiary,
                ),
              ),
            ),
          ),
          if (_dateMissing)
            const Padding(
              padding: EdgeInsets.only(top: 4, left: 14),
              child: Text(
                'La date de naissance est obligatoire',
                style: TextStyle(fontSize: 11, color: UnionFlowColors.error),
              ),
            ),
        ],
      );

  Future<void> _pickDate() async {
    final picked = await showDatePicker(
      context: context,
      initialDate: _dateNaissance ?? DateTime(1990),
      firstDate: DateTime(1900),
      lastDate: DateTime.now().subtract(const Duration(days: 365 * 16)),
      builder: (ctx, child) => Theme(
        data: Theme.of(ctx).copyWith(
          colorScheme: Theme.of(ctx).colorScheme.copyWith(
                primary: UnionFlowColors.unionGreen,
              ),
        ),
        child: child!,
      ),
    );
    if (picked != null) {
      setState(() {
        _dateNaissance = picked;
        _dateMissing = false;
      });
    }
  }
}
