import 'package:flutter/material.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: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; class planclaimsform extends StatefulWidget { const planclaimsform({Key? key}) : super(key: key); @override State createState() => _planclaimsformState(); } class _planclaimsformState extends State { late ApiService apiService; bool isLoading = false; dynamic _token; dynamic empCodeString; dynamic empPrimaryId; dynamic client_id; List> policyList = []; dynamic policyDataIsEmpty = 1; dynamic policyHeading; dynamic policyName; dynamic EmployeePolicy; List> employeeDetails = []; dynamic argumentsData; dynamic claimsDetails; int? fromClaimsPage; dynamic decodedToken; List> departmentList = []; List> policyNumberList = []; int? serviceId; int? policyNumberId; int? selectedMemberId; String? selectedMemberName; String? selectedServiceName; String? selectedPolicyNo; dynamic claimsDepartmentId; dynamic client_branch_id; dynamic policyTypeCondition; dynamic selfDetails; List> employeePolicyList = []; // Declare subjectController and bodyController as instance variables late TextEditingController subjectController; late TextEditingController messageController; late TextEditingController accidentDetailsController; late TextEditingController hospitalNameController; late TextEditingController claimAmountController; late TextEditingController admitDateController; late TextEditingController dischargeDateController; DateTime? accidentDate; DateTime? admitDate; DateTime? dischargeDate; List> filteredPoliciesList = []; // Create a unique form key for each accordion section final GlobalKey formKey = GlobalKey(); @override void initState() { super.initState(); subjectController = TextEditingController(); messageController = TextEditingController(); accidentDetailsController = TextEditingController(); hospitalNameController = TextEditingController(); claimAmountController = TextEditingController(); admitDateController = TextEditingController(); dischargeDateController = TextEditingController(); apiService = ApiService(context); // Initialize ApiService here _loadToken(); // Check if fromClaimsPage is 0 and set serviceId to 'Claims' (id is 2) // if (fromClaimsPage == 0) { // setInitialServiceId(); // } } @override void dispose() { // Dispose the controllers to avoid memory leaks subjectController.dispose(); messageController.dispose(); accidentDetailsController.dispose(); hospitalNameController.dispose(); claimAmountController.dispose(); admitDateController.dispose(); dischargeDateController.dispose(); super.dispose(); } @override void didChangeDependencies() { super.didChangeDependencies(); dynamic arguments = ModalRoute.of(context)!.settings.arguments; if (arguments != null && arguments is Map) { argumentsData = arguments; claimsDetails = argumentsData['claimsDetails']; print(claimsDetails); if (argumentsData.containsKey('fromClaimPage')) { fromClaimsPage = argumentsData['fromClaimPage']; print(fromClaimsPage); } if (fromClaimsPage == 0) { claimsDepartmentId = claimsDetails['department_id']; print(claimsDepartmentId); // employeePolicyList = claimsDetails['EmployeePolicy']; // print('employeePolicyList : $employeePolicyList'); List empList = claimsDetails['EmployeePolicy']; setState(() { employeePolicyList = empList.map((memberList) { return { 'id': int.parse(memberList['id']), 'name': memberList['name'], }; }).toList(); print('employeePolicyList : $employeePolicyList'); }); // if (claimsDetails['department_id'] == 3 || // claimsDetails['department_id'] == 4) { policyTypeCondition = claimsDetails['department_id']; // } else { // String policyType = claimsDetails['policy_type']; // policyTypeCondition = policyType.split('-')[0].trim(); // print('Output : $policyTypeCondition'); // Output: GMC // } } } } void setInitialServiceId(departmentListDetails) { print('departmentList : $departmentListDetails'); for (var department in departmentListDetails) { print(department['id'] == claimsDepartmentId); if (department['id'] == claimsDepartmentId) { setState(() { serviceId = department['id']; }); break; } } } Future _loadToken() async { print('_loadToken'); final SharedPreferences prefs = await SharedPreferences.getInstance(); final String? token = prefs.getString('token'); if (token != null && token.isNotEmpty) { setState(() { _token = token; }); // Decode the JWT token received from the API response decodedToken = Jwt.parseJwt(token); print(decodedToken); client_branch_id = decodedToken['client_branch_id']; empCodeString = prefs.getString('empCode'); print(empCodeString); // Check if emp_code is correct empPrimaryId = prefs.getString('empPrimaryId'); client_id = prefs.getString('client_id'); print(client_id); getActiveAndInactivePolicyDetails('Active'); fetchDepartmentList(); getSelfEmployeeProfile(); } else { // Token is empty or null, handle accordingly (e.g., navigate to login screen) ToastHelper.showErrorToast(context, 'Session Out'); Navigator.pushReplacementNamed(context, 'login'); } } Future getActiveAndInactivePolicyDetails(String status) async { if (client_id == null || empCodeString == null) { return; } print('check 1'); final response = await apiService.getActiveAndInactivePolicyDetails( client_id!, empCodeString!, status, client_branch_id); print('check 1234 $response'); if (response['status'] == 'success') { setState(() { policyList = List>.from(response['data']); }); print(policyList); } else { setState(() { policyDataIsEmpty = 0; }); print('API request failed with status: ${response['status']}'); } } 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 fetchDepartmentList() async { setState(() { isLoading = true; }); try { final response = await apiService.fetchDepartmentList(); if (response['departments'] != null) { List departments = response['departments']; setState(() { departmentList = departments.map((department) { return { 'id': int.parse(department['id']), 'name': department['name'], 'private': department['private'], }; }).toList(); isLoading = false; }); if (fromClaimsPage == 0) { setInitialServiceId(departmentList); } } else { throw Exception('Failed to fetch department list'); } } catch (error) { print('Error fetching department list: $error'); } } void fetchPoliciesBasedOnService(int? serviceId) { if (policyList.isEmpty) { print('Policy list is empty. Ensure data is fetched before filtering.'); return; } setState(() { policyNumberId = null; policyTypeCondition = null; }); print('1111 serviceId : $serviceId'); if (serviceId == 3 || serviceId == 4) { print('2222'); // Filter policies based on the department_id List> filteredPolicies = policyList.where((policy) { return policy['department_id'] == serviceId; }).toList(); print('Filtered matching policies: $filteredPolicies'); // if (filteredPolicies[0]['department_id'] == 3 || // filteredPolicies[0]['department_id'] == 4) { setState(() { // Ensure unique IDs for dropdown values policyNumberList = filteredPolicies.asMap().entries.map((entry) { final index = entry.key; final policy = entry.value; // Assign unique ID return { 'policy_no': policy['policy_no'], 'policy_name': policy['policy_name'], 'id': index + 1 // Use index + 1 as a unique ID }; }).toList(); print('policyNumberList : $policyNumberList'); policyTypeCondition = filteredPolicies[0]['department_id']; print('Output : $policyTypeCondition'); // Output: GMC }); } else if (serviceId == 2) { setState(() { // Ensure unique IDs for dropdown values policyNumberList = policyList.asMap().entries.map((entry) { final index = entry.key; final policy = entry.value; // Assign unique ID return { 'policy_no': policy['policy_no'], 'policy_name': policy['policy_name'], 'id': index + 1 // Use index + 1 as a unique ID }; }).toList(); print('policyNumberList : $policyNumberList'); policyTypeCondition = serviceId; print('Output : $policyTypeCondition'); }); } else { setState(() { policyTypeCondition = null; }); } } void fetchMemberBasedOnPolicy(selectedPolicyNo) { if (policyList.isEmpty) { print('Policy list is empty. Ensure data is fetched before filtering.'); return; } if (serviceId == 3 || serviceId == 4) { // Filter policies based on the department_id print('policyNumberId : $policyNumberId'); filteredPoliciesList = policyList.where((policy) { return policy['policy_no'] == selectedPolicyNo; }).toList(); print('Filtered matching policy_no: $filteredPoliciesList'); if (filteredPoliciesList.isNotEmpty) { // Assuming you need to access the first matched policy Map firstPolicy = filteredPoliciesList.first; // Check if 'EmployeePolicy' key exists and is a List if (firstPolicy.containsKey('EmployeePolicy') && firstPolicy['EmployeePolicy'] is List) { List empList = firstPolicy['EmployeePolicy']; setState(() { employeePolicyList = empList.map((memberList) { return { 'id': int.parse(memberList['id']), 'name': memberList['name'], }; }).toList(); print('employeePolicyList : $employeePolicyList'); }); } else { print('No EmployeePolicy found in the filtered policy.'); setState(() { employeePolicyList = []; // Clear the list or handle it as needed }); } } else { print('No policies matched the selected policy number.'); setState(() { employeePolicyList = []; // Clear the list or handle it as needed }); } } else if (serviceId == 2) { filteredPoliciesList = policyList.where((policy) { return policy['policy_no'] == selectedPolicyNo; }).toList(); print('Filtered matching policy_no: $filteredPoliciesList'); } } Future sendFormDataToApi() async { setState(() { isLoading = true; }); print(employeePolicyList[0]['name']); print('Help $filteredPoliciesList'); try { Map formData = { 'opener': 'user', 'department_id': serviceId, 'subject': subjectController.text, 'body': messageController.text, // 'policy_id': fromClaimsPage == 0 // ? claimsDetails['client_policy_id'] // : policyNumberId, 'emp_code': decodedToken['emp_code'] != null ? decodedToken['emp_code'] : '', 'mobile_number': decodedToken['mobile'] != null ? decodedToken['mobile'] : '', 'email': decodedToken['email_corporate'] != null ? decodedToken['email_corporate'] : '', 'fullname': decodedToken['name'] != null ? decodedToken['name'] : '', 'client_id': selfDetails['client_id'], 'relationship': selfDetails['relationship'], 'gender': selfDetails['gender'], 'age': calculateAge(selfDetails['dob']).toString(), 'policy_name': serviceId == 1 ? null : (fromClaimsPage == 0 ? claimsDetails['policy_name'] : filteredPoliciesList[0]['policy_name']), 'tpa': serviceId == 1 ? null : (fromClaimsPage == 0 ? claimsDetails['tpa_name'] : filteredPoliciesList[0]['tpa_name']), 'insurer': serviceId == 1 ? null : (fromClaimsPage == 0 ? claimsDetails['insurer_name'] : filteredPoliciesList[0]['insurer_name']), }; // Conditionally add fields based on the first word in policy_type if (policyTypeCondition == 3) { String formattedAccidentDate = DateFormat('yyyy-MM-dd').format(accidentDate!); // formData['accident_details'] = accidentDetailsController.text; formData['accident_details'] = messageController.text; formData['accident_date'] = formattedAccidentDate; formData['claim_amount'] = claimAmountController.text; formData['policyholder_name'] = employeePolicyList[0]['name']; formData['member_name'] = selectedMemberName; formData['emp_policy_id'] = selectedMemberId; } else if (policyTypeCondition == 4) { formData['hospital_name'] = hospitalNameController.text; formData['admit_date'] = admitDateController.text; formData['discharge_date'] = dischargeDateController.text; formData['claim_amount'] = claimAmountController.text; formData['policyholder_name'] = employeePolicyList[0]['name']; formData['member_name'] = selectedMemberName; formData['emp_policy_id'] = selectedMemberId; } // Convert integer values to strings formData = formData.map((key, value) => MapEntry(key, value.toString())); final response = await apiService.sendFormDataToApi(formData); if (response['success'] == 1) { ToastHelper.showSuccessToast(context, response['message']); serviceId = null; departmentList.clear(); setState(() { isLoading = false; }); Navigator.pushNamed(context, 'claims'); print('Form data submitted successfully'); } else { print('Failed to submit form data: ${response['status']}'); } } catch (e) { print('Error submitting form data: $e'); } } Future _pickAccidentDate(BuildContext context) async { final DateTime? pickedDate = await showDatePicker( context: context, initialDate: accidentDate ?? DateTime.now(), firstDate: DateTime(2000), lastDate: DateTime.now(), ); if (pickedDate != null && pickedDate != accidentDate) { setState(() { accidentDate = pickedDate; }); } } Future _pickFromToDate(BuildContext context) async { final DateTimeRange? pickedDateRange = await showDateRangePicker( context: context, firstDate: DateTime(2000), lastDate: DateTime(2100), initialDateRange: admitDate != null && dischargeDate != null ? DateTimeRange(start: admitDate!, end: dischargeDate!) : null, ); if (pickedDateRange != null) { setState(() { admitDate = pickedDateRange.start; dischargeDate = pickedDateRange.end; admitDateController.text = DateFormat('yyyy-MM-dd').format(admitDate!); dischargeDateController.text = DateFormat('yyyy-MM-dd').format(dischargeDate!); }); } } int calculateAge(String dob) { DateTime birthDate = DateTime.parse(dob); // Parse the dob string DateTime currentDate = DateTime.now(); int age = currentDate.year - birthDate.year; // Adjust age if the birthday has not occurred yet this year if (currentDate.month < birthDate.month || (currentDate.month == birthDate.month && currentDate.day < birthDate.day)) { age--; } return age; } @override Widget build(BuildContext context) { return 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.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( flex: 1, child: InkWell( onTap: () { Navigator.pushNamed( context, fromClaimsPage == 0 ? 'claims' : '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.center : MainAxisAlignment.start, children: [ Text( fromClaimsPage == 0 ? claimsDetails[ 'policy_name'] : 'Raise a Request', 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: [ buildDropdownField( 'Service', (value) { setState(() { serviceId = value; selectedServiceName = departmentList .firstWhere( (serList) => serList[ 'id'] == value, orElse: () => {'name': ''}, )['name']; policyNumberId = null; if (fromClaimsPage == 1) { // Reset policy number selection fetchPoliciesBasedOnService( serviceId); } }); }, fromClaimsPage == 0, departmentList, 'name', serviceId, // Pass current serviceId as selectedValue ), SizedBox(height: 15), if (fromClaimsPage == 1 && (serviceId == 3 || serviceId == 4 || serviceId == 2)) buildDropdownField( 'Select Policy', (value) { setState(() { policyNumberId = value; selectedMemberId = null; String? selectedPolicyNo = policyNumberList.firstWhere( (item) => item[ 'id'] == value, orElse: () => { 'policy_no': '' })['policy_no']; if (selectedPolicyNo != null && fromClaimsPage == 1) { fetchMemberBasedOnPolicy( selectedPolicyNo); } }); }, fromClaimsPage == 0, policyNumberList, 'policy_no', policyNumberId, // Pass current policyNumberId as selectedValue ), SizedBox(height: 15), if (serviceId == 3 || serviceId == 4) buildDropdownField( 'Member Name', (value) { setState(() { selectedMemberId = value; selectedMemberName = employeePolicyList .firstWhere( (member) => member[ 'id'] == value, orElse: () => { 'name': '' }, )['name']; }); }, false, employeePolicyList, 'name', selectedMemberId, // Pass current selectedMemberId as selectedValue ), buildTextField('Subject', subjectController), SizedBox(height: 15), buildTextAreaField( serviceId == 3 ? 'Accident Details' : 'Message', messageController), SizedBox(height: 15), // if (policyTypeCondition == // 3) // buildTextField( // 'Accident Details', // accidentDetailsController), SizedBox(height: 15), if (policyTypeCondition == 4) buildTextField( 'Hospital Name', hospitalNameController), SizedBox(height: 15), if (policyTypeCondition == 3) buildDatePickerField( label: 'Accident Date', selectedDate: accidentDate, allowFuture: false, onDateSelected: (selectedDate) { setState(() { accidentDate = selectedDate; }); }, ), SizedBox(height: 15), // buildTextAreaField( // 'Accident Details', // accidentDetailsController), // SizedBox(height: 15), if (policyTypeCondition == 4) InkWell( onTap: () => _pickFromToDate( context), child: InputDecorator( decoration: InputDecoration( labelText: 'Admit Date - Discharge Date', border: OutlineInputBorder(), ), child: Text( admitDate != null && dischargeDate != null ? '${admitDateController.text} to ${dischargeDateController.text}' : 'Select Admit and Discharge Dates', style: TextStyle( color: Colors .black), ), ), ), SizedBox(height: 15), if (serviceId == 3 || serviceId == 4) buildTextField( 'Claim Amount', claimAmountController, TextInputType.number, ), SizedBox(height: 15), ], ), ), ], ), ), ], ), 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 // For example: if (index == 0) { Navigator.pushNamed(context, 'home'); } else if (index == 1) { Navigator.pushNamed(context, 'claims'); } else if (index == 2) { Navigator.pushNamed(context, 'profile'); } else if (index == 3) { Navigator.pushNamed(context, 'help'); // Navigator.pushNamed(context, 'help'); } else if (index == 4) { Navigator.pushNamed(context, 'wellness'); } }, icons: [ Icons.home_outlined, Icons.sticky_note_2_outlined, Icons.person_outline_outlined, Icons.headset_mic_outlined, Icons.health_and_safety_outlined, ], labels: [ "Home", "Claim", "Profile", "Help", "Wellness", ], // 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, 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, validator: (value) { if (value == null || value.isEmpty) { return 'Please enter the $label'; } return null; }, ); } Widget buildDatePickerField({ required String label, required DateTime? selectedDate, required bool allowFuture, required ValueChanged onDateSelected, }) { return InkWell( onTap: () { _pickAccidentDate(context); }, child: InputDecorator( decoration: InputDecoration( labelText: label, border: OutlineInputBorder(), ), child: Text( selectedDate != null ? DateFormat('yyyy-MM-dd').format(selectedDate) : 'Select $label', style: TextStyle(color: Colors.black), ), ), ); } Widget buildDropdownField( String label, void Function(int?) onChanged, bool readOnly, List> itemsList, String displayField, int? selectedValue // Added selectedValue parameter ) { return DropdownButtonFormField( value: selectedValue, decoration: InputDecoration(labelText: label), items: itemsList.map>((item) { return DropdownMenuItem( value: item['id'], // Ensure 'id' is correctly referenced child: Text(item[displayField]), ); }).toList(), onChanged: readOnly ? null : onChanged, validator: (value) { if (value == null) { return 'Please select a $label'; } return null; }, ); } }