import 'package:flutter/material.dart';
import 'package:p_tits_pas/models/relais_model.dart';
import 'package:p_tits_pas/utils/phone_utils.dart';
import 'package:p_tits_pas/utils/email_utils.dart';
import 'package:p_tits_pas/widgets/email_text_field.dart';
import 'package:p_tits_pas/widgets/french_phone_field.dart';
import 'package:p_tits_pas/models/user.dart';
import 'package:p_tits_pas/services/auth_service.dart';
import 'package:p_tits_pas/services/relais_service.dart';
import 'package:p_tits_pas/services/user_service.dart';

class AdminUserFormDialog extends StatefulWidget {
  final AppUser? initialUser;
  final bool withRelais;
  final bool adminMode;
  final bool readOnly;

  const AdminUserFormDialog({
    super.key,
    this.initialUser,
    this.withRelais = true,
    this.adminMode = false,
    this.readOnly = false,
  });

  @override
  State<AdminUserFormDialog> createState() => _AdminUserFormDialogState();
}

class _AdminUserFormDialogState extends State<AdminUserFormDialog> {
  final _formKey = GlobalKey<FormState>();
  final _nomController = TextEditingController();
  final _prenomController = TextEditingController();
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();
  final _telephoneController = TextEditingController();
  final _passwordToggleFocusNode =
      FocusNode(skipTraversal: true, canRequestFocus: false);

  bool _isSubmitting = false;
  bool _obscurePassword = true;
  bool _isLoadingRelais = true;
  List<RelaisModel> _relais = [];
  String? _selectedRelaisId;
  String? _currentUserId;
  bool get _isEditMode => widget.initialUser != null;
  bool get _isSuperAdminTarget =>
      (widget.initialUser?.role ?? '').toLowerCase() == 'super_admin';
  bool get _isSelfTarget =>
      _isEditMode &&
      _currentUserId != null &&
      widget.initialUser!.id == _currentUserId;
  bool get _canDeleteTarget => !_isSuperAdminTarget && !_isSelfTarget;
  bool get _isLockedAdminIdentity =>
      _isEditMode && widget.adminMode && _isSuperAdminTarget;
  String get _targetRoleKey {
    if (widget.initialUser != null) {
      return (widget.initialUser!.role).toLowerCase();
    }
    return widget.adminMode ? 'administrateur' : 'gestionnaire';
  }

  String get _targetRoleLabel {
    switch (_targetRoleKey) {
      case 'super_admin':
        return 'Super administrateur';
      case 'administrateur':
        return 'Administrateur';
      case 'gestionnaire':
        return 'Gestionnaire';
      case 'assistante_maternelle':
        return 'Assistante maternelle';
      case 'parent':
        return 'Parent';
      default:
        return 'Utilisateur';
    }
  }

  IconData get _targetRoleIcon {
    switch (_targetRoleKey) {
      case 'super_admin':
        return Icons.verified_user_outlined;
      case 'administrateur':
        return Icons.admin_panel_settings_outlined;
      case 'gestionnaire':
        return Icons.assignment_ind_outlined;
      case 'assistante_maternelle':
        return Icons.child_care_outlined;
      case 'parent':
        return Icons.supervisor_account_outlined;
      default:
        return Icons.person_outline;
    }
  }

  @override
  void initState() {
    super.initState();
    final user = widget.initialUser;
    if (user != null) {
      _nomController.text = user.nom ?? '';
      _prenomController.text = user.prenom ?? '';
      _emailController.text = user.email;
      _telephoneController.text = formatPhoneForDisplay(user.telephone ?? '');
      // En édition, on ne préremplit jamais le mot de passe.
      _passwordController.clear();
      final initialRelaisId = user.relaisId?.trim();
      _selectedRelaisId =
          (initialRelaisId == null || initialRelaisId.isEmpty)
              ? null
              : initialRelaisId;
    }
    if (widget.withRelais) {
      _loadRelais();
    } else {
      _isLoadingRelais = false;
    }
    _loadCurrentUserId();
  }

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

  @override
  void dispose() {
    _nomController.dispose();
    _prenomController.dispose();
    _emailController.dispose();
    _passwordController.dispose();
    _telephoneController.dispose();
    _passwordToggleFocusNode.dispose();
    super.dispose();
  }

  /// Fallback si GET /relais échoue : conserve le relais déjà connu sur l'utilisateur.
  List<RelaisModel> _fallbackRelaisFromUser() {
    final id = _selectedRelaisId?.trim();
    if (id == null || id.isEmpty) return const [];
    final nom = (widget.initialUser?.relaisNom ?? '').trim();
    return [
      RelaisModel(
        id: id,
        nom: nom.isNotEmpty ? nom : 'Relais actuel',
        adresse: '',
        actif: true,
      ),
    ];
  }

  Future<void> _loadRelais() async {
    try {
      final list = await RelaisService.getRelais();
      if (!mounted) return;
      final uniqueById = <String, RelaisModel>{};
      for (final relais in list) {
        uniqueById[relais.id] = relais;
      }

      final filtered = uniqueById.values.where((r) => r.actif).toList();
      if (_selectedRelaisId != null &&
          !filtered.any((r) => r.id == _selectedRelaisId)) {
        final selected = uniqueById[_selectedRelaisId!];
        if (selected != null) {
          filtered.add(selected);
        } else {
          // Garder l'id sélectionné et afficher un item de secours (nom carte).
          filtered.addAll(_fallbackRelaisFromUser());
        }
      }

      setState(() {
        _relais = filtered;
        _isLoadingRelais = false;
      });
    } catch (_) {
      if (!mounted) return;
      // Ne pas nullifier _selectedRelaisId (#151) — la carte a déjà le bon libellé.
      setState(() {
        _relais = _fallbackRelaisFromUser();
        _isLoadingRelais = false;
      });
    }
  }

  String? _required(String? value, String field) {
    if (value == null || value.trim().isEmpty) {
      return '$field est requis';
    }
    return null;
  }

  String? _validateEmail(String? value) {
    final base = _required(value, 'Email');
    if (base != null) {
      return base;
    }
    return validateEmail(value, allowEmpty: true);
  }

  String? _validatePassword(String? value) {
    if (_isEditMode && (value == null || value.trim().isEmpty)) {
      return null;
    }
    final base = _required(value, 'Mot de passe');
    if (base != null) return base;
    if (value!.trim().length < 6) return 'Minimum 6 caractères';
    return null;
  }

  String? _validatePhone(String? value) {
    if (_isEditMode && (value == null || value.trim().isEmpty)) {
      return null;
    }
    final base = _required(value, 'Téléphone');
    if (base != null) {
      return base;
    }
    return validateFrenchNationalPhone(value, allowEmpty: false);
  }

  String _toTitleCase(String raw) {
    final trimmed = raw.trim();
    if (trimmed.isEmpty) return trimmed;
    final words = trimmed.split(RegExp(r'\s+'));
    final normalizedWords = words.map(_capitalizeComposedWord).toList();
    return normalizedWords.join(' ');
  }

  String _capitalizeComposedWord(String word) {
    if (word.isEmpty) return word;
    final lower = word.toLowerCase();
    final separators = <String>{"-", "'", "’"};
    final buffer = StringBuffer();
    var capitalizeNext = true;

    for (var i = 0; i < lower.length; i++) {
      final char = lower[i];
      if (capitalizeNext && RegExp(r'[a-zà-öø-ÿ]').hasMatch(char)) {
        buffer.write(char.toUpperCase());
        capitalizeNext = false;
      } else {
        buffer.write(char);
        capitalizeNext = separators.contains(char);
      }
    }
    return buffer.toString();
  }

  Future<void> _submit() async {
    if (widget.readOnly) return;
    if (_isSubmitting) return;
    if (!_formKey.currentState!.validate()) return;

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

    try {
      final normalizedNom = _toTitleCase(_nomController.text);
      final normalizedPrenom = _toTitleCase(_prenomController.text);
      final normalizedPhone = normalizePhone(_telephoneController.text);
      final passwordProvided = _passwordController.text.trim().isNotEmpty;

      if (_isEditMode) {
        if (widget.adminMode) {
          final lockedNom = _toTitleCase(widget.initialUser!.nom ?? '');
          final lockedPrenom = _toTitleCase(widget.initialUser!.prenom ?? '');
          await UserService.updateAdministrateur(
            adminId: widget.initialUser!.id,
            nom: _isLockedAdminIdentity ? lockedNom : normalizedNom,
            prenom: _isLockedAdminIdentity ? lockedPrenom : normalizedPrenom,
            email: _emailController.text.trim(),
            telephone: normalizedPhone.isEmpty
                ? normalizePhone(widget.initialUser!.telephone ?? '')
                : normalizedPhone,
            password: passwordProvided ? _passwordController.text : null,
          );
        } else {
          final currentUser = widget.initialUser!;
          final initialNom = _toTitleCase(currentUser.nom ?? '');
          final initialPrenom = _toTitleCase(currentUser.prenom ?? '');
          final initialEmail = currentUser.email.trim();
          final initialPhone = normalizePhone(currentUser.telephone ?? '');

          final onlyRelaisChanged =
              normalizedNom == initialNom &&
              normalizedPrenom == initialPrenom &&
              _emailController.text.trim() == initialEmail &&
              normalizedPhone == initialPhone &&
              !passwordProvided;

          if (onlyRelaisChanged) {
            await UserService.updateGestionnaireRelais(
              gestionnaireId: currentUser.id,
              relaisId: _selectedRelaisId,
            );
          } else {
            await UserService.updateGestionnaire(
              gestionnaireId: currentUser.id,
              nom: normalizedNom,
              prenom: normalizedPrenom,
              email: _emailController.text.trim(),
              telephone: normalizedPhone.isEmpty ? initialPhone : normalizedPhone,
              relaisId: _selectedRelaisId,
              password: passwordProvided ? _passwordController.text : null,
            );
          }
        }
      } else {
        if (widget.adminMode) {
          await UserService.createAdministrateur(
            nom: normalizedNom,
            prenom: normalizedPrenom,
            email: _emailController.text.trim(),
            password: _passwordController.text,
            telephone: normalizePhone(_telephoneController.text),
          );
        } else {
          await UserService.createGestionnaire(
            nom: normalizedNom,
            prenom: normalizedPrenom,
            email: _emailController.text.trim(),
            password: _passwordController.text,
            telephone: normalizePhone(_telephoneController.text),
            relaisId: _selectedRelaisId,
          );
        }
      }
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(
            _isEditMode
                ? (widget.adminMode
                    ? 'Administrateur modifié avec succès.'
                    : 'Gestionnaire modifié avec succès.')
                : (widget.adminMode
                    ? 'Administrateur créé avec succès.'
                    : 'Gestionnaire créé avec succès.'),
          ),
        ),
      );
      Navigator.of(context).pop(true);
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(
            e.toString().replaceFirst('Exception: ', ''),
          ),
          backgroundColor: Colors.red.shade700,
        ),
      );
    } finally {
      if (!mounted) return;
      setState(() {
        _isSubmitting = false;
      });
    }
  }

  Future<void> _delete() async {
    if (widget.readOnly) return;
    if (!_canDeleteTarget) return;
    if (!_isEditMode || _isSubmitting) return;

    final confirmed = await showDialog<bool>(
      context: context,
      builder: (ctx) {
        return AlertDialog(
          title: const Text('Confirmer la suppression'),
          content: Text(
            'Supprimer ${widget.initialUser!.fullName.isEmpty ? widget.initialUser!.email : widget.initialUser!.fullName} ?',
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(ctx).pop(false),
              child: const Text('Annuler'),
            ),
            FilledButton(
              onPressed: () => Navigator.of(ctx).pop(true),
              style: FilledButton.styleFrom(backgroundColor: Colors.red.shade700),
              child: const Text('Supprimer'),
            ),
          ],
        );
      },
    );

    if (confirmed != true) return;

    setState(() {
      _isSubmitting = true;
    });
    try {
      await UserService.deleteUser(widget.initialUser!.id);
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Gestionnaire supprimé.')),
      );
      Navigator.of(context).pop(true);
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(e.toString().replaceFirst('Exception: ', '')),
          backgroundColor: Colors.red.shade700,
        ),
      );
      setState(() {
        _isSubmitting = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Row(
        children: [
          CircleAvatar(
            radius: 16,
            backgroundColor: const Color(0xFFEDE5FA),
            child: Icon(
              _targetRoleIcon,
              size: 20,
              color: const Color(0xFF6B3FA0),
            ),
          ),
          const SizedBox(width: 8),
          Expanded(
            child: Text(
              _isEditMode
                  ? (widget.readOnly
                      ? 'Consulter un "$_targetRoleLabel"'
                      : 'Modifier un "$_targetRoleLabel"')
                  : 'Créer un "$_targetRoleLabel"',
            ),
          ),
          if (_isEditMode && !widget.readOnly)
            IconButton(
              icon: const Icon(Icons.close),
              tooltip: 'Fermer',
              onPressed: _isSubmitting
                  ? null
                  : () => Navigator.of(context).pop(false),
            ),
        ],
      ),
      content: SizedBox(
        width: 620,
        child: Form(
          key: _formKey,
          child: SingleChildScrollView(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Row(
                  children: [
                    Expanded(child: _buildPrenomField()),
                    const SizedBox(width: 12),
                    Expanded(child: _buildNomField()),
                  ],
                ),
                const SizedBox(height: 12),
                _buildEmailField(),
                const SizedBox(height: 12),
                Row(
                  children: [
                    Expanded(child: _buildPasswordField()),
                    const SizedBox(width: 12),
                    Expanded(child: _buildTelephoneField()),
                  ],
                ),
                if (widget.withRelais) ...[
                  const SizedBox(height: 12),
                  _buildRelaisField(),
                ],
              ],
            ),
          ),
        ),
      ),
      actions: [
        if (widget.readOnly) ...[
          FilledButton(
            onPressed: _isSubmitting ? null : () => Navigator.of(context).pop(false),
            child: const Text('Fermer'),
          ),
        ] else if (_isEditMode) ...[
          if (_canDeleteTarget)
            OutlinedButton(
              onPressed: _isSubmitting ? null : _delete,
              style: OutlinedButton.styleFrom(foregroundColor: Colors.red.shade700),
              child: const Text('Supprimer'),
            ),
          FilledButton.icon(
            onPressed: _isSubmitting ? null : _submit,
            icon: _isSubmitting
                ? const SizedBox(
                    width: 16,
                    height: 16,
                    child: CircularProgressIndicator(strokeWidth: 2),
                  )
                : const Icon(Icons.edit),
            label: Text(_isSubmitting ? 'Modification...' : 'Modifier'),
          ),
        ] else ...[
          OutlinedButton(
            onPressed:
                _isSubmitting ? null : () => Navigator.of(context).pop(false),
            child: const Text('Annuler'),
          ),
          FilledButton.icon(
            onPressed: _isSubmitting ? null : _submit,
            icon: _isSubmitting
                ? const SizedBox(
                    width: 16,
                    height: 16,
                    child: CircularProgressIndicator(strokeWidth: 2),
                  )
                : const Icon(Icons.person_add_alt_1),
            label: Text(_isSubmitting ? 'Création...' : 'Créer'),
          ),
        ],
      ],
    );
  }

  Widget _buildNomField() {
    return TextFormField(
      controller: _nomController,
      readOnly: widget.readOnly || _isLockedAdminIdentity,
      textCapitalization: TextCapitalization.words,
      decoration: const InputDecoration(
        labelText: 'Nom',
        border: OutlineInputBorder(),
      ),
      validator: (widget.readOnly || _isLockedAdminIdentity)
          ? null
          : (v) => _required(v, 'Nom'),
    );
  }

  Widget _buildPrenomField() {
    return TextFormField(
      controller: _prenomController,
      readOnly: widget.readOnly || _isLockedAdminIdentity,
      textCapitalization: TextCapitalization.words,
      decoration: const InputDecoration(
        labelText: 'Prénom',
        border: OutlineInputBorder(),
      ),
      validator: (widget.readOnly || _isLockedAdminIdentity)
          ? null
          : (v) => _required(v, 'Prénom'),
    );
  }

  Widget _buildEmailField() {
    return EmailTextFormField(
      controller: _emailController,
      readOnly: widget.readOnly,
      label: 'Email',
      validator: widget.readOnly ? null : _validateEmail,
    );
  }

  Widget _buildPasswordField() {
    return TextFormField(
      controller: _passwordController,
      readOnly: widget.readOnly,
      obscureText: _obscurePassword,
      enableSuggestions: false,
      autocorrect: false,
      autofillHints: _isEditMode
          ? const <String>[]
          : const [AutofillHints.newPassword],
      decoration: InputDecoration(
        labelText: _isEditMode
            ? 'Nouveau mot de passe'
            : 'Mot de passe',
        border: const OutlineInputBorder(),
        suffixIcon: widget.readOnly
            ? null
            : ExcludeFocus(
                child: IconButton(
                  focusNode: _passwordToggleFocusNode,
                  onPressed: () {
                    setState(() {
                      _obscurePassword = !_obscurePassword;
                    });
                  },
                  icon: Icon(
                    _obscurePassword ? Icons.visibility_off : Icons.visibility,
                  ),
                ),
              ),
      ),
      validator: widget.readOnly ? null : _validatePassword,
    );
  }

  Widget _buildTelephoneField() {
    return FrenchPhoneTextFormField(
      controller: _telephoneController,
      readOnly: widget.readOnly,
      label: 'Téléphone (ex: 06 12 34 56 78)',
      validator: widget.readOnly ? null : _validatePhone,
    );
  }

  Widget _buildRelaisField() {
    final selectedValue = _selectedRelaisId != null &&
            _relais.any((relais) => relais.id == _selectedRelaisId)
        ? _selectedRelaisId
        : null;

    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        DropdownButtonFormField<String?>(
          isExpanded: true,
          value: selectedValue,
          decoration: const InputDecoration(
            labelText: 'Relais principal',
            border: OutlineInputBorder(),
          ),
          items: [
            const DropdownMenuItem<String?>(
              value: null,
              child: Text('Aucun relais'),
            ),
            ..._relais.map(
              (relais) => DropdownMenuItem<String?>(
                value: relais.id,
                child: Text(relais.nom),
              ),
            ),
          ],
          onChanged: (_isLoadingRelais || widget.readOnly)
              ? null
              : (value) {
                  setState(() {
                    _selectedRelaisId = value;
                  });
                },
        ),
        if (_isLoadingRelais) ...[
          const SizedBox(height: 8),
          const LinearProgressIndicator(minHeight: 2),
        ],
      ],
    );
  }
}
