import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:intl/intl.dart'; import 'package:jwt_decode/jwt_decode.dart'; import 'package:nhance_app_pwa/customAppBar/customAppBar.dart'; import 'package:nhance_app_pwa/pages/postEnrollment/service/api_service.dart'; import 'package:nhance_app_pwa/pages/service/SessionManager.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../customAppBar/customFooter.dart'; import '../../customAppBar/responsive.dart'; import '../../customAppBar/tabs.dart'; import '../../customAppBar/toastHelper.dart'; import 'package:http/http.dart' as http; import '../service/TokenService.dart'; import '../service/popup_helper.dart'; class tickets extends StatefulWidget { const tickets({Key? key}) : super(key: key); @override State createState() => _ticketsState(); } class _ticketsState extends State { late ApiService apiService; bool isLoading = false; dynamic _token; dynamic empCodeString; dynamic empPrimaryId; dynamic client_id; List> policyList = []; dynamic policyDataIsEmpty = 1; int? fromClaimsPage; Map? decodedToken; List> departmentList = []; List> policyNumberList = []; dynamic serviceId; dynamic policyNumberId; String? selectedMemberName; String? selectedServiceName; String? selectedPolicyNo; dynamic client_branch_id; dynamic mobileNo; dynamic policyTypeCondition; dynamic client_policy_id; dynamic selfDetails; dynamic emailId; List> employeePolicyList = []; // Declare subjectController and bodyController as instance variables late TextEditingController subjectController; late TextEditingController messageController; final List> serviceList = [ {"id": 1, "name": "Sales"}, {"id": 2, "name": "Service"}, ]; List> filteredPoliciesList = []; // Create a unique form key for each accordion section final GlobalKey formKey = GlobalKey(); bool isServiceValid = true; bool isPolicyValid = true; bool isSubjectValid = true; bool isMessageValid = true; final session = SessionManager(); @override void initState() { super.initState(); subjectController = TextEditingController(); messageController = TextEditingController(); apiService = ApiService(context); // Initialize ApiService here _loadToken(); } @override void dispose() { // Dispose the controllers to avoid memory leaks subjectController.dispose(); messageController.dispose(); super.dispose(); } Future _loadToken() async { print('_loadToken'); final String? token = await TokenService.getPostToken(); if (token != null && token.isNotEmpty) { setState(() { _token = token; }); // Decode the JWT token received from the API response decodedToken = Jwt.parseJwt(token); print(decodedToken); mobileNo = session.mobileNo; client_branch_id = session.empClientBranchId; empCodeString = session.empCodeString; print(empCodeString); // Check if emp_code is correct empPrimaryId = session.empPrimaryId; client_id = session.client_id; emailId = session.empEmailCorporate; print(client_id); getActiveAndInactivePolicyDetails(); getSelfEmployeeProfile(); } } Future getActiveAndInactivePolicyDetails() async { if (client_id == null || empCodeString == null) { return; } try { // Call both APIs final responseActive = await apiService.getActiveAndInactivePolicyDetails( client_id!, empCodeString!, 'Active', client_branch_id, mobileNo,emailId); final responseInactive = await apiService.getActiveAndInactivePolicyDetails(client_id!, empCodeString!, 'Inactive', client_branch_id, mobileNo,emailId); final bool isActiveSuccess = responseActive['status'] == 'success' && responseActive['data'] != null; final bool isInactiveSuccess = responseInactive['status'] == 'success' && responseInactive['data'] != null; final List> activeData = isActiveSuccess ? List>.from(responseActive['data']) : []; final List> inactiveData = isInactiveSuccess ? List>.from(responseInactive['data']) : []; final combinedPolicies = [...activeData, ...inactiveData]; setState(() { policyList = combinedPolicies; policyDataIsEmpty = combinedPolicies.isEmpty ? 0 : 1; }); print("Merged policyList: $policyList"); } catch (e) { print('Error occurred while fetching policies: $e'); setState(() { policyDataIsEmpty = 0; }); } } Future getSelfEmployeeProfile() async { print(getSelfEmployeeProfile); if (client_id == null || empCodeString == null) { return; } print('check 1'); final response = await apiService.getSelfEmployeeProfileDetails( client_id!, empCodeString!, client_branch_id!); print('check 1'); if (response['status'] == 'success') { if (response.containsKey('data')) { setState(() { selfDetails = response['data']; print(selfDetails); }); } else { // Handle other status messages if needed // ToastHelper.showErrorToast( // context, 'API request failed with status: ${data['status']}'); print('API request failed with status: ${response['status']}'); } } else { print('API request failed with status: ${response['status']}'); } } Future sendFormDataToApi() async { setState(() { isServiceValid = serviceId != null; isSubjectValid = subjectController.text.trim().isNotEmpty; isMessageValid = messageController.text.trim().isNotEmpty; // ✅ Skip policy validation if service is "Sales" if (selectedServiceName == "Sales") { isPolicyValid = true; } else { isPolicyValid = policyNumberId != null; } }); if (isServiceValid && isPolicyValid && isSubjectValid && isMessageValid) { // Proceed to submit } else { ToastHelper.showErrorToast(context, 'Please Fill Required Fields'); return; } setState(() { isLoading = true; }); final SharedPreferences prefs = await SharedPreferences.getInstance(); final String? emp_id = prefs.getString('empPrimaryId'); // print('Check One'); // print(employeePolicyList[0]['name']); // print('Help $filteredPoliciesList'); try { print('Check One'); Map formData = { 'email': decodedToken?['email_corporate'], 'empcode': decodedToken?['emp_code'], 'message': messageController.text, 'mobile': decodedToken?['mobile'], 'name': decodedToken?['name'], 'policy_no': policyNumberId, 'subject': subjectController.text, 'ticket_type': selectedServiceName, 'client_id': selfDetails['client_id'], 'client_branch_id': selfDetails['client_branch_id'], }; print('formData $formData'); // if (policyTypeCondition == 1) { // formData['policyholder_name'] = employeePolicyList[0]['name']; // formData['member_name'] = selectedMemberName; // } else { // // formData['policyholder_name'] = employeePolicyList[0]['name']; // formData['member_name'] = selectedMemberName; // } // Convert integer values to strings formData = formData.map((key, value) => MapEntry(key, value.toString())); final response = await apiService.sendTicketFormDataToApi(formData); if (response['status'] == 'success') { ToastHelper.showSuccessToast(context, response['message']); serviceId = null; policyNumberId = null; subjectController.clear(); messageController.clear(); setState(() { isLoading = false; }); context.go('/raisedTicketHistory'); print('Form data submitted successfully'); } else { print('Failed to submit form data: ${response['status']}'); } } catch (e) { print('Error submitting form data: $e'); } } @override Widget build(BuildContext context) { return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) { if (didPop) return; context.go('/help'); }, child: Scaffold( backgroundColor: Colors.white, appBar: CustomAppBar(), body: Stack(children: [ SingleChildScrollView( child: Container( padding: Responsive.isDesktop(context) ? EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.2, // 30% of screen width as horizontal padding vertical: MediaQuery.of(context).size.height * 0.05, // 5% of screen height as vertical padding ) : EdgeInsets.all(10), color: Colors.white, child: Column(children: [ Card( elevation: 5, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15.0), // Set border radius here ), child: Container( decoration: BoxDecoration( color: Colors.white, // Set background color to white borderRadius: BorderRadius.circular( 15.0), // Set border radius for Container ), padding: Responsive.isDesktop(context) ? EdgeInsets.only( top: 15, bottom: 15, left: 15, right: 15) : EdgeInsets.only( top: 10, bottom: 10, left: 10, right: 10), // Add padding to the container child: Row( children: [ Expanded( flex: 12, child: Container( alignment: Alignment.centerLeft, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( decoration: BoxDecoration( color: Color( 0xFFFFFCE5), // Set background color for the container borderRadius: BorderRadius.circular( 10), // Set border radius for the container ), padding: Responsive.isDesktop(context) ? EdgeInsets.only( top: 20, bottom: 20, left: 0, right: 0) : EdgeInsets.only( top: 10, bottom: 10, left: 10, right: 10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( // flex: 1, child: InkWell( onTap: () { context.go('/help'); }, child: Icon( Icons .chevron_left, // Replace with your desired icon color: Color(0xFF000000), size: 30, ), ), ), Expanded( flex: 11, child: Row( mainAxisAlignment: Responsive .isDesktop(context) ? MainAxisAlignment.start : MainAxisAlignment.start, children: [ Text( 'Raise a Query', textAlign: TextAlign.start, style: GoogleFonts.poppins( fontSize: Responsive .isDesktop( context) ? 20 : 16, fontWeight: FontWeight.w600, color: Color(0xFF000000), ), ) ], ), ) ], ), // Space between rows // Add more rows as needed ], ), ), SizedBox(height: 15), Container( child: Column( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: double.infinity, alignment: Alignment.centerLeft, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Form( key: formKey, child: Column( children: [ Column( crossAxisAlignment: CrossAxisAlignment .start, children: [ buildDropdownField< int>( 'Type', (value) { setState(() { serviceId = value; selectedServiceName = serviceList .firstWhere( (serList) => serList[ 'id'] == value, orElse: () => { 'name': '' }, )['name']; isServiceValid = true; }); }, false, serviceList, 'name', serviceId, valueKey: 'id', ), if (!isServiceValid) Text( 'Please select a Service', style: TextStyle( color: Colors .red)), ], ), SizedBox(height: 15), if (selectedServiceName != "Sales") Column( crossAxisAlignment: CrossAxisAlignment .start, children: [ buildDropdownField< String>( 'Policy Number', (value) { setState( () { policyNumberId = value; isPolicyValid = true; }); }, false, policyList, 'policy_no', policyNumberId, valueKey: 'policy_no', combineField: 'policy_name', ), if (!isPolicyValid) Text( 'Please select a policy', style: TextStyle( color: Colors.red)), ], ), SizedBox(height: 15), Column( crossAxisAlignment: CrossAxisAlignment .start, children: [ buildTextField( 'Subject', subjectController), if (!isSubjectValid) Text( 'Please enter the Subject', style: TextStyle( color: Colors.red)), SizedBox( height: 15), buildTextAreaField( 'Message', messageController), if (!isMessageValid) Text( 'Please enter the Message', style: TextStyle( color: Colors.red)), ]), ], ), ), ], ), ), ], ), SizedBox(height: 15), Row( children: [ Expanded( flex: 12, child: Container( alignment: Alignment.centerRight, child: ElevatedButton( onPressed: () { sendFormDataToApi(); }, child: Text( 'Send', style: GoogleFonts.poppins( color: Colors.white), ), style: ElevatedButton .styleFrom( backgroundColor: Color(0xFFE26728), shape: RoundedRectangleBorder( borderRadius: BorderRadius .circular(5), ), ), ), ), ), ], ), ], ), ), ], ))), ], ), ), ), SizedBox(height: Responsive.isDesktop(context) ? 40 : 60), ]), )), if (isLoading) Container( color: Color(0x98FFFCE5), // Semi-transparent background child: Center( child: // Your GIF loader widget Image.asset( height: 60, width: 60, 'assets/nhance-loader.gif'), // Adjust path to your GIF loader ), ), if (Responsive.isDesktop(context)) Align( alignment: Alignment.bottomCenter, child: Container( width: double.infinity, // Make the footer full width child: CustomFooter(), ), ), ]), // floatingActionButton: Responsive.isDesktop(context) // ? null // : FloatingActionButton( // onPressed: () { // Navigator.pushNamed(context, 'chatbot'); // }, // child: Icon(Icons.chat), // ), floatingActionButtonLocation: Responsive.isDesktop(context) ? null : FloatingActionButtonLocation.miniEndFloat, bottomNavigationBar: Responsive.isDesktop(context) ? null : CustomBottomNavigationBar( onTabChanged: (index) { // Add your navigation logic here // repositionBotman(); if (index == 0) { context.push('/home'); } else if (index == 1) { context.push('/claims'); } else if (index == 2) { context.push('/faqs'); } else if (index == 3) { context.push('/profile'); } else if (index == 4) { context.push('/help'); } // else if (index == 4) { // // context.push('/wellness'); // // Wellness tab clicked → show popup // if(!isRetailLoggedIn) // PopupHelper.showRedirectPopup( // context: context, // apiService: apiService, // empPrimaryId: session.empPrimaryId, // ); // } }, icons: [ Icons.home_outlined, Icons.sticky_note_2_outlined, Icons.question_answer_outlined, Icons.person_outline_outlined, Icons.headset_mic_outlined, ], labels: ["Home", "Claims", "FAQs", "Profile","Help"], initialIndex: 0, // Initial index of the bottom navigation bar ), )); } Widget buildTextField(String label, TextEditingController controller, [TextInputType keyboardType = TextInputType.text]) { return TextFormField( controller: controller, decoration: InputDecoration(labelText: label), keyboardType: keyboardType, maxLength: 150, validator: (value) { if (value == null || value.isEmpty) { return 'Please enter the $label'; } return null; }, ); } Widget buildTextAreaField(String label, TextEditingController controller) { return TextFormField( controller: controller, decoration: InputDecoration(labelText: label), maxLines: 5, maxLength: 1500, validator: (value) { if (value == null || value.isEmpty) { return 'Please enter the $label'; } return null; }, ); } Widget buildDropdownField( String label, void Function(T?) onChanged, bool readOnly, List> itemsList, String displayField, T? selectedValue, { String valueKey = 'id', String? combineField, }) { return DropdownButtonFormField( value: selectedValue, decoration: InputDecoration(labelText: label), items: itemsList.map>((item) { // ▼ If combineField is provided → show "policy_no - policy_type" String textToShow; if (combineField != null) { textToShow = "${item[displayField]} - ${item[combineField]}"; } else { textToShow = item[displayField].toString(); } return DropdownMenuItem( value: item[valueKey] as T, // ✅ cast to generic type child: Text(textToShow), // always display as String ); }).toList(), onChanged: readOnly ? null : onChanged, validator: (value) { if (value == null) { return 'Please select a $label'; } return null; }, ); } }