import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flux/features/company/bloc/company_settings_cubit.dart'; import 'package:flux/features/company/models/company_model.dart'; import 'package:flux/features/settings/document_sequence/blocs/document_sequence_cubit.dart'; import 'package:flux/features/settings/document_sequence/ui/document_sequence_section.dart'; import 'package:image_picker/image_picker.dart'; class CompanySettingsScreen extends StatefulWidget { const CompanySettingsScreen({super.key}); @override State createState() => _CompanySettingsScreenState(); } class _CompanySettingsScreenState extends State { final _formKey = GlobalKey(); final _nameCtrl = TextEditingController(); final _vatCtrl = TextEditingController(); final _fiscalCodeCtrl = TextEditingController(); // Nuovo final _sdiCtrl = TextEditingController(); // Nuovo final _addressCtrl = TextEditingController(); final _cityCtrl = TextEditingController(); final _provinceCtrl = TextEditingController(); // Nuovo final _zipCtrl = TextEditingController(); final _phoneCtrl = TextEditingController(); final _emailCtrl = TextEditingController(); final _disclaimerCtrl = TextEditingController(); bool _isInitialized = false; @override void initState() { super.initState(); final cubit = context.read(); cubit.initSettings(); if (cubit.state.status == CompanySettingsStatus.ready && cubit.state.company != null) { _syncControllers(cubit.state.company!); } } @override void dispose() { _nameCtrl.dispose(); _vatCtrl.dispose(); _fiscalCodeCtrl.dispose(); // Nuovo _sdiCtrl.dispose(); // Nuovo _addressCtrl.dispose(); _cityCtrl.dispose(); _provinceCtrl.dispose(); // Nuovo _zipCtrl.dispose(); _phoneCtrl.dispose(); _emailCtrl.dispose(); _disclaimerCtrl.dispose(); super.dispose(); } void _syncControllers(CompanyModel company) { if (_nameCtrl.text.isEmpty) _nameCtrl.text = company.name; if (_vatCtrl.text.isEmpty) _vatCtrl.text = company.vatId; if (_fiscalCodeCtrl.text.isEmpty) { _fiscalCodeCtrl.text = company.fiscalCode; // Nuovo } if (_sdiCtrl.text.isEmpty) _sdiCtrl.text = company.sdi; // Nuovo if (_provinceCtrl.text.isEmpty) { _provinceCtrl.text = company.province; // Nuovo } if (_addressCtrl.text.isEmpty) _addressCtrl.text = company.address; if (_cityCtrl.text.isEmpty) _cityCtrl.text = company.city; if (_zipCtrl.text.isEmpty) _zipCtrl.text = company.zipCode; if (_phoneCtrl.text.isEmpty) _phoneCtrl.text = company.phone ?? ''; if (_emailCtrl.text.isEmpty) _emailCtrl.text = company.email ?? ''; _isInitialized = true; if (_disclaimerCtrl.text.isEmpty) { _disclaimerCtrl.text = company.ticketDisclaimer ?? ''; } } void _flushToCubit() { context.read().updateFields( name: _nameCtrl.text, vatId: _vatCtrl.text, fiscalCode: _fiscalCodeCtrl.text, // Nuovo sdi: _sdiCtrl.text, // Nuovo province: _provinceCtrl.text, address: _addressCtrl.text, city: _cityCtrl.text, zipCode: _zipCtrl.text, phone: _phoneCtrl.text, email: _emailCtrl.text, ticketDisclaimer: _disclaimerCtrl.text, ); } Future _pickAndUploadLogo() async { final picker = ImagePicker(); final companySettingsCubit = context.read(); final pickedFile = await picker.pickImage(source: ImageSource.gallery); if (pickedFile != null && mounted) { // Passiamo i bytes per compatibilità totale con Flutter Web final bytes = await pickedFile.readAsBytes(); companySettingsCubit.uploadLogo(bytes, pickedFile.name); } } void _onLabelFormatChanged(LabelFormat selectedFormat) { double? w; double? h; switch (selectedFormat) { case LabelFormat.small_62x29: w = 62.0; h = 29.0; break; case LabelFormat.medium_54x101: w = 54.0; h = 101.0; break; case LabelFormat.large_102x152: w = 102.0; h = 152.0; break; case LabelFormat.custom: case LabelFormat.none: // Lasciamo i valori null o quelli vecchi break; } context.read().updateFields( labelFormat: selectedFormat, labelWidth: w, labelHeight: h, ); } @override Widget build(BuildContext context) { final theme = Theme.of(context); return Scaffold( appBar: AppBar(title: const Text('Impostazioni Azienda')), body: BlocConsumer( listener: (context, state) { if (state.status == CompanySettingsStatus.ready && !_isInitialized) { _syncControllers(state.company!); } if (state.status == CompanySettingsStatus.success) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Impostazioni salvate con successo!'), backgroundColor: Colors.green, ), ); } if (state.status == CompanySettingsStatus.failure) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(state.errorMessage ?? 'Errore'), backgroundColor: Colors.red, ), ); } }, builder: (context, state) { if (state.company == null) { return const Center(child: CircularProgressIndicator()); } final company = state.company!; return Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 800), child: Form( key: _formKey, child: ListView( padding: const EdgeInsets.all(24.0), children: [ // --- SEZIONE LOGO --- Center( child: Stack( alignment: Alignment.bottomRight, children: [ Container( height: 120, width: 120, decoration: BoxDecoration( color: theme.colorScheme.surfaceContainerHighest, shape: BoxShape.circle, border: Border.all(color: theme.dividerColor), image: company.logoUrl != null ? DecorationImage( image: NetworkImage(company.logoUrl!), fit: BoxFit.contain, ) : null, ), child: company.logoUrl == null ? const Icon( Icons.business, size: 50, color: Colors.grey, ) : null, ), if (state.status == CompanySettingsStatus.uploadingLogo) const Positioned.fill( child: Center(child: CircularProgressIndicator()), ), FloatingActionButton.small( onPressed: state.status == CompanySettingsStatus.uploadingLogo ? null : _pickAndUploadLogo, child: const Icon(Icons.camera_alt), ), ], ), ), const SizedBox(height: 32), // --- SEZIONE DATI PRINCIPALI --- Text( 'Dati Legali', style: theme.textTheme.titleLarge?.copyWith( fontWeight: FontWeight.bold, ), ), const Divider(), const SizedBox(height: 16), TextFormField( controller: _nameCtrl, decoration: const InputDecoration( labelText: 'Ragione Sociale', prefixIcon: Icon(Icons.badge), ), validator: (val) => val == null || val.isEmpty ? 'Campo obbligatorio' : null, ), const SizedBox(height: 16), Row( children: [ Expanded( child: TextFormField( controller: _vatCtrl, decoration: const InputDecoration( labelText: 'Partita IVA', prefixIcon: Icon(Icons.receipt_long), ), ), ), const SizedBox(width: 16), Expanded( child: TextFormField( controller: _fiscalCodeCtrl, decoration: const InputDecoration( labelText: 'Codice Fiscale', ), ), ), const SizedBox(width: 16), Expanded( child: TextFormField( controller: _sdiCtrl, decoration: const InputDecoration( labelText: 'Codice SDI', ), ), ), ], ), const SizedBox(height: 16), // --- SEZIONE INDIRIZZO E CONTATTI --- Text( 'Sede e Contatti', style: theme.textTheme.titleLarge?.copyWith( fontWeight: FontWeight.bold, ), ), const Divider(), const SizedBox(height: 16), TextFormField( controller: _addressCtrl, decoration: const InputDecoration( labelText: 'Indirizzo (Via e numero civico)', prefixIcon: Icon(Icons.location_on), ), ), const SizedBox(height: 16), Row( children: [ Expanded( flex: 2, child: TextFormField( controller: _cityCtrl, decoration: const InputDecoration( labelText: 'Città', ), ), ), const SizedBox(width: 16), Expanded( flex: 1, child: TextFormField( controller: _provinceCtrl, decoration: const InputDecoration( labelText: 'Provincia (es. MI)', ), ), ), const SizedBox(width: 16), Expanded( flex: 1, child: TextFormField( controller: _zipCtrl, decoration: const InputDecoration(labelText: 'CAP'), ), ), ], ), const SizedBox(height: 16), Row( children: [ Expanded( child: TextFormField( controller: _phoneCtrl, decoration: const InputDecoration( labelText: 'Telefono', prefixIcon: Icon(Icons.phone), ), ), ), const SizedBox(width: 16), Expanded( child: TextFormField( controller: _emailCtrl, decoration: const InputDecoration( labelText: 'Email', prefixIcon: Icon(Icons.email), ), ), ), ], ), const SizedBox(height: 16), BlocProvider( create: (context) => DocumentSequenceCubit(state.company!.id!) ..loadSequences(), child: const DocumentSequenceSection(), ), const SizedBox(height: 16), // Sezione Disclaimer Text( "Note Legali Ricevuta", style: theme.textTheme.titleMedium, ), const SizedBox(height: 8), TextFormField( controller: _disclaimerCtrl, maxLines: 5, decoration: const InputDecoration( hintText: "Inserisci qui la liberatoria legale che apparirà sulla ricevuta dei ticket...", border: OutlineInputBorder(), ), onChanged: (val) => context .read() .updateFields(ticketDisclaimer: val), ), const SizedBox(height: 24), // Sezione Etichette Text( "Configurazione Etichette", style: theme.textTheme.titleMedium, ), const SizedBox(height: 8), DropdownButtonFormField( initialValue: company.labelFormat, decoration: const InputDecoration( prefixIcon: Icon(Icons.label_outline), labelText: "Formato Stampa Etichetta", ), items: LabelFormat.values .map( (f) => DropdownMenuItem( value: f, child: Text( f.name.replaceAll('_', ' ').toUpperCase(), ), ), ) .toList(), onChanged: (val) { if (val != null) { _onLabelFormatChanged(val); } }, ), const SizedBox(height: 48), // --- PULSANTE SALVATAGGIO --- SizedBox( height: 50, child: ElevatedButton.icon( onPressed: state.status == CompanySettingsStatus.saving ? null : () { if (_formKey.currentState!.validate()) { _flushToCubit(); context .read() .saveSettings(); } }, icon: state.status == CompanySettingsStatus.saving ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2, ), ) : const Icon(Icons.save), label: const Text( 'Salva Impostazioni', style: TextStyle(fontSize: 16), ), ), ), ], ), ), ), ); }, ), ); } }