import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../bloc/book_bloc.dart'; import '../bloc/navigation_bloc.dart'; import '../models/models.dart'; import '../theme/app_spacing.dart'; class AddBookScreen extends StatefulWidget { const AddBookScreen({super.key}); @override State createState() => _AddBookScreenState(); } class _AddBookScreenState extends State { final _titleController = TextEditingController(); final _authorController = TextEditingController(); final _annotationController = TextEditingController(); String _genre = 'fiction'; bool _initialized = false; @override void didChangeDependencies() { super.didChangeDependencies(); if (!_initialized) { _initialized = true; final navState = context.read().state; final book = navState.selectedBook; final prefilled = navState.prefilledData; final source = book ?? prefilled; if (source != null) { _titleController.text = source.title; _authorController.text = source.author; _annotationController.text = source.annotation; _genre = source.genre.isNotEmpty ? source.genre : 'fiction'; } } } @override void dispose() { _titleController.dispose(); _authorController.dispose(); _annotationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; final textTheme = Theme.of(context).textTheme; final navState = context.read().state; final isEditing = navState.selectedBook != null && navState.prefilledData == null; final title = isEditing ? 'Редактировать' : 'Добавить книгу'; return SafeArea( child: Column( children: [ // Header Padding( padding: const EdgeInsets.fromLTRB( AppSpacing.sm, AppSpacing.sm, AppSpacing.sm, 0, ), child: Row( children: [ IconButton( icon: const Icon(Icons.arrow_back), onPressed: () => context.read().add( isEditing ? NavigateTo(AppScreen.details) : NavigateTo(AppScreen.library), ), ), Text(title, style: textTheme.headlineMedium), ], ), ), Expanded( child: ListView( padding: const EdgeInsets.all(AppSpacing.lg), children: [ // Cover placeholder / scanner trigger GestureDetector( onTap: () => context.read().add( NavigateTo(AppScreen.scanner), ), child: Container( height: 160, decoration: BoxDecoration( border: Border.all(color: colorScheme.outline), borderRadius: BorderRadius.circular( AppSpacing.radiusMedium, ), color: colorScheme.surfaceContainerHighest, ), child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.camera_alt, size: 40, color: colorScheme.primary, ), const SizedBox(height: AppSpacing.sm), Text( 'Загрузить или отсканировать', style: textTheme.bodyMedium?.copyWith( color: colorScheme.onSurface.withValues( alpha: 0.6, ), ), ), ], ), ), ), ), const SizedBox(height: AppSpacing.lg), _field('Название', _titleController, textTheme), const SizedBox(height: AppSpacing.md), _field('Автор', _authorController, textTheme), const SizedBox(height: AppSpacing.md), // Genre dropdown Text('Жанр', style: textTheme.labelMedium), const SizedBox(height: AppSpacing.xs), DropdownButtonFormField( initialValue: _genre, dropdownColor: colorScheme.surface, decoration: const InputDecoration(), items: const [ DropdownMenuItem( value: 'fiction', child: Text('Фантастика'), ), DropdownMenuItem(value: 'fantasy', child: Text('Фэнтези')), DropdownMenuItem(value: 'science', child: Text('Научпоп')), DropdownMenuItem( value: 'biography', child: Text('Биография'), ), DropdownMenuItem( value: 'detective', child: Text('Детектив'), ), DropdownMenuItem(value: 'other', child: Text('Другое')), ], onChanged: (v) => setState(() => _genre = v ?? _genre), ), const SizedBox(height: AppSpacing.md), Text('Аннотация', style: textTheme.labelMedium), const SizedBox(height: AppSpacing.xs), TextField(controller: _annotationController, maxLines: 4), const SizedBox(height: 100), ], ), ), // Bottom actions Container( padding: const EdgeInsets.symmetric( horizontal: AppSpacing.screenPadding, vertical: AppSpacing.md, ), decoration: BoxDecoration( color: colorScheme.surface, border: Border( top: BorderSide(color: colorScheme.outlineVariant), ), boxShadow: [ BoxShadow( color: colorScheme.shadow, blurRadius: 8, offset: const Offset(0, -2), ), ], ), child: Row( children: [ Expanded( child: OutlinedButton( onPressed: () => context.read().add( isEditing ? NavigateTo(AppScreen.details) : NavigateTo(AppScreen.library), ), child: const Text('Отмена'), ), ), const SizedBox(width: AppSpacing.md), Expanded( flex: 2, child: ElevatedButton( onPressed: _save, child: const Text('Сохранить'), ), ), ], ), ), ], ), ); } Widget _field( String label, TextEditingController controller, TextTheme textTheme, ) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(label, style: textTheme.labelMedium), const SizedBox(height: AppSpacing.xs), TextField(controller: controller), ], ); } void _save() { final navState = context.read().state; final existing = navState.selectedBook; final isEditing = existing != null && navState.prefilledData == null; final Book book = ( id: isEditing ? existing.id : '${Random().nextInt(100000)}', title: _titleController.text, author: _authorController.text, genre: _genre, annotation: _annotationController.text, coverUrl: isEditing ? existing.coverUrl : 'https://picsum.photos/seed/newbook/400/600', pages: isEditing ? existing.pages : 0, language: isEditing ? existing.language : 'Russian', publishedYear: isEditing ? existing.publishedYear : DateTime.now().year, rating: isEditing ? existing.rating : 5.0, status: isEditing ? existing.status : 'want_to_read', progress: isEditing ? existing.progress : null, isFavorite: isEditing ? existing.isFavorite : false, ); if (isEditing) { context.read().add(UpdateBook(book)); } else { context.read().add(AddBook(book)); } context.read().add(NavigateTo(AppScreen.library)); } }