import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/validator/validator.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/modules/applicationDemo/enums/otp_method.dart'; import 'package:test_sa/modules/applicationDemo/models/application_demo_request_model.dart'; import 'package:test_sa/modules/applicationDemo/models/role_model.dart'; import 'package:test_sa/modules/applicationDemo/providers/application_demo_request_provider.dart'; import 'package:test_sa/modules/applicationDemo/widgets/otp_method_selection_dialog.dart'; import 'package:test_sa/modules/applicationDemo/widgets/otp_verification_bottom_sheet.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; import 'package:test_sa/new_views/common_widgets/custom_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/multiple_item_drop_down_menu.dart'; import 'package:test_sa/providers/loading_list_notifier.dart'; class ApplicationDemoRequestFormScreen extends StatefulWidget { static const String routeName = '/demo_request_form'; const ApplicationDemoRequestFormScreen({Key? key}) : super(key: key); @override State createState() => _ApplicationDemoRequestFormScreenState(); } class _ApplicationDemoRequestFormScreenState extends State { final GlobalKey _formKey = GlobalKey(); final TextEditingController _fullNameController = TextEditingController(); final TextEditingController _emailController = TextEditingController(); final TextEditingController _mobileController = TextEditingController(); final TextEditingController _companyNameController = TextEditingController(); List _selectedRoles = []; bool _isSubmitting = false; String? _rolesValidationError; bool _formSubmitted = false; // Track if form has been submitted @override void initState() { super.initState(); // Fetch roles when the screen initializes WidgetsBinding.instance.addPostFrameCallback((_) { final provider = Provider.of(context, listen: false); provider.fetchRoles(); }); } @override void dispose() { _fullNameController.dispose(); _emailController.dispose(); _mobileController.dispose(); _companyNameController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final provider = Provider.of(context); return Scaffold( backgroundColor: AppColor.scaffoldBackground(context), appBar: const DefaultAppBar(title: 'Demo Request'), body: Form( key: _formKey, autovalidateMode: AutovalidateMode.disabled, child: Column( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ AppTextFormField( controller: _fullNameController, labelText: 'Full Name *', textInputType: TextInputType.name, validator: (value) { if (!_formSubmitted && _fullNameController.text.isEmpty) return null; if (_fullNameController.text.isEmpty) return 'Full Name is required'; return null; }, ), 16.height, AppTextFormField( controller: _emailController, labelText: 'Email Address *', textInputType: TextInputType.emailAddress, validator: (value) { if (!_formSubmitted && _emailController.text.isEmpty) return null; if (_emailController.text.isEmpty) return 'Email is required'; if (!Validator.isEmail(_emailController.text)) return 'Invalid email format'; return null; }, ), 16.height, AppTextFormField( controller: _mobileController, labelText: 'Mobile Number *', textInputType: TextInputType.phone, validator: (value) { if (!_formSubmitted && _mobileController.text.isEmpty) return null; if (_mobileController.text.isEmpty) return 'Mobile Number is required'; if (!Validator.isPhoneNumber(_mobileController.text)) return 'Invalid mobile number'; return null; }, ), 16.height, AppTextFormField( controller: _companyNameController, labelText: 'Company Name *', textInputType: TextInputType.text, validator: (value) { if (!_formSubmitted && _companyNameController.text.isEmpty) return null; if (_companyNameController.text.isEmpty) return 'Company Name is required'; return null; }, ), 16.height, MultipleItemDropDownMenu( context: context, title: 'Select Roles *', initialValue: _selectedRoles, staticData: provider.roles, loading: provider.roleLoading, showAsFullScreenDialog: true, onSelect: (selectedRoles) { setState(() { _selectedRoles = selectedRoles ?? []; _rolesValidationError = null; // Clear error when roles are selected }); }, ), if (_rolesValidationError != null) Padding( padding: const EdgeInsets.only(top: 8, left: 16), child: Text( _rolesValidationError!, style: AppTextStyles.tinyFont.copyWith( color: AppColor.red30, ), ), ), ], ).paddingAll(16).expanded, FooterActionButton.footerContainer( context: context, child: AppFilledButton( label: 'Submit', buttonColor: AppColor.primary10, maxWidth: true, loading: _isSubmitting, onPressed: _isSubmitting ? null : _submitRequest, ), ), ], ), ), ); } Future _submitRequest() async { // Mark form as submitted setState(() { _formSubmitted = true; }); // Validate form fields if (!_formKey.currentState!.validate()) { return; } // Validate roles selection if (_selectedRoles.isEmpty) { setState(() { _rolesValidationError = 'Please select at least one role'; }); return; } showDialog( context: context, builder: (BuildContext context) { return OtpMethodSelectionDialog( onMethodSelected: (OtpMethod method) { _submitRequestWithOtpMethod(method); }, ); }, ); } Future _submitRequestWithOtpMethod(OtpMethod otpMethod) async { setState(() { _isSubmitting = true; }); try { final provider = Provider.of(context, listen: false); final otpSent = await provider.sendOtp( fullName: _fullNameController.text.trim(), phoneNumber: _mobileController.text.trim(), email: _emailController.text.trim(), typeSend: otpMethod.value, ); if (otpSent) { if (mounted) { setState(() { _isSubmitting = false; }); await context.showBottomSheet( OtpVerificationBottomSheet( otpMethod: otpMethod.value, onOtpVerified: (String otp) async { await _verifyOtpAndComplete(otp, otpMethod); }, onResend: () async { await provider.sendOtp( fullName: _fullNameController.text.trim(), phoneNumber: _mobileController.text.trim(), email: _emailController.text.trim(), typeSend: otpMethod.value, ); }, onChangeMethod: () { _submitRequest(); }, ), isDismissible: false, title: 'Verify OTP', showCancelButton: true, ); } } else { if (mounted) { setState(() { _isSubmitting = false; }); context.showConfirmDialog( provider.errorMessage ?? 'Failed to send OTP. Please try again.', ); } } } catch (e) { if (mounted) { setState(() { _isSubmitting = false; }); context.showConfirmDialog('An error occurred: $e'); } } } Future _verifyOtpAndComplete(String otp, OtpMethod otpMethod) async { // Close the bottom sheet Navigator.pop(context); // Show loading setState(() { _isSubmitting = true; }); try { final provider = Provider.of(context, listen: false); // Verify OTP - pass email or phoneNumber based on selected method final otpVerified = await provider.verifyOtp( email: otpMethod == OtpMethod.email ? _emailController.text.trim() : null, phoneNumber: otpMethod == OtpMethod.sms ? _mobileController.text.trim() : null, otpCode: otp, ); if (otpVerified) { // OTP verified, now submit the demo request final request = ApplicationDemoRequestModel( fullName: _fullNameController.text.trim(), emailAddress: _emailController.text.trim(), mobileNumber: _mobileController.text.trim(), companyName: _companyNameController.text.trim(), roleIds: _selectedRoles.map((role) => role.identifier ?? '').toList(), roleNames: _selectedRoles.map((role) => role.name ?? '').toList(), // status: 'Pending', requestDate: DateTime.now(), ); final success = await provider.submitApplicationDemoRequest(request); if (mounted) { setState(() { _isSubmitting = false; }); if (success) { context.showConfirmDialog( provider.successMessage ?? 'Your demo request has been verified and submitted successfully. We will contact you soon!', onTap: () { Navigator.of(context).pop(); // Close dialog Navigator.of(context).pop(); // Go back to login }, ); } else { context.showConfirmDialog( provider.errorMessage ?? 'Failed to submit demo request. Please try again.', ); } } } else { // OTP verification failed if (mounted) { setState(() { _isSubmitting = false; }); context.showConfirmDialog( provider.errorMessage ?? 'Invalid OTP code. Please try again.', ); } } } catch (e) { if (mounted) { setState(() { _isSubmitting = false; }); context.showConfirmDialog('OTP verification failed: $e'); } } } }