// import 'package:base_project/core/providers/dynamic_theme_provider.dart';
// import 'package:flutter/material.dart';
// import 'package:provider/provider.dart';
// import '../fields/base_field.dart';
// import '../../../shared/widgets/buttons/modern_button.dart';
// import '../../../core/constants/ui_constants.dart';

// /// Reusable form component that dynamically renders fields based on field definitions
// /// This allows UI to be independent of field types and enables reusability
// class EntityForm extends StatefulWidget {
//   final List<BaseField> fields;
//   final Map<String, dynamic>? initialData;
//   final Function(Map<String, dynamic>) onSubmit;
//   final String submitButtonText;
//   final bool isLoading;

//   const EntityForm({
//     super.key,
//     required this.fields,
//     this.initialData,
//     required this.onSubmit,
//     this.submitButtonText = 'Submit',
//     this.isLoading = false,
//   });

//   @override
//   State<EntityForm> createState() => _EntityFormState();
// }

// class _EntityFormState extends State<EntityForm> {
//   final _formKey = GlobalKey<FormState>();
//   final Map<String, TextEditingController> _controllers = {};
//   final Map<String, BaseField> _fieldByKey = {};

//   @override
//   void initState() {
//     super.initState();
//     _initializeControllers();
//   }

//   void _initializeControllers() {
//     for (final field in widget.fields) {
//       _controllers[field.fieldKey] = TextEditingController(
//         text: widget.initialData?[field.fieldKey]?.toString() ?? '',
//       );
//       _fieldByKey[field.fieldKey] = field;
//     }
//   }

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

//   @override
//   Widget build(BuildContext context) {
//     return Consumer<DynamicThemeProvider>(
//       builder: (context, dynamicThemeProvider, child) {
//         final colorScheme = dynamicThemeProvider.getCurrentColorScheme(
//           Theme.of(context).brightness == Brightness.dark,
//         );

//         return Form(
//           key: _formKey,
//           child: Column(
//             children: [
//               // Dynamic field rendering
//               ...widget.fields.map((field) => Padding(
//                     padding:
//                         const EdgeInsets.only(bottom: UIConstants.spacing16),
//                     child: field.buildField(
//                       controller: _controllers[field.fieldKey]!,
//                       colorScheme: colorScheme,
//                       onChanged: () => setState(() {}),
//                     ),
//                   )),

//               const SizedBox(height: UIConstants.spacing24),

//               // Submit button
//               ModernButton(
//                 text: widget.submitButtonText,
//                 type: ModernButtonType.primary,
//                 size: ModernButtonSize.large,
//                 isLoading: widget.isLoading,
//                 onPressed: widget.isLoading ? null : _handleSubmit,
//               ),
//             ],
//           ),
//         );
//       },
//     );
//   }

//   void _handleSubmit() {
//     if (_formKey.currentState!.validate()) {
//       // Dynamic cross-field match for any password-confirm group
//       final Map<String, String> passwordByGroup = {};
//       final Map<String, String> confirmByGroup = {};
//       for (final entry in _controllers.entries) {
//         final key = entry.key;
//         final field = _fieldByKey[key];
//         final props = field?.customProperties ?? const {};
//         final isPassword = props['isPassword'] == true;
//         if (!isPassword) continue;
//         final String? groupId = props['groupId'];
//         if (groupId == null) continue;
//         final bool isConfirm = props['isConfirm'] == true;
//         if (isConfirm) {
//           confirmByGroup[groupId] = entry.value.text;
//         } else {
//           passwordByGroup[groupId] = entry.value.text;
//         }
//       }
//       for (final gid in confirmByGroup.keys) {
//         final confirm = confirmByGroup[gid] ?? '';
//         final pass = passwordByGroup[gid] ?? '';
//         if (confirm.isNotEmpty && confirm != pass) {
//           ScaffoldMessenger.of(context).showSnackBar(
//             const SnackBar(content: Text('Passwords do not match')),
//           );
//           return;
//         }
//       }

//       final formData = <String, dynamic>{};
//       for (final entry in _controllers.entries) {
//         final key = entry.key;
//         final field = _fieldByKey[key];
//         final value = entry.value.text.trim();

//         // Skip confirm entries for any password group
//         final props = field?.customProperties ?? const {};
//         final bool isPassword = props['isPassword'] == true;
//         final bool isConfirm = props['isConfirm'] == true;
//         if (isPassword && isConfirm) continue;

//         formData[key] = value;
//       }
//       widget.onSubmit(formData);
//     }
//   }
// }

// SECOND WORKING CODE
// import 'dart:convert';

// import 'package:flutter/material.dart';
// import 'package:provider/provider.dart';

// import '../../../core/constants/ui_constants.dart';
// import '../../../core/providers/dynamic_theme_provider.dart';
// import '../../../shared/widgets/buttons/modern_button.dart';
// import '../fields/base_field.dart';

// /// Reusable form component that dynamically renders fields based on field definitions
// /// This allows UI to be independent of field types and enables reusability
// class EntityForm extends StatefulWidget {
//   final List<BaseField> fields;
//   final Map<String, dynamic>? initialData;
//   final Function(Map<String, dynamic>) onSubmit;
//   final String submitButtonText;
//   final bool isLoading;

//   const EntityForm({
//     super.key,
//     required this.fields,
//     this.initialData,
//     required this.onSubmit,
//     this.submitButtonText = 'Submit',
//     this.isLoading = false,
//   });

//   @override
//   State<EntityForm> createState() => _EntityFormState();
// }

// class _EntityFormState extends State<EntityForm> {
//   final _formKey = GlobalKey<FormState>();
//   final Map<String, TextEditingController> _controllers = {};
//   final Map<String, BaseField> _fieldByKey = {};
//   late final Map<String, dynamic> _initialData;

//   @override
//   void initState() {
//     super.initState();
//     _initializeControllers();
//   }

//   void _initializeControllers() {
//     _initialData = widget.initialData ?? const {};
//     for (final field in widget.fields) {
//       final props = field.customProperties ?? const {};
//       final bool assignByJsonPaths = props['assignByJsonPaths'] == true;
//       final List<dynamic>? paths = props['paths'] as List<dynamic>?;
//       String initialText =
//           widget.initialData?[field.fieldKey]?.toString() ?? '';
//       if (assignByJsonPaths && paths != null) {
//         final Map<String, dynamic> values = {};
//         for (final p in paths) {
//           if (p is String) {
//             final v = _readValueByPath(_initialData, p);
//             if (v != null) values[p] = v;
//           }
//         }
//         if (values.isNotEmpty) {
//           initialText = _encodeMap(values);
//         }
//       }
//       _controllers[field.fieldKey] = TextEditingController(text: initialText);
//       _fieldByKey[field.fieldKey] = field;
//     }
//   }

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

//   @override
//   Widget build(BuildContext context) {
//     return Consumer<DynamicThemeProvider>(
//       builder: (context, dynamicThemeProvider, child) {
//         final colorScheme = dynamicThemeProvider.getCurrentColorScheme(
//           Theme.of(context).brightness == Brightness.dark,
//         );

//         return Form(
//           key: _formKey,
//           child: Column(
//             children: [
//               // Dynamic field rendering
//               ...widget.fields.map((field) => Padding(
//                     padding:
//                         const EdgeInsets.only(bottom: UIConstants.spacing16),
//                     child: field.buildField(
//                       controller: _controllers[field.fieldKey]!,
//                       colorScheme: colorScheme,
//                       onChanged: () => setState(() {}),
//                     ),
//                   )),

//               const SizedBox(height: UIConstants.spacing24),

//               // Submit button
//               ModernButton(
//                 text: widget.submitButtonText,
//                 type: ModernButtonType.primary,
//                 size: ModernButtonSize.large,
//                 isLoading: widget.isLoading,
//                 onPressed: widget.isLoading ? null : _handleSubmit,
//               ),
//             ],
//           ),
//         );
//       },
//     );
//   }

//   void _handleSubmit() {
//     if (_formKey.currentState!.validate()) {
//       // Dynamic cross-field match for any password-confirm group
//       final Map<String, String> passwordByGroup = {};
//       final Map<String, String> confirmByGroup = {};
//       for (final entry in _controllers.entries) {
//         final key = entry.key;
//         final field = _fieldByKey[key];
//         final props = field?.customProperties ?? const {};
//         final isPassword = props['isPassword'] == true;
//         if (!isPassword) continue;
//         final String? groupId = props['groupId'];
//         if (groupId == null) continue;
//         final bool isConfirm = props['isConfirm'] == true;
//         if (isConfirm) {
//           confirmByGroup[groupId] = entry.value.text;
//         } else {
//           passwordByGroup[groupId] = entry.value.text;
//         }
//       }
//       for (final gid in confirmByGroup.keys) {
//         final confirm = confirmByGroup[gid] ?? '';
//         final pass = passwordByGroup[gid] ?? '';
//         if (confirm.isNotEmpty && confirm != pass) {
//           ScaffoldMessenger.of(context).showSnackBar(
//             const SnackBar(content: Text('Passwords do not match')),
//           );
//           return;
//         }
//       }

//       final formData = <String, dynamic>{};
//       for (final entry in _controllers.entries) {
//         final key = entry.key;
//         final field = _fieldByKey[key];
//         final value = entry.value.text.trim();

//         // Skip fields that are marked as non-submittable (e.g., DataGrid)
//         final props = field?.customProperties ?? const {};
//         final bool excludeFromSubmit = props['excludeFromSubmit'] == true;
//         if (excludeFromSubmit) {
//           continue;
//         }

//         // Skip confirm entries for any password group
//         final bool isPassword = props['isPassword'] == true;
//         final bool isConfirm = props['isConfirm'] == true;
//         if (isPassword && isConfirm) continue;

//         final bool assignByJsonPaths = props['assignByJsonPaths'] == true;
//         if (assignByJsonPaths) {
//           // If composite and empty -> skip adding base key
//           if (value.isEmpty) {
//             continue;
//           }
//           final Map<String, dynamic>? map = _tryDecodeMap(value);
//           if (map != null) {
//             map.forEach((path, v) {
//               if (path is String) {
//                 _assignValueByPath(formData, path, v);
//               }
//             });
//             continue;
//           }
//           // If not decodable, also skip to avoid sending invalid base key
//           continue;
//         }

//         formData[key] = value;
//       }
//       widget.onSubmit(formData);
//     }
//   }

//   dynamic _readValueByPath(Map<String, dynamic>? source, String path) {
//     if (source == null) return null;
//     final segments = path.split('.');
//     dynamic current = source;
//     for (final segment in segments) {
//       if (current is Map<String, dynamic> && current.containsKey(segment)) {
//         current = current[segment];
//       } else {
//         return null;
//       }
//     }
//     return current;
//   }

//   void _assignValueByPath(
//       Map<String, dynamic> target, String path, dynamic value) {
//     final segments = path.split('.');
//     Map<String, dynamic> current = target;
//     for (int i = 0; i < segments.length; i++) {
//       final seg = segments[i];
//       final bool isLast = i == segments.length - 1;
//       if (isLast) {
//         current[seg] = value;
//       } else {
//         if (current[seg] is! Map<String, dynamic>) {
//           current[seg] = <String, dynamic>{};
//         }
//         current = current[seg] as Map<String, dynamic>;
//       }
//     }
//   }

//   String _encodeMap(Map<String, dynamic> map) {
//     return const JsonEncoder().convert(map);
//   }

//   Map<String, dynamic>? _tryDecodeMap(String value) {
//     try {
//       final decoded = const JsonDecoder().convert(value);
//       if (decoded is Map<String, dynamic>) return decoded;
//       return null;
//     } catch (_) {
//       return null;
//     }
//   }
// }

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../../core/providers/dynamic_theme_provider.dart';
import '../fields/base_field.dart';
import '../../../shared/widgets/buttons/modern_button.dart';
import '../../../core/constants/ui_constants.dart';

/// Reusable form component that dynamically renders fields based on field definitions
/// This allows UI to be independent of field types and enables reusability
class EntityForm extends StatefulWidget {
  final List<BaseField> fields;
  final Map<String, dynamic>? initialData;
  final Function(Map<String, dynamic>) onSubmit;
  final String submitButtonText;
  final bool isLoading;

  const EntityForm({
    super.key,
    required this.fields,
    this.initialData,
    required this.onSubmit,
    this.submitButtonText = 'Submit',
    this.isLoading = false,
  });

  @override
  State<EntityForm> createState() => _EntityFormState();
}

class _EntityFormState extends State<EntityForm> {
  final _formKey = GlobalKey<FormState>();
  final Map<String, TextEditingController> _controllers = {};
  final Map<String, BaseField> _fieldByKey = {};
  late final Map<String, dynamic> _initialData;

  @override
  void initState() {
    super.initState();
    _initializeControllers();
  }

  void _initializeControllers() {
    _initialData = widget.initialData ?? const {};
    for (final field in widget.fields) {
      final props = field.customProperties ?? const {};
      final bool assignByJsonPaths = props['assignByJsonPaths'] == true;
      final List<dynamic>? paths = props['paths'] as List<dynamic>?;
      String initialText =
          widget.initialData?[field.fieldKey]?.toString() ?? '';
      if (assignByJsonPaths && paths != null) {
        final Map<String, dynamic> values = {};
        for (final p in paths) {
          if (p is String) {
            final v = _readValueByPath(_initialData, p);
            if (v != null) values[p] = v;
          }
        }
        if (values.isNotEmpty) {
          initialText = _encodeMap(values);
        }
      }
      _controllers[field.fieldKey] = TextEditingController(text: initialText);
      _fieldByKey[field.fieldKey] = field;
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return Consumer<DynamicThemeProvider>(
      builder: (context, dynamicThemeProvider, child) {
        final colorScheme = dynamicThemeProvider.getCurrentColorScheme(
          Theme.of(context).brightness == Brightness.dark,
        );

        return EntityFormScope(
          controllers: _controllers,
          notifyParent: () => setState(() {}),
          child: Form(
            key: _formKey,
            child: Column(
              children: [
                // Dynamic field rendering
                ...widget.fields.map((field) => Padding(
                      padding:
                          const EdgeInsets.only(bottom: UIConstants.spacing16),
                      child: field.buildField(
                        controller: _controllers[field.fieldKey]!,
                        colorScheme: colorScheme,
                        onChanged: () => setState(() {}),
                      ),
                    )),

                const SizedBox(height: UIConstants.spacing24),

                // Submit button
                ModernButton(
                  text: widget.submitButtonText,
                  type: ModernButtonType.primary,
                  size: ModernButtonSize.large,
                  isLoading: widget.isLoading,
                  onPressed: widget.isLoading ? null : _handleSubmit,
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  void _handleSubmit() {
    if (_formKey.currentState!.validate()) {
      // Dynamic cross-field match for any password-confirm group
      final Map<String, String> passwordByGroup = {};
      final Map<String, String> confirmByGroup = {};
      for (final entry in _controllers.entries) {
        final key = entry.key;
        final field = _fieldByKey[key];
        final props = field?.customProperties ?? const {};
        final isPassword = props['isPassword'] == true;
        if (!isPassword) continue;
        final String? groupId = props['groupId'];
        if (groupId == null) continue;
        final bool isConfirm = props['isConfirm'] == true;
        if (isConfirm) {
          confirmByGroup[groupId] = entry.value.text;
        } else {
          passwordByGroup[groupId] = entry.value.text;
        }
      }
      for (final gid in confirmByGroup.keys) {
        final confirm = confirmByGroup[gid] ?? '';
        final pass = passwordByGroup[gid] ?? '';
        if (confirm.isNotEmpty && confirm != pass) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Passwords do not match')),
          );
          return;
        }
      }

      final formData = <String, dynamic>{};
      for (final entry in _controllers.entries) {
        final key = entry.key;
        final field = _fieldByKey[key];
        final value = entry.value.text.trim();

        // Skip fields that are marked as non-submittable (e.g., DataGrid)
        final props = field?.customProperties ?? const {};
        final bool excludeFromSubmit = props['excludeFromSubmit'] == true;
        if (excludeFromSubmit) {
          continue;
        }

        // Skip confirm entries for any password group
        final bool isPassword = props['isPassword'] == true;
        final bool isConfirm = props['isConfirm'] == true;
        if (isPassword && isConfirm) continue;

        final bool assignByJsonPaths = props['assignByJsonPaths'] == true;
        if (assignByJsonPaths) {
          // If composite and empty -> skip adding base key
          if (value.isEmpty) {
            continue;
          }
          final Map<String, dynamic>? map = _tryDecodeMap(value);
          if (map != null) {
            map.forEach((path, v) {
              if (path is String) {
                _assignValueByPath(formData, path, v);
              }
            });
            continue;
          }
          // If not decodable, also skip to avoid sending invalid base key
          continue;
        }

        formData[key] = value;
      }
      widget.onSubmit(formData);
    }
  }

  dynamic _readValueByPath(Map<String, dynamic>? source, String path) {
    if (source == null) return null;
    final segments = path.split('.');
    dynamic current = source;
    for (final segment in segments) {
      if (current is Map<String, dynamic> && current.containsKey(segment)) {
        current = current[segment];
      } else {
        return null;
      }
    }
    return current;
  }

  void _assignValueByPath(
      Map<String, dynamic> target, String path, dynamic value) {
    final segments = path.split('.');
    Map<String, dynamic> current = target;
    for (int i = 0; i < segments.length; i++) {
      final seg = segments[i];
      final bool isLast = i == segments.length - 1;
      if (isLast) {
        current[seg] = value;
      } else {
        if (current[seg] is! Map<String, dynamic>) {
          current[seg] = <String, dynamic>{};
        }
        current = current[seg] as Map<String, dynamic>;
      }
    }
  }

  String _encodeMap(Map<String, dynamic> map) {
    return const JsonEncoder().convert(map);
  }

  Map<String, dynamic>? _tryDecodeMap(String value) {
    try {
      final decoded = const JsonDecoder().convert(value);
      if (decoded is Map<String, dynamic>) return decoded;
      return null;
    } catch (_) {
      return null;
    }
  }
}

/// Inherited scope to provide access to the form's controllers for advanced shared fields
class EntityFormScope extends InheritedWidget {
  final Map<String, TextEditingController> controllers;
  final VoidCallback notifyParent;

  const EntityFormScope({
    super.key,
    required this.controllers,
    required this.notifyParent,
    required Widget child,
  }) : super(child: child);

  static EntityFormScope? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<EntityFormScope>();
  }

  @override
  bool updateShouldNotify(covariant EntityFormScope oldWidget) {
    return oldWidget.controllers != controllers;
  }
}
