import 'package:flutter/material.dart';
import 'base_field.dart';
import '../ui/entity_form.dart';

/// Value List Picker
/// - Shows an icon button
/// - Loads list from API and displays as modal cards
/// - On selecting an item, fills multiple form fields based on mapping
class ValueListPickerField extends BaseField {
  final String fieldKey;
  final String label;
  final String hint;
  final bool isRequired;
  final Future<List<Map<String, dynamic>>> Function() optionsLoader;
  final Map<String, String> fillMappings; // sourceKey -> targetFieldKey in form
  final IconData icon;

  ValueListPickerField({
    required this.fieldKey,
    required this.label,
    this.hint = '',
    this.isRequired = false,
    required this.optionsLoader,
    required this.fillMappings,
    this.icon = Icons.playlist_add_check,
  });

  @override
  String? Function(String?)? get validator => null;

  @override
  Map<String, dynamic>? get customProperties => const {
        'excludeFromSubmit': true, // helper-only, no direct submission
      };

  @override
  Widget buildField({
    required TextEditingController controller,
    required ColorScheme colorScheme,
    VoidCallback? onChanged,
  }) {
    return _ValueListPickerWidget(
      label: label,
      colorScheme: colorScheme,
      optionsLoader: optionsLoader,
      fillMappings: fillMappings,
      icon: icon,
    );
  }
}

class _ValueListPickerWidget extends StatefulWidget {
  final String label;
  final ColorScheme colorScheme;
  final Future<List<Map<String, dynamic>>> Function() optionsLoader;
  final Map<String, String> fillMappings;
  final IconData icon;

  const _ValueListPickerWidget({
    required this.label,
    required this.colorScheme,
    required this.optionsLoader,
    required this.fillMappings,
    required this.icon,
  });

  @override
  State<_ValueListPickerWidget> createState() => _ValueListPickerWidgetState();
}

class _ValueListPickerWidgetState extends State<_ValueListPickerWidget> {
  bool _loading = false;
  String? _loadError;

  Future<void> _open() async {
    if (!mounted) return;
    setState(() => _loading = true);

    // Kick off the load but render the sheet immediately with a loader
    final Future<List<Map<String, dynamic>>> loadFuture = (() async {
      try {
        _loadError = null;
        final list = await widget.optionsLoader();
        return list;
      } catch (e) {
        _loadError = e.toString();
        return const <Map<String, dynamic>>[];
      }
    })();

    final cs = widget.colorScheme;
    final selected = await showModalBottomSheet<Map<String, dynamic>>(
      context: context,
      isScrollControlled: true,
      backgroundColor: cs.surface,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
      ),
      builder: (context) {
        return SafeArea(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              // Header with close button
              Padding(
                padding:
                    const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
                child: Row(
                  children: [
                    Expanded(
                      child: Text(
                        widget.label,
                        style: TextStyle(
                          color: cs.onSurface,
                          fontSize: 16,
                          fontWeight: FontWeight.w700,
                        ),
                      ),
                    ),
                    IconButton(
                      tooltip: 'Close',
                      icon:
                          Icon(Icons.close_rounded, color: cs.onSurfaceVariant),
                      onPressed: () => Navigator.of(context).pop(),
                    )
                  ],
                ),
              ),
              const SizedBox(height: 4),
              FutureBuilder<List<Map<String, dynamic>>>(
                future: loadFuture,
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return Padding(
                      padding: const EdgeInsets.all(24),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          SizedBox(
                            width: 20,
                            height: 20,
                            child: CircularProgressIndicator(
                                strokeWidth: 2, color: cs.primary),
                          ),
                          const SizedBox(width: 12),
                          Text('Loading...',
                              style: TextStyle(color: cs.onSurfaceVariant)),
                        ],
                      ),
                    );
                  }
                  if (snapshot.hasError || _loadError != null) {
                    final String msg = snapshot.error?.toString() ??
                        _loadError ??
                        'Failed to load';
                    return Padding(
                      padding: const EdgeInsets.all(16),
                      child: Container(
                        width: double.infinity,
                        decoration: BoxDecoration(
                          color: cs.errorContainer.withOpacity(0.3),
                          borderRadius: BorderRadius.circular(12),
                          border: Border.all(color: cs.error.withOpacity(0.2)),
                        ),
                        padding: const EdgeInsets.all(12),
                        child: Row(
                          children: [
                            Icon(Icons.error_outline, color: cs.error),
                            const SizedBox(width: 8),
                            Expanded(
                              child: Text(msg,
                                  style: TextStyle(color: cs.onSurfaceVariant)),
                            ),
                          ],
                        ),
                      ),
                    );
                  }
                  final options =
                      snapshot.data ?? const <Map<String, dynamic>>[];
                  if (options.isEmpty) {
                    return Padding(
                      padding: const EdgeInsets.all(24),
                      child: Column(
                        children: [
                          Icon(Icons.inbox_rounded,
                              color: cs.onSurfaceVariant, size: 36),
                          const SizedBox(height: 8),
                          Text('No data found',
                              style: TextStyle(color: cs.onSurfaceVariant)),
                          const SizedBox(height: 12),
                          ElevatedButton.icon(
                            onPressed: () => Navigator.of(context).pop(),
                            icon: const Icon(Icons.close_rounded),
                            label: const Text('Close'),
                            style: ElevatedButton.styleFrom(
                              backgroundColor: cs.primary,
                              foregroundColor: cs.onPrimary,
                            ),
                          )
                        ],
                      ),
                    );
                  }
                  return Flexible(
                    child: ListView.separated(
                      padding: const EdgeInsets.symmetric(horizontal: 8),
                      itemCount: options.length,
                      separatorBuilder: (_, __) => Divider(
                          height: 1, color: cs.outline.withOpacity(0.08)),
                      itemBuilder: (context, index) {
                        final o = options[index];

                        dynamic _readByPath(
                            Map<String, dynamic> m, String path) {
                          if (m.isEmpty || path.isEmpty) return null;
                          if (path.contains('.')) {
                            dynamic current = m;
                            for (final seg in path.split('.')) {
                              if (current is Map && current.containsKey(seg)) {
                                current = current[seg];
                              } else {
                                current = null;
                                break;
                              }
                            }
                            return current;
                          }
                          return m[path];
                        }

                        final List<String> mappingKeys =
                            widget.fillMappings.keys.toList();
                        print('mappingKeys: $mappingKeys');
                        final String titleKey =
                            mappingKeys.isNotEmpty ? mappingKeys[0] : 'name';
                        final String subtitleKey =
                            mappingKeys.length > 1 ? mappingKeys[1] : '';

                        String title = (_readByPath(o, titleKey) ??
                                o['name'] ??
                                o['title'] ??
                                '')
                            .toString();
                        String subtitle = subtitleKey.isNotEmpty
                            ? (_readByPath(o, subtitleKey) ?? '').toString()
                            : (o['description'] ??
                                    o['email'] ??
                                    o['phone'] ??
                                    '')
                                .toString();

                        final String leadingText =
                            (title.isNotEmpty ? title[0] : 'N').toUpperCase();
                        return ListTile(
                          leading: Container(
                            width: 40,
                            height: 40,
                            decoration: BoxDecoration(
                              gradient: LinearGradient(
                                colors: [
                                  cs.primary,
                                  cs.primary.withOpacity(0.7)
                                ],
                                begin: Alignment.topLeft,
                                end: Alignment.bottomRight,
                              ),
                              borderRadius: BorderRadius.circular(10),
                              boxShadow: [
                                BoxShadow(
                                    color: cs.primary.withOpacity(0.2),
                                    blurRadius: 8,
                                    offset: const Offset(0, 4)),
                              ],
                            ),
                            alignment: Alignment.center,
                            child: Text(leadingText,
                                style: TextStyle(
                                    color: cs.onPrimary,
                                    fontWeight: FontWeight.w700)),
                          ),
                          title: Text(title,
                              style: TextStyle(
                                  color: cs.onSurface,
                                  fontWeight: FontWeight.w600)),
                          subtitle: subtitle.isEmpty
                              ? null
                              : Text(subtitle,
                                  style: TextStyle(color: cs.onSurfaceVariant)),
                          trailing: Icon(Icons.chevron_right_rounded,
                              color: cs.onSurfaceVariant),
                          onTap: () {
                            Navigator.of(context).pop<Map<String, dynamic>>(o);
                          },
                        );
                      },
                    ),
                  );
                },
              ),
              const SizedBox(height: 16),
            ],
          ),
        );
      },
    );

    if (!mounted) return;
    setState(() => _loading = false);

    // After sheet closes, if a selection was returned, fill controllers safely
    if (selected != null) {
      final scope = EntityFormScope.of(context);
      if (scope != null) {
        dynamic _readByPath(Map<String, dynamic> m, String path) {
          if (m.isEmpty || path.isEmpty) return null;
          if (path.contains('.')) {
            dynamic current = m;
            for (final seg in path.split('.')) {
              if (current is Map && current.containsKey(seg)) {
                current = current[seg];
              } else {
                current = null;
                break;
              }
            }
            return current;
          }
          return m[path];
        }

        widget.fillMappings.forEach((sourceKey, targetFieldKey) {
          dynamic v = _readByPath(selected, sourceKey);
          if (v == null) {
            v = _readByPath(selected, '${sourceKey}1') ??
                _readByPath(selected, '${sourceKey}2') ??
                _readByPath(selected, sourceKey.toLowerCase()) ??
                _readByPath(selected, sourceKey.toUpperCase());
          }
          final c = scope.controllers[targetFieldKey];
          if (c != null) {
            try {
              c.text = v?.toString() ?? '';
            } catch (_) {
              // Controller may be disposed; ignore safely
            }
          }
        });
        scope.notifyParent();
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final cs = widget.colorScheme;
    return Row(
      children: [
        Expanded(
          child: Text(widget.label,
              style:
                  TextStyle(color: cs.onSurface, fontWeight: FontWeight.w600)),
        ),
        IconButton(
          tooltip: 'Open ${widget.label}',
          icon: _loading
              ? const SizedBox(
                  width: 18,
                  height: 18,
                  child: CircularProgressIndicator(strokeWidth: 2))
              : Icon(widget.icon, color: cs.primary),
          onPressed: _loading ? null : _open,
        )
      ],
    );
  }
}
