import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:gen_rentals/Utility/CustomSnackbar.dart'; import 'package:image_picker/image_picker.dart'; import 'package:provider/provider.dart'; import '../../Notifier/HelpAndEnquiryProvider.dart'; import '../../Utility/AppColors.dart'; import '../../Utility/Reusablewidgets.dart'; class HelpTicketScreen extends StatefulWidget { final String? reason; final String sessionId; final String accId; final String orderId; const HelpTicketScreen({ super.key, this.reason, required this.sessionId, required this.accId, required this.orderId }); @override State createState() => _HelpTicketScreenState(); } class _HelpTicketScreenState extends State { final TextEditingController _issueController = TextEditingController(); final TextEditingController _otherReasonController = TextEditingController(); final ImagePicker _picker = ImagePicker(); List _selectedImages = []; String _selectedReason = 'Payment Issues'; final List> createNewTickets = [ { 'title': 'Payment Issues', 'description': 'Get help with payment related problems', 'icon': "assets/svg/rupee_coin_ic.svg", 'color': Color(0xFFFFEFBE), }, { 'title': 'Bill Related Issues', 'description': 'Resolve bill and invoice matters', 'icon': "assets/svg/know_pay.svg", 'color': Color(0xFFCEF9FF), }, { 'title': 'Other Issues', 'description': 'Any other support you need', 'icon': 'assets/svg/help_ic.svg', 'color': Color(0xFFE4E5FF), }, ]; @override void initState() { super.initState(); if (widget.reason != null) { _selectedReason = widget.reason!; } } @override Widget build(BuildContext context) { final showOtherReasonField = _selectedReason == 'Other Issues'; final helpProvider = Provider.of(context); return SafeArea( top: false, child: Scaffold( backgroundColor: AppColors.backgroundRegular, appBar: AppBar( automaticallyImplyLeading: false, backgroundColor: Colors.white, elevation: 0, title: Row( children: [ InkResponse( onTap: () => Navigator.pop(context, true), child: SvgPicture.asset( "assets/svg/continue_left_ic.svg", height: 25, ), ), const SizedBox(width: 10), const Text( "Help?", style: TextStyle( fontSize: 16, fontFamily: "Plus Jakarta Sans", fontWeight: FontWeight.w600, color: Colors.black87, ), ), ], ), ), body: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SectionHeading( title: 'Create New Ticket', textStyle: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), Container( padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 10), decoration: BoxDecoration( color: Color(0xFFE0F4FF), borderRadius: BorderRadius.circular(10), ), child: Text( "order #${ widget.orderId}", style: TextStyle( fontSize: 12, fontFamily: "Plus Jakarta Sans", fontWeight: FontWeight.w400, color: Colors.black87, ), ), ), ], ), const SizedBox(height: 12), _fieldLabel("Reason"), const SizedBox(height: 6), GestureDetector( onTap: _showReasonBottomSheet, child: Container( width: 200, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( color: const Color(0xffFFF3D1), borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( _selectedReason, style: TextStyle( fontSize: 14, fontStyle: FontStyle.normal, fontWeight: FontWeight.w400, color: Colors.black87, ), ), SvgPicture.asset( "assets/svg/edit_ic.svg", height: 25, ), ], ), ), ), const SizedBox(height: 16), if (showOtherReasonField) ...[ _fieldLabel("Enter Reason"), const SizedBox(height: 6), _textField( controller: _otherReasonController, hint: "Write your reason", ), const SizedBox(height: 16), ], _fieldLabel("Tell us your issue?"), const SizedBox(height: 6), _textField( controller: _issueController, hint: "Write your issue", maxLines: 5, ), const SizedBox(height: 16), _fieldLabel("Add Screenshot (optional)"), const SizedBox(height: 6), Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 60, height: 60, decoration: BoxDecoration( color: Colors.grey.shade100, borderRadius: BorderRadius.circular(8), ), child: IconButton( onPressed: _pickImage, icon: Icon( Icons.add, size: 24, color: Colors.grey[600], ), ), ), const SizedBox(height: 8), if (_selectedImages.isNotEmpty) GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 4, crossAxisSpacing: 8, mainAxisSpacing: 8, ), itemCount: _selectedImages.length, itemBuilder: (context, index) { return Stack( children: [ ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.file( _selectedImages[index], fit: BoxFit.cover, width: double.infinity, height: double.infinity, ), ), Positioned( top: 4, right: 4, child: GestureDetector( onTap: () => _removeImage(index), child: Container( padding: const EdgeInsets.all(2), decoration: const BoxDecoration( color: Colors.black54, shape: BoxShape.circle, ), child: const Icon( Icons.close, size: 14, color: Colors.white, ), ), ), ), ], ); }, ), ], ), ), const SizedBox(height: 24), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: helpProvider.isLoading ? null : _submitTicket, style: ElevatedButton.styleFrom( backgroundColor: AppColors.buttonColor, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(28), ), elevation: 0, ), child: helpProvider.isLoading ? const SizedBox( height: 22, width: 22, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2, ), ) : Text( 'Submit', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w400, ), ), ), ), ], ), ), ), ); } Widget _fieldLabel(String text) => Text( text, style: TextStyle( fontSize: 14, fontStyle: FontStyle.normal, fontWeight: FontWeight.w400, color: Colors.black87, ), ); Widget _textField({ required TextEditingController controller, required String hint, int maxLines = 1, }) { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), ), child: TextFormField( controller: controller, maxLines: maxLines, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w400, color: Colors.black87, ), decoration: InputDecoration( hintText: hint, hintStyle: TextStyle( fontSize: 14, fontWeight: FontWeight.w400, color: Colors.grey[400], ), border: InputBorder.none, contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), ), ), ); } Future _pickImage() async { final pickedFile = await _picker.pickImage(source: ImageSource.gallery, imageQuality: 70); if (pickedFile != null) { setState(() { _selectedImages.add(File(pickedFile.path)); }); } } void _removeImage(int index) { setState(() { _selectedImages.removeAt(index); }); } Future _submitTicket() async { final issue = _issueController.text.trim(); final otherReason = _otherReasonController.text.trim(); if (issue.isEmpty) { CustomSnackBar.showWarning( context: context, message: "Please describe your issue", ); return; } if (_selectedReason == 'Other Issues' && otherReason.isEmpty) { CustomSnackBar.showWarning( context: context, message: "Please enter your reason", ); return; } // Determine the reason type based on selected reason String reason; if (_selectedReason == "Payment Issues") { reason = "Payment"; } else if (_selectedReason == "Bill Related Issues") { reason = "Bill"; } else { reason = "Other"; } // If user selected "Other Issues", use the custom reason text final customReason = _selectedReason == 'Other Issues' ? otherReason : null; debugPrint("Reason ========= $reason"); final helpProvider = Provider.of(context, listen: false); await helpProvider.createTicket( sessionId: widget.sessionId, accId: widget.accId, type: reason, description: issue, orderId: "1235", otherReason: customReason.toString(), images: _selectedImages, context: context, ); } void _showReasonBottomSheet() { showModalBottomSheet( context: context, backgroundColor: Colors.white, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20), ), ), builder: (context) { return Container( padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( "Select Your Reason", style: TextStyle( fontSize: 18, fontFamily: "Plus Jakarta Sans", fontWeight: FontWeight.w600, color: Colors.black87, ), ), const SizedBox(height: 16), GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, crossAxisSpacing: 12, mainAxisSpacing: 12, childAspectRatio: 0.99, ), itemCount: createNewTickets.length, itemBuilder: (context, index) { final ticket = createNewTickets[index]; return _buildReasonCard( title: ticket['title'], icon: ticket['icon'], color: ticket['color'], ); }, ), const SizedBox(height: 24), ], ), ); }, ); } Widget _buildReasonCard({ required String title, required String icon, required Color color, }) { return GestureDetector( onTap: () { setState(() => _selectedReason = title); Navigator.pop(context); }, child: Container( padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 1), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( width: 88, height: 88, decoration: BoxDecoration( color: color.withOpacity(0.12), borderRadius: BorderRadius.circular(12), ), child: Center( child: SizedBox( height: 40, width: 40, child: SvgPicture.asset(icon, fit: BoxFit.fitWidth), ), ), ), const SizedBox(height: 8), Text( title, textAlign: TextAlign.center, style: TextStyle( color: AppColors.nearDarkText, fontSize: 14, fontWeight: FontWeight.w400, fontFamily: "Plus Jakarta Sans", ), ), const SizedBox(height: 4), ], ), ), ); } @override void dispose() { _issueController.dispose(); _otherReasonController.dispose(); super.dispose(); } }