import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:http/http.dart' as http; import 'package:nhance_partner/data/utils/toastNotification.dart'; import 'package:nhance_partner/presentation/themes/indicators/text_field_theme_inline_editor.dart'; import '../../../../core/config/env.dart'; import '../../../../core/services/api_service.dart'; import '../../../../data/services/auth_service.dart'; import '../../../../data/utils/validators.dart'; class Insurer extends ConsumerStatefulWidget { final String? id; final Map? data; final VoidCallback onSubmit; const Insurer({ super.key, this.id, this.data, required this.onSubmit, }); @override ConsumerState createState() => InsurerState(); } class InsurerState extends ConsumerState { final _formKey = GlobalKey(); late ApiService apiService; List tabHeader = ['name', 'code']; String? _token; dynamic selectedId; Map controllers = {}; bool get _isEdit => selectedId != null; Map dataDetails() { final data = { 'name': controllers['name']?.text.trim(), 'short_name': controllers['code']?.text.trim(), }; if (_isEdit) { data['id'] = selectedId.toString(); } return data; } @override void initState() { super.initState(); apiService = ApiService(); for (final field in tabHeader) { controllers[field] = TextEditingController(); } _initializeToken(); updateData(); } void updateData() { if (widget.data == null) return; final data = widget.data!; selectedId = data['id']; controllers['name']?.text = data['name']?.toString() ?? ''; controllers['code']?.text = data['short_name']?.toString() ?? ''; } Future _initializeToken() async { _token = await AuthService.getToken(); } Future handleSave() async { final nameEmpty = controllers['name'] == null || controllers['name']!.text.trim().isEmpty; final codeEmpty = controllers['code'] == null || controllers['code']!.text.trim().isEmpty; if (nameEmpty && codeEmpty) { ToastHelper.showWarningToast( context, 'Insurer and Short Name are required', ); return; } if (nameEmpty) { ToastHelper.showWarningToast(context, 'Insurer is required'); return; } if (codeEmpty) { ToastHelper.showWarningToast(context, 'Short Name is required'); return; } if (!_formKey.currentState!.validate()) return; await createUserData(dataDetails()); } void refresh() { widget.onSubmit(); setState(() { selectedId = null; for (final controller in controllers.values) { controller.clear(); } }); } Future createUserData(Map data) async { if (_token == null) { throw Exception('Token not found. Please log in.'); } try { final response = await http.post( Uri.parse('${Env.apiUrl}master/saveInsurer'), headers: { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, }, body: jsonEncode(data), ); if (response.statusCode == 200) { final responseBody = jsonDecode(response.body); final message = responseBody['message']?.toString() ?? (_isEdit ? 'Insurer updated successfully.' : 'Insurer created successfully.'); if (responseBody['status'] == 200 || responseBody['status'] == 'success') { refresh(); if (mounted) { ToastHelper.showSuccessToast(context, message); } } else if (mounted) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text(_isEdit ? 'Insurer Update Failed' : 'Insurer Save Failed'), content: Text(message), actions: [ TextButton( child: const Text('OK'), onPressed: () => Navigator.of(context).pop(), ), ], ); }, ); } } else if (response.statusCode == 403) { await apiService.clearLocalStorageAndRedirect(); } } catch (e) { if (mounted) { ToastHelper.showWarningToast(context, 'Error saving insurer: $e'); } } } @override void dispose() { for (final controller in controllers.values) { controller.dispose(); } super.dispose(); } @override Widget build(BuildContext context) { return SelectionArea( child: Row( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end, children: [ buildFormFields(), const SizedBox(width: 5), InkWell( onTap: handleSave, child: Container( padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 6), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.0), color: const Color(0xFF2E7D6E), ), child: Text( 'Save', style: GoogleFonts.inter(color: Colors.white, fontSize: 10), ), ), ), const SizedBox(width: 5), InkWell( onTap: refresh, child: Container( padding: const EdgeInsets.all(6.0), decoration: BoxDecoration( color: const Color(0xFF2E7D6E), borderRadius: BorderRadius.circular(5.0), ), child: const Icon(Icons.refresh, size: 13, color: Colors.white), ), ), ], ), ); } Widget buildFormFields() { return Form( key: _formKey, child: Row( children: [ buildName(), const SizedBox(width: 10), buildShortName(), ], ), ); } Widget buildName() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Insurer *', style: _textStyle), const SizedBox(width: 10), ThemedFormInlineField( controller: controllers['name']!, validator: (value) => Validators.requiredField(value, 'name'), txtwidth: MediaQuery.of(context).size.width * 0.15, borderColor: const Color(0xFFE2E8F0), highlightColor: const Color(0xFF50A398), isdense: true, errFieldHgt: 0, ), ], ); } Widget buildShortName() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Short Name *', style: _textStyle), const SizedBox(width: 10), ThemedFormInlineField( controller: controllers['code']!, validator: (value) => Validators.requiredField(value, 'code'), inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9\-_ ]')), ], txtwidth: MediaQuery.of(context).size.width * 0.15, borderColor: const Color(0xFFE2E8F0), highlightColor: const Color(0xFF50A398), isdense: true, errFieldHgt: 0, ), ], ); } static final _textStyle = GoogleFonts.inter( fontSize: 11, fontWeight: FontWeight.w600, ); }