import 'dart:io';
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import '../services/tflite_service.dart';
import '../services/database_helper.dart';
import '../models/palm_record.dart';
import '../widgets/palm_bounding_box.dart';
import '../services/app_strings.dart';
import '../theme/locale_controller.dart';
import 'batch_report_screen.dart';

class AnalysisScreen extends StatefulWidget {
  const AnalysisScreen({super.key});

  @override
  State<AnalysisScreen> createState() => _AnalysisScreenState();
}

class _AnalysisScreenState extends State<AnalysisScreen> with SingleTickerProviderStateMixin {
  final TfliteService _tfliteService = TfliteService();
  final DatabaseHelper _dbHelper = DatabaseHelper();

  late AnimationController _scanningController;
  bool _isAnalyzing = false;
  File? _selectedImage;
  List<DetectionResult>? _detections;
  String? _errorMessage;

  // One batch groups every image analyzed during this screen visit.
  late final String _batchId = 'batch_${DateTime.now().millisecondsSinceEpoch}_${Random().nextInt(1 << 32)}';

  // Multi-image pick progress.
  int _batchTotal = 0;
  int _batchProcessed = 0;
  int _batchSkipped = 0;

  @override
  void initState() {
    super.initState();
    _scanningController = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );
    _initModel();
  }

  Future<void> _initModel() async {
    try {
      await _tfliteService.initModel();
    } catch (e) {
      if (mounted) {
        setState(() {
          _errorMessage = AppStrings.tp('analysis_init_error', {'error': '$e'});
        });
      }
    }
  }

  Future<void> _processGalleryImage() async {
    final images = await _tfliteService.pickMultiImage();
    if (images.isEmpty) return;

    if (mounted) {
      setState(() {
        _isAnalyzing = true;
        _detections = null;
        _errorMessage = null;
        _batchTotal = images.length;
        _batchProcessed = 0;
        _batchSkipped = 0;
      });
      _scanningController.repeat(reverse: true);
      // Give the UI a frame to paint the loading state
      await Future.delayed(const Duration(milliseconds: 50));
    }

    for (final image in images) {
      if (!mounted) return;
      setState(() => _selectedImage = File(image.path));

      try {
        // 1. Run Inference
        final stopwatch = Stopwatch()..start();
        final detections = await _tfliteService.runInference(image.path);
        stopwatch.stop();

        if (detections.isEmpty) {
          setState(() => _batchSkipped++);
          continue;
        }

        // 2. Persist Image to Documents Directory
        final appDocDir = await getApplicationDocumentsDirectory();
        final fileName = p.basename(image.path);
        final persistentPath = p.join(appDocDir.path, 'palm_${DateTime.now().millisecondsSinceEpoch}_$fileName');
        await File(image.path).copy(persistentPath);

        // 3. Update UI
        if (mounted) {
          setState(() {
            _detections = detections;
            _selectedImage = File(persistentPath);
          });
        }

        // 4. Save to Database
        final best = detections.first;
        final record = PalmRecord(
          imagePath: persistentPath,
          ripenessClass: best.className,
          confidence: best.confidence,
          timestamp: DateTime.now(),
          x1: best.normalizedBox.left,
          y1: best.normalizedBox.top,
          x2: best.normalizedBox.right,
          y2: best.normalizedBox.bottom,
          detections: detections.map((d) => {
            'className': d.className,
            'classIndex': d.classIndex,
            'confidence': d.confidence,
            'x1': d.normalizedBox.left,
            'y1': d.normalizedBox.top,
            'x2': d.normalizedBox.right,
            'y2': d.normalizedBox.bottom,
          }).toList(),
          batchId: _batchId,
          inferenceMs: stopwatch.elapsedMilliseconds,
        );

        await _dbHelper.insertRecord(record);
        setState(() => _batchProcessed++);
      } catch (e) {
        setState(() => _batchSkipped++);
        debugPrint('Analysis error for ${image.path}: $e');
      }
    }

    if (mounted) {
      setState(() {
        _isAnalyzing = false;
      });
      _scanningController.stop();
      _scanningController.reset();

      if (_batchProcessed > 0) {
        Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => BatchReportScreen(batchId: _batchId)),
        );
      } else {
        setState(() {
          _errorMessage = AppStrings.t('analysis_no_detections_batch');
        });
      }
    }
  }

  bool _isHealthAlert(String label) {
    return label == 'Empty_Bunch' || label == 'Abnormal';
  }

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<String>(
      valueListenable: LocaleController.localeCode,
      builder: (context, _, _) => _buildScaffold(context),
    );
  }

  Widget _buildScaffold(BuildContext context) {
    final colorScheme = Theme.of(context).colorScheme;
    return Scaffold(
      appBar: AppBar(title: Text(AppStrings.t('analysis_appbar_title'))),
      body: Stack(
        children: [
          Column(
            children: [
              Expanded(
                child: Center(
                  child: _selectedImage == null
                      ? Text(AppStrings.t('analysis_select_photo_hint'))
                      : AspectRatio(
                          aspectRatio: 1.0,
                          child: Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Stack(
                              children: [
                                // Main Image
                                ClipRRect(
                                  borderRadius: BorderRadius.circular(12),
                                  child: Image.file(
                                    _selectedImage!,
                                    fit: BoxFit.contain,
                                    width: double.infinity,
                                    height: double.infinity,
                                  ),
                                ),
                                // Bounding Box Overlays
                                if (_detections != null)
                                  Positioned.fill(
                                    child: LayoutBuilder(
                                      builder: (context, constraints) {
                                        return Stack(
                                          children: _detections!
                                              .map((d) => PalmBoundingBox(
                                                    normalizedRect: d.normalizedBox,
                                                    label: d.className,
                                                    confidence: d.confidence,
                                                    constraints: constraints,
                                                  ))
                                              .toList(),
                                        );
                                      },
                                    ),
                                  ),
                                // Scanning Animation
                                if (_isAnalyzing)
                                  _ScanningOverlay(animation: _scanningController, color: colorScheme.primary),
                              ],
                            ),
                          ),
                        ),
                ),
              ),
              if (_detections != null) _buildResultSummary(),
              Padding(
                padding: const EdgeInsets.all(32.0),
                child: ElevatedButton.icon(
                  onPressed: _isAnalyzing ? null : _processGalleryImage,
                  icon: const Icon(Icons.add_a_photo),
                  label: Text(AppStrings.t('analysis_pick_button')),
                  style: ElevatedButton.styleFrom(
                    minimumSize: const Size(double.infinity, 54),
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
                  ),
                ),
              ),
            ],
          ),
          if (_isAnalyzing) _buildLoadingOverlay(),
          if (_errorMessage != null) _buildErrorToast(),
        ],
      ),
    );
  }

  // Bounding box logic replaced by shared PalmBoundingBox widget

  // Removed _getStatusColor local method in favor of DetectionResult.getStatusColor()


  Widget _buildResultSummary() {
    final colorScheme = Theme.of(context).colorScheme;
    final best = _detections!.first;
    return Container(
      padding: const EdgeInsets.all(16),
      margin: const EdgeInsets.symmetric(horizontal: 16),
      decoration: BoxDecoration(
        color: colorScheme.surfaceContainerHighest,
        borderRadius: BorderRadius.circular(12),
        boxShadow: [BoxShadow(color: Colors.black.withValues(alpha: 0.08), blurRadius: 10)],
      ),
      child: Column(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Icon(Icons.check_circle, color: best.getStatusColor(), size: 32),
              const SizedBox(width: 12),
              Text(
                AppStrings.className(best.className),
                style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: colorScheme.onSurface),
              ),
            ],
          ),
          Text(
            AppStrings.tp('confidence_label', {'percent': (best.confidence * 100).toStringAsFixed(1)}),
            style: TextStyle(fontSize: 14, color: colorScheme.onSurface.withValues(alpha: 0.6)),
          ),
          if (_isHealthAlert(best.className))
            Padding(
              padding: const EdgeInsets.only(top: 8.0),
              child: Text(
                AppStrings.t('health_alert_abnormal'),
                style: const TextStyle(color: Colors.red, fontWeight: FontWeight.bold),
              ),
            ),
          if (_detections!.length > 1)
            Padding(
              padding: const EdgeInsets.only(top: 8.0),
              child: Text(
                AppStrings.tp('analysis_bunches_detected', {'count': '${_detections!.length}'}),
                style: TextStyle(fontSize: 13, color: colorScheme.onSurface.withValues(alpha: 0.6)),
              ),
            ),
        ],
      ),
    );
  }

  Widget _buildLoadingOverlay() {
    final isBatch = _batchTotal > 1;
    return Positioned.fill(
      child: BackdropFilter(
        filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
        child: Container(
          color: Colors.black.withValues(alpha: 0.3),
          child: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const CircularProgressIndicator(
                  color: Colors.white,
                  strokeWidth: 6,
                ),
                const SizedBox(height: 24),
                Text(
                  isBatch
                      ? AppStrings.tp('analysis_progress_of', {
                          'current': '${(_batchProcessed + _batchSkipped) + 1}',
                          'total': '$_batchTotal',
                        })
                      : AppStrings.t('ai_analyzing'),
                  style: const TextStyle(
                    color: Colors.white,
                    fontSize: 22,
                    fontWeight: FontWeight.bold,
                    letterSpacing: 1.2,
                  ),
                ),
                Text(
                  isBatch
                      ? AppStrings.tp('analysis_progress_stats', {'processed': '$_batchProcessed', 'skipped': '$_batchSkipped'})
                      : AppStrings.t('analysis_optimizing_hint'),
                  style: const TextStyle(color: Colors.white70, fontSize: 14),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildErrorToast() {
    final colorScheme = Theme.of(context).colorScheme;
    return Positioned(
      bottom: 20,
      left: 20,
      right: 20,
      child: Container(
        padding: const EdgeInsets.all(16),
        decoration: BoxDecoration(
          color: colorScheme.error,
          borderRadius: BorderRadius.circular(12),
          boxShadow: [BoxShadow(color: Colors.black.withValues(alpha: 0.15), blurRadius: 8)],
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Icon(Icons.error_outline, color: colorScheme.onError),
                const SizedBox(width: 8),
                Text(AppStrings.t('error_details_label'), style: TextStyle(color: colorScheme.onError, fontWeight: FontWeight.bold)),
              ],
            ),
            const SizedBox(height: 8),
            Text(
              _errorMessage!,
              style: TextStyle(color: colorScheme.onError, fontSize: 12),
            ),
            const SizedBox(height: 8),
            TextButton(
              onPressed: () => setState(() => _errorMessage = null),
              child: Text(AppStrings.t('dismiss_button'), style: TextStyle(color: colorScheme.onError)),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _scanningController.dispose();
    _tfliteService.dispose();
    super.dispose();
  }
}

class _ScanningOverlay extends StatelessWidget {
  final Animation<double> animation;
  final Color color;

  const _ScanningOverlay({required this.animation, required this.color});

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: animation,
      builder: (context, child) {
        return Stack(
          children: [
            Positioned(
              top: animation.value * MediaQuery.of(context).size.width, // Rough estimation since AspectRatio is 1.0
              left: 0,
              right: 0,
              child: Container(
                height: 4,
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    colors: [
                      Colors.transparent,
                      color.withValues(alpha: 0.8),
                      Colors.transparent,
                    ],
                  ),
                  boxShadow: [
                    BoxShadow(
                      color: color.withValues(alpha: 0.6),
                      blurRadius: 15,
                      spreadRadius: 2,
                    ),
                  ],
                ),
              ),
            ),
          ],
        );
      },
    );
  }
}
