import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:real_estate_mobile/core/constants/app_colors.dart';
import 'package:real_estate_mobile/features/profile/data/profile_repository.dart';

// ---------------------------------------------------------------------------
// Data loading provider
// ---------------------------------------------------------------------------

/// Bundles all three API calls needed to render the edit-profile form.
final _editProfileDataProvider = FutureProvider.autoDispose<_EditProfileData>((
  ref,
) async {
  final repo = ProfileRepository();

  // 1. Fetch agent profile (need agentTypeId + pre-fill values)
  final profile = await repo.getMyProfile('AGENT');

  // 2. Resolve agentTypeId
  final agentTypeId =
      profile['agentTypeId'] as String? ??
      (profile['agentType'] as Map<String, dynamic>?)?['id'] as String?;
  if (agentTypeId == null || agentTypeId.isEmpty) {
    throw Exception('Agent type not found on profile');
  }

  // 3 + 4. Fetch sections & field-values in parallel
  final results = await Future.wait([
    repo.getSectionsForAgentType(agentTypeId),
    repo.getFieldValues(),
  ]);

  // getSectionsForAgentType returns { agentType: {...}, sections: [...] }
  final sectionsResponse = results[0];
  final sections = (sectionsResponse['sections'] as List<dynamic>?) ?? [];

  // getFieldValues returns { agentProfileId: "...", fieldValues: [...] }
  final fieldValuesResponse = results[1];
  final fieldValues =
      (fieldValuesResponse['fieldValues'] as List<dynamic>?) ?? [];

  return _EditProfileData(
    profile: profile,
    sections: sections,
    fieldValues: fieldValues,
  );
});

class _EditProfileData {
  final Map<String, dynamic> profile;
  final List<dynamic> sections;
  final List<dynamic> fieldValues;
  const _EditProfileData({
    required this.profile,
    required this.sections,
    required this.fieldValues,
  });
}

// ---------------------------------------------------------------------------
// Screen
// ---------------------------------------------------------------------------

class AgentEditProfileScreen extends ConsumerStatefulWidget {
  const AgentEditProfileScreen({super.key});

  @override
  ConsumerState<AgentEditProfileScreen> createState() =>
      _AgentEditProfileScreenState();
}

class _AgentEditProfileScreenState
    extends ConsumerState<AgentEditProfileScreen> {
  /// Master form data keyed by field slug.
  final Map<String, dynamic> _formData = {};

  /// Repeatable section entries keyed by section slug.
  final Map<String, List<Map<String, dynamic>>> _repeatableEntries = {};

  /// Tag-input controllers keyed by field slug.
  final Map<String, TextEditingController> _tagControllers = {};

  /// All text controllers for cleanup.
  final List<TextEditingController> _controllers = [];

  bool _saving = false;
  bool _initialized = false;

  final _formKey = GlobalKey<FormState>();

  // Pre-fill slug mapping to profile keys
  static const _profileSlugMap = <String, String>{
    'first-name': 'firstName',
    'first_name': 'firstName',
    'last-name': 'lastName',
    'last_name': 'lastName',
    'email': 'email',
    'bio': 'bio',
    'license-number': 'licenseNumber',
    'license_number': 'licenseNumber',
    'experience': 'experience',
    'specializations': 'specializations',
    'languages': 'languages',
    'service-areas': 'serviceAreas',
    'service_areas': 'serviceAreas',
  };

  @override
  void dispose() {
    for (final c in _controllers) {
      c.dispose();
    }
    for (final c in _tagControllers.values) {
      c.dispose();
    }
    super.dispose();
  }

  // ---------------------------------------------------------------------------
  // Initialization
  // ---------------------------------------------------------------------------

  void _initializeFormData(_EditProfileData data) {
    if (_initialized) return;
    _initialized = true;

    final profile = data.profile;

    // Build field-value lookup by slug
    final fvMap = <String, dynamic>{};
    for (final fv in data.fieldValues) {
      if (fv is Map<String, dynamic>) {
        final slug = fv['fieldSlug'] as String? ?? '';
        if (slug.isNotEmpty) {
          fvMap[slug] = fv['value'];
        }
      }
    }

    // Walk sections & fields
    for (final section in data.sections) {
      if (section is! Map<String, dynamic>) continue;
      final isRepeatable = section['isRepeatable'] == true;
      final sectionSlug = section['slug'] as String? ?? '';
      final fields = section['fields'] as List<dynamic>? ?? [];

      if (isRepeatable) {
        // Load existing repeatable entries from field values
        final entriesKey = '${sectionSlug}_entries';
        final existingEntries = fvMap[entriesKey];
        if (existingEntries is List && existingEntries.isNotEmpty) {
          _repeatableEntries[sectionSlug] = existingEntries
              .map(
                (e) => e is Map<String, dynamic>
                    ? Map<String, dynamic>.from(e)
                    : <String, dynamic>{},
              )
              .toList();
        } else {
          _repeatableEntries[sectionSlug] = [{}];
        }
      }

      for (final field in fields) {
        if (field is! Map<String, dynamic>) continue;
        final slug = field['slug'] as String? ?? '';
        final fieldType = field['fieldType'] as String? ?? 'TEXT';
        if (slug.isEmpty) continue;

        // Priority: fieldValues API > profile pre-fill > defaultValue
        dynamic value;

        // 1. Field values from API
        if (fvMap.containsKey(slug)) {
          value = fvMap[slug];
        }
        // 2. Profile pre-fill
        else if (_profileSlugMap.containsKey(slug)) {
          value = profile[_profileSlugMap[slug]!];
        }
        // 3. Default value
        else {
          value = field['defaultValue'];
        }

        // Normalize value based on field type
        if (!isRepeatable) {
          _formData[slug] = _normalizeValue(value, fieldType, field);
        }
      }
    }
  }

  dynamic _normalizeValue(
    dynamic value,
    String fieldType,
    Map<String, dynamic> field,
  ) {
    switch (fieldType) {
      case 'CHECKBOX':
        if (value is bool) return value;
        if (value is String) return value.toLowerCase() == 'true';
        return false;
      case 'CHECKBOX_GROUP':
      case 'MULTI_SELECT':
      case 'TAG_INPUT':
        if (value is List) return List<String>.from(value.map((e) => '$e'));
        if (value is String && value.isNotEmpty) {
          try {
            final decoded = jsonDecode(value);
            if (decoded is List) {
              return List<String>.from(decoded.map((e) => '$e'));
            }
          } catch (_) {}
          return [value];
        }
        return <String>[];
      case 'NUMBER':
        if (value is num) return value;
        if (value is String) return num.tryParse(value);
        return null;
      case 'RANGE':
        if (value is Map) return value;
        if (value is String && value.isNotEmpty) {
          try {
            return jsonDecode(value);
          } catch (_) {}
        }
        final rangeConfig = field['rangeConfig'] as Map<String, dynamic>?;
        final min = (rangeConfig?['min'] as num?)?.toDouble() ?? 0;
        final max = (rangeConfig?['max'] as num?)?.toDouble() ?? 100;
        return {'min': min, 'max': max};
      case 'FILE':
      case 'FILE_UPLOAD':
        // Keep as list of maps — don't stringify
        if (value is List) return value;
        if (value is String && value.isNotEmpty) {
          try {
            final decoded = jsonDecode(value);
            if (decoded is List) return decoded;
          } catch (_) {}
        }
        return <Map<String, dynamic>>[];
      default:
        return value?.toString() ?? '';
    }
  }

  // ---------------------------------------------------------------------------
  // Save
  // ---------------------------------------------------------------------------

  Future<void> _save(_EditProfileData data) async {
    if (!(_formKey.currentState?.validate() ?? false)) return;

    setState(() => _saving = true);

    try {
      final repo = ProfileRepository();
      final fieldValuesToSave = <Map<String, dynamic>>[];

      // Collect all form data
      for (final entry in _formData.entries) {
        dynamic val = entry.value;
        // Convert lists to JSON-compatible format
        if (val is List) {
          val = val;
        } else if (val is Map) {
          val = val;
        }
        fieldValuesToSave.add({'fieldSlug': entry.key, 'value': val});
      }

      // Add repeatable section entries
      for (final entry in _repeatableEntries.entries) {
        fieldValuesToSave.add({
          'fieldSlug': '${entry.key}_entries',
          'value': entry.value,
        });
      }

      // Save field values
      await repo.saveFieldValues(fieldValuesToSave);

      // Sync phone to main profile if present
      const phoneSlugs = [
        'phone_number',
        'phone-number',
        'cell_number',
        'cell-number',
        'office_number',
        'office-number',
        'phone',
      ];
      for (final slug in phoneSlugs) {
        if (_formData.containsKey(slug)) {
          final phoneVal = _formData[slug];
          if (phoneVal is String && phoneVal.isNotEmpty) {
            await repo.updateProfile('AGENT', {'phone': phoneVal});
            break;
          }
        }
      }

      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('Profile updated successfully'),
            backgroundColor: AppColors.success,
          ),
        );
        context.pop();
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Failed to save: $e'),
            backgroundColor: AppColors.error,
          ),
        );
      }
    } finally {
      if (mounted) setState(() => _saving = false);
    }
  }

  // ---------------------------------------------------------------------------
  // Build
  // ---------------------------------------------------------------------------

  @override
  Widget build(BuildContext context) {
    final asyncData = ref.watch(_editProfileDataProvider);

    return Column(
      children: [
        // Header with circular back button (SVG) matching Figma
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 4, 16, 8),
          child: Row(
            children: [
              GestureDetector(
                onTap: () => context.pop(),
                child: SvgPicture.asset(
                  'assets/icons/back_circle_icon.svg',
                  width: 32,
                  height: 32,
                ),
              ),
              const SizedBox(width: 12),
              const Text(
                'Edit Profile',
                style: TextStyle(
                  fontFamily: 'Fractul',
                  fontSize: 16,
                  fontWeight: FontWeight.w700,
                  color: AppColors.primaryDark,
                ),
              ),
            ],
          ),
        ),
        Expanded(child: _buildBody(asyncData)),
      ],
    );
  }

  Widget _buildBody(AsyncValue<_EditProfileData> asyncData) {
    return asyncData.when(
      loading: () => const Center(
        child: CircularProgressIndicator(
          color: AppColors.accentOrange,
          strokeWidth: 2,
        ),
      ),
      error: (err, _) => Center(
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const Icon(Icons.error_outline, size: 48, color: AppColors.error),
              const SizedBox(height: 16),
              Text(
                'Failed to load profile data',
                style: const TextStyle(
                  fontFamily: 'Fractul',
                  fontSize: 16,
                  fontWeight: FontWeight.w600,
                  color: AppColors.primaryDark,
                ),
              ),
              const SizedBox(height: 8),
              Text(
                '$err',
                textAlign: TextAlign.center,
                style: const TextStyle(
                  fontFamily: 'SourceSerif4',
                  fontSize: 14,
                  color: AppColors.hintText,
                ),
              ),
              const SizedBox(height: 24),
              ElevatedButton(
                onPressed: () => ref.invalidate(_editProfileDataProvider),
                style: ElevatedButton.styleFrom(
                  backgroundColor: AppColors.accentOrange,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  ),
                ),
                child: const Text(
                  'Retry',
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ],
          ),
        ),
      ),
      data: (data) {
        _initializeFormData(data);
        return _buildForm(data);
      },
    );
  }

  Widget _buildForm(_EditProfileData data) {
    final sections =
        data.sections
            .whereType<Map<String, dynamic>>()
            .where((s) => s['isActive'] != false)
            .toList()
          ..sort(
            (a, b) => ((a['sortOrder'] as num?) ?? 0).compareTo(
              (b['sortOrder'] as num?) ?? 0,
            ),
          );

    return Form(
      key: _formKey,
      child: Column(
        children: [
          Expanded(
            child: SingleChildScrollView(
              padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
              child: Column(
                children: [
                  for (final section in sections) ...[
                    _buildSection(section),
                    const SizedBox(height: 16),
                  ],
                  const SizedBox(height: 24),
                ],
              ),
            ),
          ),
          _buildBottomButtons(data),
        ],
      ),
    );
  }

  // ---------------------------------------------------------------------------
  // Bottom buttons
  // ---------------------------------------------------------------------------

  Widget _buildBottomButtons(_EditProfileData data) {
    return Container(
      padding: const EdgeInsets.fromLTRB(16, 12, 16, 24),
      decoration: BoxDecoration(
        color: Colors.white,
        boxShadow: [
          BoxShadow(
            color: Colors.black.withValues(alpha: 0.05),
            blurRadius: 10,
            offset: const Offset(0, -2),
          ),
        ],
      ),
      child: Row(
        children: [
          Expanded(
            child: OutlinedButton(
              onPressed: _saving ? null : () => context.pop(),
              style: OutlinedButton.styleFrom(
                side: const BorderSide(color: AppColors.primaryDark),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15),
                ),
                padding: const EdgeInsets.symmetric(vertical: 14),
              ),
              child: const Text(
                'Cancel',
                style: TextStyle(
                  fontFamily: 'Fractul',
                  fontSize: 14,
                  fontWeight: FontWeight.w500,
                  color: AppColors.primaryDark,
                ),
              ),
            ),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: ElevatedButton(
              onPressed: _saving ? null : () => _save(data),
              style: ElevatedButton.styleFrom(
                backgroundColor: AppColors.accentOrange,
                disabledBackgroundColor: AppColors.accentOrange.withValues(
                  alpha: 0.5,
                ),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15),
                ),
                padding: const EdgeInsets.symmetric(vertical: 14),
              ),
              child: _saving
                  ? const SizedBox(
                      width: 20,
                      height: 20,
                      child: CircularProgressIndicator(
                        strokeWidth: 2,
                        color: Colors.white,
                      ),
                    )
                  : const Text(
                      'Save',
                      style: TextStyle(
                        fontFamily: 'Fractul',
                        fontSize: 14,
                        fontWeight: FontWeight.w600,
                        color: Colors.white,
                      ),
                    ),
            ),
          ),
        ],
      ),
    );
  }

  // ---------------------------------------------------------------------------
  // Section card
  // ---------------------------------------------------------------------------

  Widget _buildSection(Map<String, dynamic> section) {
    final name = section['name'] as String? ?? '';
    final iconName = section['icon'] as String?;
    final isRepeatable = section['isRepeatable'] == true;
    final sectionSlug = section['slug'] as String? ?? '';
    final fields =
        (section['fields'] as List<dynamic>? ?? [])
            .whereType<Map<String, dynamic>>()
            .where(
              (f) => f['isActive'] != false && f['isSearchableOnly'] != true,
            )
            .toList()
          ..sort(
            (a, b) => ((a['sortOrder'] as num?) ?? 0).compareTo(
              (b['sortOrder'] as num?) ?? 0,
            ),
          );

    if (fields.isEmpty) return const SizedBox.shrink();

    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(15),
        border: Border.all(color: const Color(0xFFE5E7EB)),
        boxShadow: const [
          BoxShadow(
            color: Color(0x80D9D9D9),
            blurRadius: 20,
            offset: Offset(0, 10),
          ),
        ],
      ),
      padding: const EdgeInsets.all(20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Header
          Row(
            children: [
              if (iconName != null && iconName.isNotEmpty) ...[
                Icon(
                  _resolveIcon(iconName),
                  size: 20,
                  color: AppColors.accentOrange,
                ),
                const SizedBox(width: 8),
              ],
              Expanded(
                child: Text(
                  name,
                  style: const TextStyle(
                    fontFamily: 'Fractul',
                    fontSize: 15,
                    fontWeight: FontWeight.w500,
                    color: AppColors.primaryDark,
                  ),
                ),
              ),
            ],
          ),
          const SizedBox(height: 16),

          // Fields
          if (isRepeatable)
            _buildRepeatableFields(sectionSlug, fields)
          else
            ...fields.map((f) => _buildFieldWidget(f)),
        ],
      ),
    );
  }

  // ---------------------------------------------------------------------------
  // Repeatable section
  // ---------------------------------------------------------------------------

  Widget _buildRepeatableFields(
    String sectionSlug,
    List<Map<String, dynamic>> fields,
  ) {
    final entries = _repeatableEntries[sectionSlug] ?? [{}];

    return Column(
      children: [
        for (int i = 0; i < entries.length; i++) ...[
          if (i > 0)
            const Padding(
              padding: EdgeInsets.symmetric(vertical: 12),
              child: Divider(height: 1, color: Color(0xFFE5E7EB)),
            ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(
                'Entry ${i + 1}',
                style: const TextStyle(
                  fontFamily: 'Fractul',
                  fontSize: 13,
                  fontWeight: FontWeight.w500,
                  color: AppColors.hintText,
                ),
              ),
              if (entries.length > 1)
                GestureDetector(
                  onTap: () {
                    setState(() {
                      entries.removeAt(i);
                      // Clear cached controllers for this section's entries
                      // so they get recreated with correct values after
                      // re-indexing
                      final fieldSlugs =
                          fields.map((f) => f['slug'] as String? ?? '');
                      _tagControllers.removeWhere((key, _) =>
                          fieldSlugs.any((s) => key.startsWith('${s}_entry')));
                    });
                  },
                  child: const Icon(
                    Icons.remove_circle_outline,
                    size: 20,
                    color: AppColors.error,
                  ),
                ),
            ],
          ),
          const SizedBox(height: 8),
          ...fields.map((f) {
            final slug = f['slug'] as String? ?? '';
            return _buildFieldWidget(
              f,
              getValue: () => entries[i][slug],
              setValue: (val) {
                setState(() {
                  entries[i][slug] = val;
                });
              },
              controllerKeySuffix: 'entry$i',
            );
          }),
        ],
        const SizedBox(height: 12),
        GestureDetector(
          onTap: () {
            setState(() {
              entries.add({});
            });
          },
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: const [
              Icon(
                Icons.add_circle_outline,
                size: 20,
                color: AppColors.accentOrange,
              ),
              SizedBox(width: 6),
              Text(
                'Add Entry',
                style: TextStyle(
                  fontFamily: 'Fractul',
                  fontSize: 13,
                  fontWeight: FontWeight.w500,
                  color: AppColors.accentOrange,
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }

  // ---------------------------------------------------------------------------
  // Field dispatcher
  // ---------------------------------------------------------------------------

  Widget _buildFieldWidget(
    Map<String, dynamic> field, {
    dynamic Function()? getValue,
    void Function(dynamic)? setValue,
    String? controllerKeySuffix,
  }) {
    final slug = field['slug'] as String? ?? '';
    final fieldType = field['fieldType'] as String? ?? 'TEXT';
    final label = field['name'] as String? ?? '';
    final placeholder = field['placeholder'] as String? ?? '';
    final description = field['description'] as String?;
    final isRequired = field['isRequired'] == true;
    final validation = field['validation'] as Map<String, dynamic>?;
    final options =
        (field['options'] as List<dynamic>?)
            ?.whereType<Map<String, dynamic>>()
            .toList() ??
        [];
    final uiConfig = field['uiConfig'] as Map<String, dynamic>?;
    final helpText = uiConfig?['helpText'] as String?;

    // Getter / setter — either use repeatable entry or global formData
    dynamic currentValue() => getValue != null ? getValue() : _formData[slug];
    void updateValue(dynamic val) {
      if (setValue != null) {
        setValue(val);
      } else {
        setState(() {
          _formData[slug] = val;
        });
      }
    }

    Widget fieldWidget;

    switch (fieldType) {
      case 'TEXT':
        fieldWidget = _buildTextField(
          slug,
          currentValue,
          updateValue,
          placeholder,
          validation,
          false,
          controllerKeySuffix: controllerKeySuffix,
        );
        break;
      case 'TEXTAREA':
        fieldWidget = _buildTextField(
          slug,
          currentValue,
          updateValue,
          placeholder,
          validation,
          true,
          controllerKeySuffix: controllerKeySuffix,
        );
        break;
      case 'NUMBER':
        fieldWidget = _buildNumberField(
          slug,
          currentValue,
          updateValue,
          placeholder,
          validation,
          controllerKeySuffix: controllerKeySuffix,
        );
        break;
      case 'DATE':
        fieldWidget = _buildDateField(
          slug,
          currentValue,
          updateValue,
          placeholder,
        );
        break;
      case 'CHECKBOX':
        fieldWidget = _buildCheckboxField(
          slug,
          currentValue,
          updateValue,
          label,
        );
        // Checkbox renders its own label, so skip the standard label wrapper.
        return Padding(
          padding: const EdgeInsets.only(bottom: 16),
          child: fieldWidget,
        );
      case 'CHECKBOX_GROUP':
        fieldWidget = _buildCheckboxGroup(
          slug,
          currentValue,
          updateValue,
          options,
          uiConfig,
        );
        break;
      case 'RADIO':
        fieldWidget = _buildRadioGroup(
          slug,
          currentValue,
          updateValue,
          options,
        );
        break;
      case 'SELECT':
        fieldWidget = _buildSelectField(
          slug,
          currentValue,
          updateValue,
          placeholder,
          options,
        );
        break;
      case 'MULTI_SELECT':
        fieldWidget = _buildMultiSelect(
          slug,
          currentValue,
          updateValue,
          options,
        );
        break;
      case 'TAG_INPUT':
        fieldWidget = _buildTagInput(
          slug,
          currentValue,
          updateValue,
          placeholder,
          controllerKeySuffix: controllerKeySuffix,
        );
        break;
      case 'RANGE':
        fieldWidget = _buildRangeField(slug, currentValue, updateValue, field);
        break;
      case 'FILE':
      case 'FILE_UPLOAD':
        fieldWidget = _buildFileUpload(slug, currentValue, updateValue);
        break;
      case 'REPEATER':
        return const SizedBox.shrink();
      default:
        fieldWidget = _buildTextField(
          slug,
          currentValue,
          updateValue,
          placeholder,
          validation,
          false,
          controllerKeySuffix: controllerKeySuffix,
        );
    }

    return Padding(
      padding: const EdgeInsets.only(bottom: 16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Label
          RichText(
            text: TextSpan(
              text: label,
              style: const TextStyle(
                fontFamily: 'Fractul',
                fontSize: 14,
                fontWeight: FontWeight.w500,
                color: AppColors.primaryDark,
              ),
              children: isRequired
                  ? [
                      const TextSpan(
                        text: ' *',
                        style: TextStyle(color: AppColors.error),
                      ),
                    ]
                  : null,
            ),
          ),
          if (description != null && description.isNotEmpty) ...[
            const SizedBox(height: 2),
            Text(
              description,
              style: const TextStyle(
                fontFamily: 'SourceSerif4',
                fontSize: 12,
                color: AppColors.hintText,
              ),
            ),
          ],
          if (helpText != null && helpText.isNotEmpty) ...[
            const SizedBox(height: 2),
            Text(
              helpText,
              style: const TextStyle(
                fontFamily: 'SourceSerif4',
                fontSize: 12,
                color: AppColors.hintText,
              ),
            ),
          ],
          const SizedBox(height: 6),
          fieldWidget,
        ],
      ),
    );
  }

  // ---------------------------------------------------------------------------
  // TEXT / TEXTAREA
  // ---------------------------------------------------------------------------

  Widget _buildTextField(
    String slug,
    dynamic Function() getValue,
    void Function(dynamic) setValue,
    String placeholder,
    Map<String, dynamic>? validation,
    bool multiline, {
    String? controllerKeySuffix,
  }) {
    final key = controllerKeySuffix != null
        ? '${slug}_${controllerKeySuffix}_text'
        : '${slug}_text';
    if (!_tagControllers.containsKey(key)) {
      final controller = TextEditingController(text: '${getValue() ?? ''}');
      _tagControllers[key] = controller;
      _controllers.add(controller);
    }
    final controller = _tagControllers[key]!;

    final maxLength = validation?['maxLength'] as int?;

    return TextFormField(
      controller: controller,
      maxLines: multiline ? 5 : 1,
      minLines: multiline ? 3 : 1,
      maxLength: maxLength != null && maxLength > 0 ? maxLength : null,
      style: const TextStyle(
        fontFamily: 'SourceSerif4',
        fontSize: 14,
        fontWeight: FontWeight.w300,
        color: AppColors.primaryDark,
      ),
      decoration: _inputDecoration(placeholder),
      onChanged: (val) => setValue(val),
    );
  }

  // ---------------------------------------------------------------------------
  // NUMBER
  // ---------------------------------------------------------------------------

  Widget _buildNumberField(
    String slug,
    dynamic Function() getValue,
    void Function(dynamic) setValue,
    String placeholder,
    Map<String, dynamic>? validation, {
    String? controllerKeySuffix,
  }) {
    final key = controllerKeySuffix != null
        ? '${slug}_${controllerKeySuffix}_number'
        : '${slug}_number';
    if (!_tagControllers.containsKey(key)) {
      final val = getValue();
      final controller = TextEditingController(text: val != null ? '$val' : '');
      _tagControllers[key] = controller;
      _controllers.add(controller);
    }
    final controller = _tagControllers[key]!;

    return TextFormField(
      controller: controller,
      keyboardType: const TextInputType.numberWithOptions(decimal: true),
      inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[0-9.]'))],
      style: const TextStyle(
        fontFamily: 'SourceSerif4',
        fontSize: 14,
        fontWeight: FontWeight.w300,
        color: AppColors.primaryDark,
      ),
      decoration: _inputDecoration(placeholder),
      onChanged: (val) => setValue(num.tryParse(val)),
    );
  }

  // ---------------------------------------------------------------------------
  // DATE
  // ---------------------------------------------------------------------------

  Widget _buildDateField(
    String slug,
    dynamic Function() getValue,
    void Function(dynamic) setValue,
    String placeholder,
  ) {
    final val = getValue();
    final displayText = val is String && val.isNotEmpty ? val : placeholder;

    return GestureDetector(
      onTap: () async {
        DateTime initial = DateTime.now();
        if (val is String && val.isNotEmpty) {
          try {
            initial = DateTime.parse(val);
          } catch (_) {}
        }
        final picked = await showDatePicker(
          context: context,
          initialDate: initial,
          firstDate: DateTime(1900),
          lastDate: DateTime(2100),
          builder: (ctx, child) => Theme(
            data: Theme.of(ctx).copyWith(
              colorScheme: const ColorScheme.light(
                primary: AppColors.accentOrange,
                onPrimary: Colors.white,
                surface: Colors.white,
                onSurface: AppColors.primaryDark,
              ),
            ),
            child: child!,
          ),
        );
        if (picked != null) {
          setValue(DateFormat('yyyy-MM-dd').format(picked));
        }
      },
      child: Container(
        height: 44,
        padding: const EdgeInsets.symmetric(horizontal: 12),
        decoration: BoxDecoration(
          border: Border.all(color: const Color(0xFFE5E7EB)),
          borderRadius: BorderRadius.circular(15),
        ),
        child: Row(
          children: [
            Expanded(
              child: Text(
                displayText.isEmpty ? 'Select date' : displayText,
                style: TextStyle(
                  fontFamily: 'SourceSerif4',
                  fontSize: 14,
                  fontWeight: FontWeight.w300,
                  color: val is String && val.isNotEmpty
                      ? AppColors.primaryDark
                      : AppColors.hintText,
                ),
              ),
            ),
            const Icon(
              Icons.calendar_today,
              size: 18,
              color: AppColors.hintText,
            ),
          ],
        ),
      ),
    );
  }

  // ---------------------------------------------------------------------------
  // CHECKBOX (single toggle)
  // ---------------------------------------------------------------------------

  Widget _buildCheckboxField(
    String slug,
    dynamic Function() getValue,
    void Function(dynamic) setValue,
    String label,
  ) {
    final checked = getValue() == true;
    return GestureDetector(
      onTap: () => setValue(!checked),
      child: Row(
        children: [
          Container(
            width: 17,
            height: 17,
            decoration: BoxDecoration(
              color: checked ? AppColors.accentOrange : Colors.white,
              borderRadius: BorderRadius.circular(5),
              border: Border.all(
                color: checked
                    ? AppColors.accentOrange
                    : const Color(0xFFD1D5DB),
              ),
            ),
            child: checked
                ? const Icon(Icons.check, size: 13, color: Colors.white)
                : null,
          ),
          const SizedBox(width: 10),
          Expanded(
            child: Text(
              label,
              style: const TextStyle(
                fontFamily: 'Fractul',
                fontSize: 14,
                fontWeight: FontWeight.w500,
                color: AppColors.primaryDark,
              ),
            ),
          ),
        ],
      ),
    );
  }

  // ---------------------------------------------------------------------------
  // CHECKBOX_GROUP
  // ---------------------------------------------------------------------------

  Widget _buildCheckboxGroup(
    String slug,
    dynamic Function() getValue,
    void Function(dynamic) setValue,
    List<Map<String, dynamic>> options,
    Map<String, dynamic>? uiConfig,
  ) {
    final selected = List<String>.from((getValue() ?? <String>[]) as List);
    final columns = (uiConfig?['columns'] as num?)?.toInt() ?? 2;

    return Wrap(
      spacing: 8,
      runSpacing: 8,
      children: options.map((opt) {
        final optVal = opt['value'] as String? ?? '';
        final optLabel = opt['label'] as String? ?? optVal;
        final isChecked = selected.contains(optVal);

        return GestureDetector(
          onTap: () {
            final newList = List<String>.from(selected);
            if (isChecked) {
              newList.remove(optVal);
            } else {
              newList.add(optVal);
            }
            setValue(newList);
          },
          child: SizedBox(
            width: columns > 1
                ? (MediaQuery.of(context).size.width - 72) / columns
                : null,
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Container(
                  width: 17,
                  height: 17,
                  decoration: BoxDecoration(
                    color: isChecked ? AppColors.accentOrange : Colors.white,
                    borderRadius: BorderRadius.circular(5),
                    border: Border.all(
                      color: isChecked
                          ? AppColors.accentOrange
                          : const Color(0xFFD1D5DB),
                    ),
                  ),
                  child: isChecked
                      ? const Icon(Icons.check, size: 13, color: Colors.white)
                      : null,
                ),
                const SizedBox(width: 8),
                Flexible(
                  child: Text(
                    optLabel,
                    style: const TextStyle(
                      fontFamily: 'SourceSerif4',
                      fontSize: 13,
                      fontWeight: FontWeight.w300,
                      color: AppColors.primaryDark,
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }).toList(),
    );
  }

  // ---------------------------------------------------------------------------
  // RADIO
  // ---------------------------------------------------------------------------

  Widget _buildRadioGroup(
    String slug,
    dynamic Function() getValue,
    void Function(dynamic) setValue,
    List<Map<String, dynamic>> options,
  ) {
    final currentVal = '${getValue() ?? ''}';
    return Column(
      children: options.map((opt) {
        final optVal = opt['value'] as String? ?? '';
        final optLabel = opt['label'] as String? ?? optVal;
        return GestureDetector(
          onTap: () => setValue(optVal),
          child: Padding(
            padding: const EdgeInsets.symmetric(vertical: 4),
            child: Row(
              children: [
                Container(
                  width: 20,
                  height: 20,
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    border: Border.all(
                      color: currentVal == optVal
                          ? AppColors.accentOrange
                          : const Color(0xFFD1D5DB),
                      width: 2,
                    ),
                  ),
                  child: currentVal == optVal
                      ? Center(
                          child: Container(
                            width: 10,
                            height: 10,
                            decoration: const BoxDecoration(
                              shape: BoxShape.circle,
                              color: AppColors.accentOrange,
                            ),
                          ),
                        )
                      : null,
                ),
                const SizedBox(width: 10),
                Expanded(
                  child: Text(
                    optLabel,
                    style: const TextStyle(
                      fontFamily: 'SourceSerif4',
                      fontSize: 14,
                      fontWeight: FontWeight.w300,
                      color: AppColors.primaryDark,
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }).toList(),
    );
  }

  // ---------------------------------------------------------------------------
  // SELECT (dropdown)
  // ---------------------------------------------------------------------------

  Widget _buildSelectField(
    String slug,
    dynamic Function() getValue,
    void Function(dynamic) setValue,
    String placeholder,
    List<Map<String, dynamic>> options,
  ) {
    final currentVal = '${getValue() ?? ''}';
    final hasMatch = options.any((o) => o['value'] == currentVal);

    return DropdownButtonFormField<String>(
      initialValue: hasMatch ? currentVal : null,
      isExpanded: true,
      decoration: _inputDecoration(placeholder),
      icon: const Icon(Icons.keyboard_arrow_down, color: AppColors.hintText),
      style: const TextStyle(
        fontFamily: 'SourceSerif4',
        fontSize: 14,
        fontWeight: FontWeight.w300,
        color: AppColors.primaryDark,
      ),
      hint: Text(
        placeholder.isEmpty ? 'Select...' : placeholder,
        style: const TextStyle(
          fontFamily: 'SourceSerif4',
          fontSize: 14,
          fontWeight: FontWeight.w300,
          color: AppColors.hintText,
        ),
      ),
      items: options.map((opt) {
        final v = opt['value'] as String? ?? '';
        final l = opt['label'] as String? ?? v;
        return DropdownMenuItem<String>(value: v, child: Text(l));
      }).toList(),
      onChanged: (val) {
        if (val != null) setValue(val);
      },
    );
  }

  // ---------------------------------------------------------------------------
  // MULTI_SELECT (chip group)
  // ---------------------------------------------------------------------------

  Widget _buildMultiSelect(
    String slug,
    dynamic Function() getValue,
    void Function(dynamic) setValue,
    List<Map<String, dynamic>> options,
  ) {
    final selected = List<String>.from((getValue() ?? <String>[]) as List);

    return Wrap(
      spacing: 8,
      runSpacing: 8,
      children: options.map((opt) {
        final optVal = opt['value'] as String? ?? '';
        final optLabel = opt['label'] as String? ?? optVal;
        final isSelected = selected.contains(optVal);

        return GestureDetector(
          onTap: () {
            final newList = List<String>.from(selected);
            if (isSelected) {
              newList.remove(optVal);
            } else {
              newList.add(optVal);
            }
            setValue(newList);
          },
          child: Container(
            padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
            decoration: BoxDecoration(
              color: isSelected
                  ? AppColors.accentOrange.withValues(alpha: 0.1)
                  : Colors.white,
              borderRadius: BorderRadius.circular(20),
              border: Border.all(
                color: isSelected
                    ? AppColors.accentOrange
                    : const Color(0xFFD1D5DB),
              ),
            ),
            child: Text(
              optLabel,
              style: TextStyle(
                fontFamily: 'SourceSerif4',
                fontSize: 13,
                fontWeight: FontWeight.w400,
                color: isSelected
                    ? AppColors.accentOrange
                    : AppColors.primaryDark,
              ),
            ),
          ),
        );
      }).toList(),
    );
  }

  // ---------------------------------------------------------------------------
  // TAG_INPUT
  // ---------------------------------------------------------------------------

  Widget _buildTagInput(
    String slug,
    dynamic Function() getValue,
    void Function(dynamic) setValue,
    String placeholder, {
    String? controllerKeySuffix,
  }) {
    final tags = List<String>.from((getValue() ?? <String>[]) as List);

    final tagKey = controllerKeySuffix != null
        ? '${slug}_${controllerKeySuffix}'
        : slug;
    if (!_tagControllers.containsKey(tagKey)) {
      final controller = TextEditingController();
      _tagControllers[tagKey] = controller;
      _controllers.add(controller);
    }
    final controller = _tagControllers[tagKey]!;

    void addTag(String text) {
      final trimmed = text.trim();
      if (trimmed.isEmpty || tags.contains(trimmed)) return;
      final newList = List<String>.from(tags)..add(trimmed);
      setValue(newList);
      controller.clear();
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        if (tags.isNotEmpty)
          Padding(
            padding: const EdgeInsets.only(bottom: 8),
            child: Wrap(
              spacing: 6,
              runSpacing: 6,
              children: tags.map((tag) {
                return Container(
                  padding: const EdgeInsets.symmetric(
                    horizontal: 12,
                    vertical: 6,
                  ),
                  decoration: BoxDecoration(
                    color: AppColors.accentOrange.withValues(alpha: 0.1),
                    borderRadius: BorderRadius.circular(20),
                    border: Border.all(
                      color: AppColors.accentOrange.withValues(alpha: 0.3),
                    ),
                  ),
                  child: Row(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Text(
                        tag,
                        style: const TextStyle(
                          fontFamily: 'SourceSerif4',
                          fontSize: 13,
                          fontWeight: FontWeight.w400,
                          color: AppColors.primaryDark,
                        ),
                      ),
                      const SizedBox(width: 4),
                      GestureDetector(
                        onTap: () {
                          final newList = List<String>.from(tags)..remove(tag);
                          setValue(newList);
                        },
                        child: const Icon(
                          Icons.close,
                          size: 14,
                          color: AppColors.hintText,
                        ),
                      ),
                    ],
                  ),
                );
              }).toList(),
            ),
          ),
        TextFormField(
          controller: controller,
          style: const TextStyle(
            fontFamily: 'SourceSerif4',
            fontSize: 14,
            fontWeight: FontWeight.w300,
            color: AppColors.primaryDark,
          ),
          decoration:
              _inputDecoration(
                placeholder.isEmpty ? 'Type and press Enter' : placeholder,
              ).copyWith(
                suffixIcon: IconButton(
                  icon: const Icon(
                    Icons.add_circle_outline,
                    color: AppColors.accentOrange,
                  ),
                  onPressed: () => addTag(controller.text),
                ),
              ),
          onFieldSubmitted: addTag,
        ),
      ],
    );
  }

  // ---------------------------------------------------------------------------
  // RANGE
  // ---------------------------------------------------------------------------

  Widget _buildRangeField(
    String slug,
    dynamic Function() getValue,
    void Function(dynamic) setValue,
    Map<String, dynamic> field,
  ) {
    final rangeConfig = field['rangeConfig'] as Map<String, dynamic>? ?? {};
    final configMin = (rangeConfig['min'] as num?)?.toDouble() ?? 0;
    final configMax = (rangeConfig['max'] as num?)?.toDouble() ?? 100;
    final step = (rangeConfig['step'] as num?)?.toDouble() ?? 1;
    final unit = rangeConfig['unit'] as String? ?? '';

    final currentRange = getValue();
    double rangeMin = configMin;
    double rangeMax = configMax;
    if (currentRange is Map) {
      rangeMin = (currentRange['min'] as num?)?.toDouble() ?? configMin;
      rangeMax = (currentRange['max'] as num?)?.toDouble() ?? configMax;
    }
    // Clamp to valid range
    rangeMin = rangeMin.clamp(configMin, configMax);
    rangeMax = rangeMax.clamp(configMin, configMax);
    if (rangeMin > rangeMax) rangeMin = rangeMax;

    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text(
              '${rangeMin.toInt()} $unit',
              style: const TextStyle(
                fontFamily: 'SourceSerif4',
                fontSize: 13,
                color: AppColors.primaryDark,
              ),
            ),
            Text(
              '${rangeMax.toInt()} $unit',
              style: const TextStyle(
                fontFamily: 'SourceSerif4',
                fontSize: 13,
                color: AppColors.primaryDark,
              ),
            ),
          ],
        ),
        SliderTheme(
          data: SliderTheme.of(context).copyWith(
            activeTrackColor: AppColors.accentOrange,
            inactiveTrackColor: AppColors.accentOrange.withValues(alpha: 0.2),
            thumbColor: AppColors.accentOrange,
            overlayColor: AppColors.accentOrange.withValues(alpha: 0.1),
          ),
          child: RangeSlider(
            values: RangeValues(rangeMin, rangeMax),
            min: configMin,
            max: configMax,
            divisions: step > 0
                ? ((configMax - configMin) / step).round()
                : null,
            onChanged: (values) {
              setValue({'min': values.start, 'max': values.end});
            },
          ),
        ),
      ],
    );
  }

  // ---------------------------------------------------------------------------
  // FILE_UPLOAD
  // ---------------------------------------------------------------------------

  bool _uploading = false;

  /// Parse file entries from the stored value (list of maps or strings).
  List<Map<String, dynamic>> _parseFileList(dynamic value) {
    if (value is! List) return [];
    return value.map<Map<String, dynamic>>((e) {
      if (e is Map<String, dynamic>) return e;
      if (e is Map) return Map<String, dynamic>.from(e);
      return {'name': '$e', 'id': '$e'};
    }).toList();
  }

  /// Extract a human-readable filename from a file entry.
  String _extractFileName(Map<String, dynamic> file) {
    // Prefer 'name' field
    if (file['name'] != null && (file['name'] as String).isNotEmpty) {
      return file['name'] as String;
    }
    // Fall back to extracting from key/id/url
    final key = (file['key'] ?? file['id'] ?? file['url'] ?? '') as String;
    if (key.isEmpty) return 'Unknown file';
    // Extract just the filename from the S3 key path
    final parts = key.split('/');
    return parts.last;
  }

  /// Format file size in human-readable form.
  String _formatFileSize(dynamic size) {
    if (size == null) return '';
    final bytes = size is num ? size.toInt() : int.tryParse('$size') ?? 0;
    if (bytes <= 0) return '';
    if (bytes < 1024) return '$bytes B';
    if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
    return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
  }

  Future<void> _pickAndUploadFile(
    String slug,
    dynamic Function() getValue,
    void Function(dynamic) setValue,
  ) async {
    final picker = ImagePicker();
    final picked = await picker.pickImage(source: ImageSource.gallery);
    if (picked == null) return;

    setState(() => _uploading = true);
    try {
      final repo = ProfileRepository();
      final fileName = picked.path.split('/').last;
      final contentType = _guessContentType(fileName);
      final fileBytes = await File(picked.path).readAsBytes();

      // Get presigned URL
      final urlData = await repo.getDocumentUploadUrl(fileName, contentType);

      // Upload to S3
      await repo.uploadToS3(urlData['uploadUrl']!, fileBytes, contentType);

      // Build new file entry
      final newFile = {
        'id': urlData['key']!,
        'key': urlData['key']!,
        'name': fileName,
        'size': fileBytes.length,
        'type': contentType,
        'url': urlData['publicUrl'] ?? urlData['key']!,
        'uploadedAt': DateTime.now().toIso8601String(),
      };

      // Add to existing list
      final currentFiles = _parseFileList(getValue());
      currentFiles.add(newFile);
      setValue(currentFiles);

      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('File uploaded successfully'),
            backgroundColor: AppColors.success,
          ),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Upload failed: $e'),
            backgroundColor: AppColors.error,
          ),
        );
      }
    } finally {
      if (mounted) setState(() => _uploading = false);
    }
  }

  String _guessContentType(String fileName) {
    final ext = (fileName.contains('.') ? '.${fileName.split('.').last}' : '')
        .toLowerCase();
    switch (ext) {
      case '.pdf':
        return 'application/pdf';
      case '.doc':
        return 'application/msword';
      case '.docx':
        return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
      case '.png':
        return 'image/png';
      case '.jpg':
      case '.jpeg':
        return 'image/jpeg';
      case '.gif':
        return 'image/gif';
      default:
        return 'application/octet-stream';
    }
  }

  Widget _buildFileUpload(
    String slug,
    dynamic Function() getValue,
    void Function(dynamic) setValue,
  ) {
    final fileList = _parseFileList(getValue());

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // Dashed upload area (matches Figma design)
        GestureDetector(
          onTap: _uploading
              ? null
              : () => _pickAndUploadFile(slug, getValue, setValue),
          child: Container(
            width: double.infinity,
            padding: const EdgeInsets.symmetric(vertical: 24),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(15),
              border: Border.all(
                color: const Color(0xFFCCD5DA),
                style: BorderStyle.solid,
              ),
            ),
            child: Column(
              children: [
                Icon(
                  Icons.cloud_upload_outlined,
                  size: 28,
                  color: _uploading
                      ? AppColors.hintText
                      : AppColors.primaryDark.withValues(alpha: 0.6),
                ),
                const SizedBox(height: 8),
                Text(
                  _uploading ? 'Uploading...' : 'Click to upload',
                  style: const TextStyle(
                    fontFamily: 'SourceSerif4',
                    fontSize: 14,
                    color: AppColors.primaryDark,
                  ),
                ),
                const SizedBox(height: 4),
                const Text(
                  'PDF, DOCX, JPG, PNG (max 10MB)',
                  style: TextStyle(
                    fontFamily: 'SourceSerif4',
                    fontSize: 12,
                    color: AppColors.hintText,
                  ),
                ),
                if (_uploading) ...[
                  const SizedBox(height: 12),
                  const SizedBox(
                    width: 24,
                    height: 24,
                    child: CircularProgressIndicator(
                      strokeWidth: 2,
                      color: AppColors.accentOrange,
                    ),
                  ),
                ],
              ],
            ),
          ),
        ),
        // Existing files list
        if (fileList.isNotEmpty) ...[
          const SizedBox(height: 12),
          const Row(
            children: [
              Icon(Icons.link, size: 16, color: AppColors.primaryDark),
              SizedBox(width: 6),
              Text(
                'Attached Documents',
                style: TextStyle(
                  fontFamily: 'Fractul',
                  fontSize: 14,
                  fontWeight: FontWeight.w500,
                  color: AppColors.primaryDark,
                ),
              ),
            ],
          ),
          const SizedBox(height: 8),
          ...fileList.map((file) {
            final name = _extractFileName(file);
            final sizeStr = _formatFileSize(file['size']);
            return Padding(
              padding: const EdgeInsets.only(bottom: 6),
              child: Container(
                padding: const EdgeInsets.symmetric(
                  horizontal: 12,
                  vertical: 8,
                ),
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(15),
                  border: Border.all(color: const Color(0xFFE5E7EB)),
                ),
                child: Row(
                  children: [
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            name,
                            overflow: TextOverflow.ellipsis,
                            style: const TextStyle(
                              fontFamily: 'SourceSerif4',
                              fontSize: 13,
                              color: AppColors.primaryDark,
                            ),
                          ),
                          if (sizeStr.isNotEmpty)
                            Text(
                              sizeStr,
                              style: const TextStyle(
                                fontFamily: 'SourceSerif4',
                                fontSize: 11,
                                color: AppColors.hintText,
                              ),
                            ),
                        ],
                      ),
                    ),
                    GestureDetector(
                      onTap: () {
                        final newList = List<Map<String, dynamic>>.from(
                          fileList,
                        );
                        newList.remove(file);
                        setValue(newList);
                      },
                      child: const Padding(
                        padding: EdgeInsets.all(4),
                        child: Icon(
                          Icons.close,
                          size: 14,
                          color: AppColors.hintText,
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            );
          }),
        ],
      ],
    );
  }

  // ---------------------------------------------------------------------------
  // Shared input decoration
  // ---------------------------------------------------------------------------

  InputDecoration _inputDecoration(String hint) {
    return InputDecoration(
      hintText: hint,
      hintStyle: const TextStyle(
        fontFamily: 'SourceSerif4',
        fontSize: 14,
        fontWeight: FontWeight.w300,
        color: AppColors.hintText,
      ),
      contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(15),
        borderSide: const BorderSide(color: Color(0xFFE5E7EB)),
      ),
      enabledBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(15),
        borderSide: const BorderSide(color: Color(0xFFE5E7EB)),
      ),
      focusedBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(15),
        borderSide: const BorderSide(color: AppColors.accentOrange),
      ),
      errorBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(15),
        borderSide: const BorderSide(color: AppColors.error),
      ),
      focusedErrorBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(15),
        borderSide: const BorderSide(color: AppColors.error),
      ),
      isDense: true,
    );
  }

  // ---------------------------------------------------------------------------
  // Icon resolver
  // ---------------------------------------------------------------------------

  IconData _resolveIcon(String name) {
    const iconMap = <String, IconData>{
      'user': Icons.person_outline,
      'person': Icons.person_outline,
      'profile': Icons.person_outline,
      'briefcase': Icons.work_outline,
      'work': Icons.work_outline,
      'business': Icons.business_outlined,
      'building': Icons.business_outlined,
      'office': Icons.business_outlined,
      'education': Icons.school_outlined,
      'school': Icons.school_outlined,
      'award': Icons.emoji_events_outlined,
      'trophy': Icons.emoji_events_outlined,
      'certificate': Icons.card_membership_outlined,
      'star': Icons.star_outline,
      'heart': Icons.favorite_outline,
      'home': Icons.home_outlined,
      'house': Icons.home_outlined,
      'location': Icons.location_on_outlined,
      'map': Icons.map_outlined,
      'phone': Icons.phone_outlined,
      'call': Icons.phone_outlined,
      'email': Icons.email_outlined,
      'mail': Icons.email_outlined,
      'globe': Icons.language,
      'world': Icons.language,
      'link': Icons.link,
      'settings': Icons.settings_outlined,
      'gear': Icons.settings_outlined,
      'info': Icons.info_outline,
      'dollar': Icons.attach_money,
      'money': Icons.attach_money,
      'finance': Icons.attach_money,
      'shield': Icons.shield_outlined,
      'lock': Icons.lock_outline,
      'clock': Icons.access_time,
      'time': Icons.access_time,
      'calendar': Icons.calendar_today_outlined,
      'file': Icons.description_outlined,
      'document': Icons.description_outlined,
      'camera': Icons.camera_alt_outlined,
      'photo': Icons.photo_outlined,
      'image': Icons.image_outlined,
      'chat': Icons.chat_outlined,
      'message': Icons.message_outlined,
      'list': Icons.list,
      'check': Icons.check_circle_outline,
      'target': Icons.gps_fixed,
      'flag': Icons.flag_outlined,
      'tag': Icons.label_outline,
    };

    final lower = name.toLowerCase().replaceAll(RegExp(r'[^a-z]'), '');
    for (final entry in iconMap.entries) {
      if (lower.contains(entry.key)) return entry.value;
    }
    return Icons.article_outlined;
  }
}
