import 'package:flutter/material.dart'; import 'dart:ui'; import '../theme.dart'; import 'customize_setup_screen.dart'; class BusinessSetupScreen extends StatefulWidget { const BusinessSetupScreen({super.key}); @override State createState() => _BusinessSetupScreenState(); } class _BusinessSetupScreenState extends State { final TextEditingController _nameController = TextEditingController(); final TextEditingController _gstinController = TextEditingController(); String _selectedCategory = 'supermarket'; bool _isNameValid = false; final Set _selectedDocs = {'GSTIN', 'FSSAI'}; final Map _uploadedDocs = {}; @override void initState() { super.initState(); _nameController.addListener(() { setState(() { _isNameValid = _nameController.text.trim().isNotEmpty; }); }); } @override void dispose() { _nameController.dispose(); _gstinController.dispose(); super.dispose(); } final List> _categories = [ {'id': 'supermarket', 'name': 'Supermarket', 'icon': Icons.shopping_cart}, {'id': 'restaurant', 'name': 'Restaurant', 'icon': Icons.restaurant}, {'id': 'clothing', 'name': 'Clothing', 'icon': Icons.checkroom}, {'id': 'kirana', 'name': 'Kirana', 'icon': Icons.local_mall}, {'id': 'grocers', 'name': 'Grocers', 'icon': Icons.storefront}, {'id': 'others', 'name': 'Others', 'icon': Icons.grid_view}, ]; Widget _buildDocChip(String label, IconData icon) { final theme = Theme.of(context); final isSelected = _selectedDocs.contains(label); return InkWell( onTap: () { setState(() { if (isSelected) { _selectedDocs.remove(label); } else { _selectedDocs.add(label); } }); }, borderRadius: BorderRadius.circular(8), child: Container( constraints: const BoxConstraints(minHeight: 48), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: isSelected ? const Color(0xFFFAF0F0) : Colors.white, borderRadius: BorderRadius.circular(8), border: Border.all( color: isSelected ? const Color(0xFFAF101A) : theme.colorScheme.outlineVariant, width: isSelected ? 1.5 : 1, ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( icon, size: 16, color: isSelected ? const Color(0xFFAF101A) : Colors.grey[600], ), const SizedBox(width: 8), Text( label, style: TextStyle( fontSize: 13, fontWeight: FontWeight.bold, color: isSelected ? const Color(0xFFAF101A) : Colors.grey[800], ), ), ], ), ), ); } Widget _buildUploadSection(String docName, IconData icon) { final theme = Theme.of(context); final isUploaded = _uploadedDocs.containsKey(docName); return Container( margin: const EdgeInsets.only(top: 12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: theme.colorScheme.outlineVariant, width: 1, ), ), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Icon(icon, color: const Color(0xFFAF101A), size: 18), const SizedBox(width: 8), Text( '$docName Document', style: theme.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.onSurface, ), ), ], ), IconButton( icon: const Icon(Icons.close, size: 18, color: Colors.grey), onPressed: () { setState(() { _selectedDocs.remove(docName); }); }, padding: EdgeInsets.zero, constraints: const BoxConstraints(), ) ], ), const SizedBox(height: 12), if (isUploaded) ...[ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.grey[50], borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey[200]!), ), child: Row( children: [ Container( width: 50, height: 50, decoration: BoxDecoration( color: Colors.red[50], borderRadius: BorderRadius.circular(8), ), child: const Center( child: Icon( Icons.insert_drive_file, color: Color(0xFFAF101A), size: 24, ), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _uploadedDocs[docName] ?? 'Attached_document.pdf', style: const TextStyle( fontSize: 13, fontWeight: FontWeight.bold, overflow: TextOverflow.ellipsis, ), ), const SizedBox(height: 2), const Text( 'Size: 1.2 MB • Ready', style: TextStyle( fontSize: 11, color: Colors.grey, ), ), ], ), ), IconButton( icon: const Icon(Icons.delete_outline, color: Colors.red), onPressed: () { setState(() { _uploadedDocs.remove(docName); }); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('$docName attachment removed.'), behavior: SnackBarBehavior.floating, ), ); }, ), ], ), ), ] else ...[ CustomPaint( painter: DashedBorderPainter( color: const Color(0xFFAF101A), radius: 16, ), child: Container( width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 16), decoration: BoxDecoration( color: Colors.transparent, borderRadius: BorderRadius.circular(16), ), child: Column( children: [ const Icon( Icons.cloud_upload_outlined, color: Color(0xFFAF101A), size: 32, ), const SizedBox(height: 8), Text( 'Upload your $docName Proof', style: const TextStyle( fontSize: 13, fontWeight: FontWeight.bold, color: Colors.grey, ), ), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton.icon( onPressed: () { setState(() { _uploadedDocs[docName] = '${docName.toLowerCase().replaceAll(' ', '_')}_scan.jpg'; }); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('📸 Captured photo for $docName!'), backgroundColor: const Color(0xFFAF101A), behavior: SnackBarBehavior.floating, ), ); }, icon: const Icon(Icons.camera_alt, size: 14), label: const Text('Take Photo'), style: ElevatedButton.styleFrom( minimumSize: const Size(0, 36), backgroundColor: const Color(0xFFAF101A), foregroundColor: Colors.white, elevation: 1, padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), ), const SizedBox(width: 8), OutlinedButton.icon( onPressed: () { setState(() { _uploadedDocs[docName] = 'gallery_${docName.toLowerCase().replaceAll(' ', '_')}.png'; }); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('📂 Uploaded $docName from gallery!'), backgroundColor: Colors.green, behavior: SnackBarBehavior.floating, ), ); }, icon: const Icon(Icons.photo_library, size: 14), label: const Text('From Gallery'), style: OutlinedButton.styleFrom( foregroundColor: const Color(0xFFAF101A), side: const BorderSide(color: Color(0xFFAF101A)), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), ), ], ), ], ), ), ), ], ], ), ), ); } @override Widget build(BuildContext context) { final theme = Theme.of(context); final padding = context.responsivePadding; return Scaffold( appBar: AppBar( leading: IconButton( icon: const Icon(Icons.arrow_back, color: Color(0xFFBA1A20)), onPressed: () => Navigator.pop(context), ), title: Text( 'PozoApp', style: theme.textTheme.headlineMedium?.copyWith( color: theme.colorScheme.primary, fontWeight: FontWeight.bold, ), ), actions: [ Padding( padding: EdgeInsets.symmetric(horizontal: padding), child: Center( child: Text( 'Step 3 of 5', style: theme.textTheme.labelMedium?.copyWith( fontWeight: FontWeight.bold, ), ), ), ) ], bottom: PreferredSize( preferredSize: const Size.fromHeight(6), child: Row( children: List.generate(5, (index) { return Expanded( child: Container( height: 6, margin: const EdgeInsets.symmetric(horizontal: 2.0), decoration: BoxDecoration( color: index <= 2 ? theme.colorScheme.primary : theme.colorScheme.surfaceContainerHighest, borderRadius: BorderRadius.circular(3), ), ), ); }), ), ), ), body: SafeArea( child: Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 600), child: Column( children: [ Expanded( child: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Complete verification', style: theme.textTheme.headlineLarge?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 6), Text( 'Verify your business details to start selling.', style: theme.textTheme.bodyMedium, ), const SizedBox(height: 16), // Name Field Input Text( 'Business/Shop Name *', style: theme.textTheme.labelSmall?.copyWith( color: theme.colorScheme.onSurface, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), TextField( controller: _nameController, decoration: const InputDecoration( hintText: 'e.g. Sharma General Store', ), style: const TextStyle(fontWeight: FontWeight.bold), ), const SizedBox(height: 16), // Category selection Block Text( 'Business Type *', style: theme.textTheme.labelSmall?.copyWith( color: theme.colorScheme.onSurface, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 10), // Category custom grid (2x3) GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 16, mainAxisSpacing: 16, childAspectRatio: 2.2, ), itemCount: _categories.length, itemBuilder: (context, index) { final cat = _categories[index]; final isSelected = _selectedCategory == cat['id']; return InkWell( onTap: () { setState(() { _selectedCategory = cat['id']; }); }, borderRadius: BorderRadius.circular(16), child: Container( decoration: BoxDecoration( color: isSelected ? const Color(0xFFAF101A).withOpacity(0.08) : Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: isSelected ? const Color(0xFFAF101A) : const Color(0xFFE2E2E2), width: isSelected ? 2 : 1, ), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.01), blurRadius: 4, offset: const Offset(0, 2), ) ], ), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Center( child: Icon( cat['icon'], color: isSelected ? const Color(0xFFAF101A) : Colors.grey[600], size: 26, ), ), const SizedBox(height: 6), Center( child: Text( cat['name'], textAlign: TextAlign.center, style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: isSelected ? const Color(0xFFAF101A) : Colors.grey[800], ), ), ) ], ), ), ); }, ), const SizedBox(height: 16), // GSTIN optional Input group with Verify button on right-side Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'GSTIN', style: theme.textTheme.labelSmall?.copyWith( color: theme.colorScheme.onSurface, fontWeight: FontWeight.bold, ), ), Text( '(Optional)', style: theme.textTheme.bodySmall?.copyWith( color: Colors.grey[500], ), ) ], ), const SizedBox(height: 8), Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: TextField( controller: _gstinController, textCapitalization: TextCapitalization.characters, decoration: const InputDecoration( hintText: '15-DIGIT GST NUMBER', ), style: const TextStyle(fontWeight: FontWeight.bold, letterSpacing: 1.2), ), ), const SizedBox(width: 12), ElevatedButton( onPressed: () { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('GSTIN Verified Successfully!'), backgroundColor: Colors.green, behavior: SnackBarBehavior.floating, ), ); }, style: ElevatedButton.styleFrom( minimumSize: const Size(0, 48), backgroundColor: theme.colorScheme.primary, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), ), child: const Text('Verify'), ), ], ), const SizedBox(height: 6), Text( "Auto-fetches address & legal name on verification.", style: TextStyle(fontSize: 11, color: Colors.grey[500]), ), const SizedBox(height: 16), // Shop Location Detect Text( 'Shop Location *', style: theme.textTheme.labelSmall?.copyWith( color: theme.colorScheme.onSurface, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), InkWell( onTap: () { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('📍 Location detected: Sector 62, Noida, UP'), backgroundColor: Colors.green, behavior: SnackBarBehavior.floating, ), ); }, borderRadius: BorderRadius.circular(16), child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: theme.colorScheme.outlineVariant, ), ), child: Row( children: [ Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: theme.colorScheme.primary.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon( Icons.my_location, color: theme.colorScheme.primary, size: 20, ), ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( 'Detect current location', style: theme.textTheme.bodyLarge?.copyWith( fontWeight: FontWeight.bold, fontSize: 15, ), ), const SizedBox(height: 2), Text( 'Pin shop address automatically', style: TextStyle( fontSize: 11, color: Colors.grey[600], ), ), ], ), ), Icon( Icons.chevron_right, color: Colors.grey[400], ), ], ), ), ), const SizedBox(height: 16), // Identity/License Documents Text( 'Identity / License Documents (Select all that apply)', style: theme.textTheme.labelSmall?.copyWith( color: theme.colorScheme.onSurface, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 10), Wrap( spacing: 8, runSpacing: 8, children: [ _buildDocChip('GSTIN', Icons.description), _buildDocChip('FSSAI', Icons.restaurant), _buildDocChip('Aadhar', Icons.badge_outlined), _buildDocChip('Udhyog Aadhar', Icons.domain), _buildDocChip('PAN', Icons.credit_card), ], ), const SizedBox(height: 8), // Expanded Upload Sections ..._selectedDocs.map((doc) { IconData docIcon = Icons.description; if (doc == 'GSTIN') docIcon = Icons.description; if (doc == 'FSSAI') docIcon = Icons.restaurant; if (doc == 'Aadhar') docIcon = Icons.badge_outlined; if (doc == 'Udhyog Aadhar') docIcon = Icons.domain; if (doc == 'PAN') docIcon = Icons.credit_card; return _buildUploadSection(doc, docIcon); }), const SizedBox(height: 16), // Shop Facade Photo upload area Text( 'Shop Facade Photo *', style: theme.textTheme.labelSmall?.copyWith( color: theme.colorScheme.onSurface, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), InkWell( onTap: () { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('📸 Camera / Photo Upload Clicked!'), behavior: SnackBarBehavior.floating, ), ); }, child: Container( width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 24), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: theme.colorScheme.outlineVariant, ), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: theme.colorScheme.primary.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon( Icons.add_a_photo_outlined, color: theme.colorScheme.primary, size: 24, ), ), const SizedBox(height: 12), Text( 'Upload front view', style: theme.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.onSurface, ), ), const SizedBox(height: 4), Text( 'Clear photo showing shop board', style: TextStyle( fontSize: 11, color: Colors.grey[500], ), ), ], ), ), ), const SizedBox(height: 12), ], ), ), ), ), // Button docked Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), child: ElevatedButton( onPressed: _isNameValid ? () { Navigator.push( context, MaterialPageRoute( builder: (context) => CustomizeSetupScreen( businessName: _nameController.text.trim(), businessType: _selectedCategory, gstin: _gstinController.text.trim(), ), ), ); } : null, style: ElevatedButton.styleFrom( minimumSize: const Size.fromHeight(54), backgroundColor: _isNameValid ? theme.colorScheme.primary : Colors.grey[200], foregroundColor: _isNameValid ? Colors.white : Colors.grey[400], elevation: _isNameValid ? 2 : 0, ), child: const Text('Continue to Verification'), ), ) ], ), ), ), ), ); } } class DashedBorderPainter extends CustomPainter { final Color color; final double strokeWidth; final double gap; final double radius; DashedBorderPainter({ required this.color, this.strokeWidth = 1.5, this.gap = 4.0, this.radius = 16.0, }); @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = color ..strokeWidth = strokeWidth ..style = PaintingStyle.stroke; final RRect rrect = RRect.fromRectAndRadius( Rect.fromLTWH(0, 0, size.width, size.height), Radius.circular(radius), ); try { final Path path = Path()..addRRect(rrect); final Path dashPath = Path(); double distance = 0.0; bool draw = true; for (final PathMetric metric in path.computeMetrics()) { while (distance < metric.length) { final double len = draw ? gap * 1.5 : gap; if (draw) { dashPath.addPath( metric.extractPath(distance, (distance + len).clamp(0.0, metric.length)), Offset.zero, ); } distance += len; draw = !draw; } } canvas.drawPath(dashPath, paint); } catch (e) { // Fallback for platform/renderers (such as Flutter Web HTML renderer) that do not support computeMetrics() canvas.drawRRect(rrect, paint); } } @override bool shouldRepaint(covariant DashedBorderPainter oldDelegate) { return oldDelegate.color != color || oldDelegate.strokeWidth != strokeWidth || oldDelegate.gap != gap || oldDelegate.radius != radius; } }