import 'dart:async'; // Timer
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive_flutter/hive_flutter.dart'; 
import 'package:path/path.dart' show join;
import 'package:path_provider/path_provider.dart';
import 'package:uuid/uuid.dart';
import 'package:gal/gal.dart'; 

import '../services/gemini_service.dart';
import '../services/ocr_service.dart';
import '../widgets/analyzing_dialog.dart';
import '../models/sake_item.dart';
import '../theme/app_theme.dart';
import 'package:lucide_icons/lucide_icons.dart';
import 'package:image_picker/image_picker.dart'; // Gallery Import
import '../models/user_profile.dart';
import '../providers/theme_provider.dart'; // userProfileProvider


enum CameraMode {
  createItem,
  returnPath,
}

class CameraScreen extends ConsumerStatefulWidget {
  final CameraMode mode;
  const CameraScreen({super.key, this.mode = CameraMode.createItem});

  @override
  ConsumerState<CameraScreen> createState() => _CameraScreenState();
}

class _CameraScreenState extends ConsumerState<CameraScreen> with SingleTickerProviderStateMixin, WidgetsBindingObserver {
  CameraController? _controller;
  Future<void>? _initializeControllerFuture;
  bool _isTakingPicture = false;
  DateTime? _quotaLockoutTime;
  
  // Phase 3-B: Focus & Zoom
  double _minZoom = 1.0;
  double _maxZoom = 1.0;
  double _currentZoom = 1.0;
  double _baseScale = 1.0; // For pinch reference
  
  // Phase 3-B2: Exposure
  double _minExposure = 0.0;
  double _maxExposure = 0.0;
  double _currentExposureOffset = 0.0;
  
  Offset? _focusPoint;
  bool _showFocusRing = false;
  Timer? _focusRingTimer;
  DateTime? _lastExposureUpdate; // Throttling state

  @override
  void initState() {
    super.initState();
    _initializeCamera();
  }

  Future<void> _initializeCamera() async {
    final cameras = await availableCameras();
    final firstCamera = cameras.first;

    _controller = CameraController(
      firstCamera,
      ResolutionPreset.high, 
      enableAudio: false,
      imageFormatGroup: ImageFormatGroup.jpeg,
    );

    _initializeControllerFuture = _controller!.initialize().then((_) async {
       if (!mounted) return;
       // [Phase 3-B] Get Zoom Range
       _minZoom = await _controller!.getMinZoomLevel();
       _maxZoom = await _controller!.getMaxZoomLevel();
       // [Phase 3-B2] Get Exposure Range
       _minExposure = await _controller!.getMinExposureOffset();
       _maxExposure = await _controller!.getMaxExposureOffset();
       
       // [Phase 3-B] Set Auto Focus Mode
       await _controller!.setFocusMode(FocusMode.auto);
       setState(() {});
    });
  }

  @override
  void dispose() {
    _controller?.dispose();
    _focusRingTimer?.cancel();
    super.dispose();
  }

  // ... (Keep existing methods: _capturedImages, _takePicture, _analyzeImages)

  double? _pendingExposureValue;
  bool _isUpdatingExposure = false;

  Future<void> _setExposureSafe(double value) async {
    _pendingExposureValue = value;
    if (_isUpdatingExposure) return;

    _isUpdatingExposure = true;
    while (_pendingExposureValue != null) {
      final valueToSet = _pendingExposureValue!;
      _pendingExposureValue = null;
      try {
        if (_controller != null && _controller!.value.isInitialized) {
          await _controller!.setExposureOffset(valueToSet);
        }
      } catch (e) {
        debugPrint('Exposure update error: $e');
      }
    }
    _isUpdatingExposure = false;
  }

  void _onTapFocus(TapUpDetails details, BoxConstraints constraints) async {
    if (_controller == null || !_controller!.value.isInitialized) return;

    // Normalizing coordinates (0.0 - 1.0)
    final offset = Offset(
      details.localPosition.dx / constraints.maxWidth,
      details.localPosition.dy / constraints.maxHeight,
    );

    try {
      await _controller!.setFocusPoint(offset);
      await _controller!.setFocusMode(FocusMode.auto); 
    } catch (e) {
      // Some devices might not support focus point
      debugPrint('Focus failed: $e');
    }

    if (!mounted) return;

    setState(() {
      _focusPoint = details.localPosition;
      _showFocusRing = true;
    });

    _focusRingTimer?.cancel();
    _focusRingTimer = Timer(const Duration(milliseconds: 1000), () {
      if (mounted) setState(() => _showFocusRing = false);
    });
  }

  void _onScaleStart(ScaleStartDetails details) {
    _baseScale = _currentZoom;
  }

  Future<void> _onScaleUpdate(ScaleUpdateDetails details) async {
    if (_controller == null || !_controller!.value.isInitialized) return;

    // Calculate new zoom level
    final newZoom = (_baseScale * details.scale).clamp(_minZoom, _maxZoom);
    
    // Optimize: 0.1 increments (Prevent jitter)
    if ((newZoom - _currentZoom).abs() < 0.1) return;

    try {
      await _controller!.setZoomLevel(newZoom);
      setState(() => _currentZoom = newZoom);
    } catch (e) {
      debugPrint('Zoom failed: $e');
    }
  }

  final List<String> _capturedImages = [];

  Future<void> _takePicture() async {
    // Check Quota Lockout
    if (_quotaLockoutTime != null) {
      final remaining = _quotaLockoutTime!.difference(DateTime.now());
      if (remaining.isNegative) {
        setState(() => _quotaLockoutTime = null); // Reset
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('AI利用制限中です。あと${remaining.inSeconds}秒お待ちください。')),
        );
        return;
      }
    }

    if (_isTakingPicture || _controller == null || !_controller!.value.isInitialized) {
      return;
    }

    setState(() {
      _isTakingPicture = true;
    });

    try {
      await _initializeControllerFuture;
      final image = await _controller!.takePicture();

      // Save image locally (App Sandbox)
      final directory = await getApplicationDocumentsDirectory();
      final String imagePath = join(directory.path, '${const Uuid().v4()}.jpg');
      await image.saveTo(imagePath);

      // Save to Gallery (Public) - Phase 4: Data Safety
      try {
        await Gal.putImage(imagePath);
        debugPrint('Saved to Gallery: $imagePath');
      } catch (e) {
         debugPrint('Gallery Save Error: $e');
         // Don't block flow, but maybe notify?
         if (mounted) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text('ギャラリー保存に失敗しました: $e'), duration: const Duration(seconds: 1)),
            );
         }
      }

      if (!mounted) return;
      
      _handleCapturedImage(imagePath);


    } catch (e) {
      debugPrint('Capture Error: $e');
    } finally {
      if (mounted) {
        setState(() {
          _isTakingPicture = false;
        });
      }
    }
  }



  Future<void> _pickFromGallery() async {
    final picker = ImagePicker();
    final XFile? image = await picker.pickImage(source: ImageSource.gallery);

    if (image != null && mounted) {
      await _handleCapturedImage(image.path, fromGallery: true);
    }
  }

  Future<void> _handleCapturedImage(String imagePath, {bool fromGallery = false}) async {
      // IF RETURN PATH Mode
      if (widget.mode == CameraMode.returnPath) {
        Navigator.of(context).pop(imagePath);
        return;
      }

      setState(() {
         _capturedImages.add(imagePath);
      });

      // Show Confirmation Dialog
      await showDialog(
        context: context,
        barrierDismissible: false,
        builder: (ctx) => AlertDialog(
          title: Text(fromGallery ? '画像を読み込みました' : '写真を保存しました'),
          content: const Text('さらに別の面も撮影・追加すると、\nAI解析の精度がアップします！'),
          actions: [
            OutlinedButton(
              onPressed: () {
                // Start Analysis
                Navigator.of(context).pop();
                _analyzeImages();
              },
              child: const Text('解析開始'),
            ),
            FilledButton(
              onPressed: () {
                // Return to capture (Dismiss dialog)
                Navigator.of(context).pop();
              },
              style: FilledButton.styleFrom(
                backgroundColor: AppTheme.posimaiBlue,
                foregroundColor: Colors.white,
              ),
              child: const Text('さらに追加'),
            ),
          ],
        ),
      );
  }

  Future<void> _analyzeImages() async {
      if (_capturedImages.isEmpty) return;

      // Show AnalyzingDialog
      showDialog(
        context: context,
        barrierDismissible: false,
        builder: (context) => const AnalyzingDialog(),
      );

    try {
      // [Phase 3-C Revised] Hybrid Analysis Implementation
      final ocrService = OcrService();
      final StringBuffer extractedBuffer = StringBuffer();
      
      try {
        for (final path in _capturedImages) {
          final text = await ocrService.extractText(path);
          if (text.isNotEmpty) {
             extractedBuffer.writeln(text);
          }
        }
      } finally {
        ocrService.dispose(); // Ensure resources are released
      }

      final extractedText = extractedBuffer.toString().trim();
      debugPrint('OCR Extracted Text (${extractedText.length} chars):');
      if (extractedText.isNotEmpty) {
        debugPrint('${extractedText.substring(0, extractedText.length > 100 ? 100 : extractedText.length)}...');
      }

      // Hybrid Decision Logic (Threshold: 30 chars)
      SakeAnalysisResult result;
      final geminiService = GeminiService();

      if (extractedText.length > 30) {
        debugPrint('✅ OCR SUCCESS: Using Hybrid Analysis (Text + Images)');
        // Send both text and images (images allow AI to correct OCR errors)
        result = await geminiService.analyzeSakeHybrid(extractedText, _capturedImages);
      } else {
        debugPrint('⚠️ OCR INSUFFICIENT (${extractedText.length} chars): Fallback to Image Analysis');
        result = await geminiService.analyzeSakeLabel(_capturedImages);
      }

      // Create SakeItem
      // Create SakeItem (Schema v2.0)
      final sakeItem = SakeItem(
        id: const Uuid().v4(),
        displayData: DisplayData(
          name: result.name ?? '不明な日本酒',
          brewery: result.brand ?? '不明',
          prefecture: result.prefecture ?? '不明',
          catchCopy: result.catchCopy,
          imagePaths: List.from(_capturedImages),
          rating: null,
        ),
        hiddenSpecs: HiddenSpecs(
          description: result.description,
          tasteStats: result.tasteStats,
          flavorTags: result.flavorTags,
        ),
        metadata: Metadata(
          createdAt: DateTime.now(),
          aiConfidence: result.confidenceScore,
        ),
      );

      // Save to Hive
      final box = Hive.box<SakeItem>('sake_items');
      await box.add(sakeItem);

      // Prepend new item to sort order so it appears at the top
      final settingsBox = Hive.box('settings');
      final List<String> currentOrder = (settingsBox.get('sake_sort_order') as List<dynamic>?)
          ?.cast<String>() ?? [];
      currentOrder.insert(0, sakeItem.id); // Insert at beginning
      await settingsBox.put('sake_sort_order', currentOrder);

      // --- v1.3 Gamification Hook ---
      // Award EXP
      final userProfileState = ref.read(userProfileProvider);
      final prevLevel = userProfileState.level;
      
      await ref.read(userProfileProvider.notifier).updateTotalExp(userProfileState.totalExp + 10);
      
      // Refetch updated state for level comparison
      final updatedProfile = ref.read(userProfileProvider);
      final newLevel = updatedProfile.level;
      final isLevelUp = newLevel > prevLevel;

      // Debug: Verify save
      debugPrint('✅ Saved to Hive: ${sakeItem.displayData.name} (ID: ${sakeItem.id})');
      debugPrint('📦 Total items in box: ${box.length}');
      debugPrint('📦 Prepended to sort order (now ${currentOrder.length} items)');
      debugPrint('🎮 Gamification: EXP +10 (Total: ${updatedProfile.totalExp}) Level: $prevLevel -> $newLevel');

      if (!mounted) return;

      // Close Dialog
      Navigator.of(context).pop();

      // Close Camera Screen (Return to Home)
      Navigator.of(context).pop();

      // Success Message (with EXP/Level Up info)
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('${sakeItem.displayData.name} を登録しました！'),
              const SizedBox(height: 4),
              Row(
                children: [
                  const Icon(LucideIcons.sparkles, color: Colors.yellow, size: 16),
                  const SizedBox(width: 8),
                  Text(
                    '経験値 +10 GET! ${isLevelUp ? " (Level UP!)" : ""}',
                     style: const TextStyle(fontWeight: FontWeight.bold, color: Colors.yellowAccent),
                  ),
                ],
              ),
            ],
          ),
          duration: const Duration(seconds: 4), // Longer display for level up
        ),
      );

    } catch (e) {
      if (mounted) {
        Navigator.of(context).pop(); // Close AnalyzingDialog
        
        // Check for Quota Error to set Lockout
        if (e.toString().contains('Quota') || e.toString().contains('429')) {
             setState(() {
               _quotaLockoutTime = DateTime.now().add(const Duration(minutes: 1));
             });
        }

        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('解析エラー: $e')),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: FutureBuilder<void>(
        future: _initializeControllerFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            // Camera Preview with Focus/Zoom
            return Stack(
              fit: StackFit.expand,
              children: [
                LayoutBuilder(
                  builder: (context, constraints) {
                    return GestureDetector(
                      onScaleStart: _onScaleStart,
                      onScaleUpdate: _onScaleUpdate,
                      onTapUp: (details) => _onTapFocus(details, constraints),
                      child: CameraPreview(_controller!),
                    );
                  }
                ),
                
                // Focus Ring Overlay
                if (_showFocusRing && _focusPoint != null)
                  Positioned(
                    left: _focusPoint!.dx - 40,
                    top: _focusPoint!.dy - 40,
                    child: Container(
                      width: 80,
                      height: 80,
                      decoration: BoxDecoration(
                        border: Border.all(color: Colors.yellow, width: 2),
                        borderRadius: BorderRadius.circular(40),
                      ),
                    ),
                  ),

                // Instagram-style Exposure Slider
                Positioned(
                  right: 16,
                  top: MediaQuery.of(context).size.height * 0.25,
                  child: GestureDetector(
                    onVerticalDragUpdate: (details) async {
                      // Throttling (30ms)
                      final now = DateTime.now();
                      if (_lastExposureUpdate != null && now.difference(_lastExposureUpdate!).inMilliseconds < 30) {
                        return;
                      }
                      
                      // Drag Up = Brighter (+), Down = Darker (-)
                      final sensitivity = 0.03; 
                      final delta = -details.delta.dy * sensitivity; 
                      
                      if (_controller == null || !_controller!.value.isInitialized) return;

                      final newValue = (_currentExposureOffset + delta).clamp(_minExposure, _maxExposure);
                      
                      // UI immediate update
                      setState(() => _currentExposureOffset = newValue);
                      // Async camera update
                      _setExposureSafe(newValue);
                      
                      _lastExposureUpdate = now;
                    },
                    onVerticalDragEnd: (details) {
                      // Finalize value on drag end
                       _setExposureSafe(_currentExposureOffset);
                    },
                    onDoubleTap: () async {
                      // Reset
                      if (_controller == null) return;
                      setState(() => _currentExposureOffset = 0.0);
                      _setExposureSafe(0.0);
                    },
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        // Sun Icon (Bright)
                        Icon(LucideIcons.sun, color: _currentExposureOffset > 0.5 ? Colors.yellow : Colors.white54, size: 24),
                        const SizedBox(height: 8),
                        
                        // Vertical Track
                        Container(
                           height: 180,
                           width: 4, // Thin track
                           decoration: BoxDecoration(
                             color: Colors.white.withValues(alpha: 0.3),
                             borderRadius: BorderRadius.circular(2),
                           ),
                           child: Stack(
                             alignment: Alignment.bottomCenter,
                             children: [
                               // Center Marker
                               Align(alignment: Alignment.center, child: Container(height: 2, width: 12, color: Colors.white54)),

                               // Knob
                               LayoutBuilder(
                                 builder: (context, constraints) {
                                   final range = _maxExposure - _minExposure;
                                   if (range == 0) return const SizedBox();
                                   
                                   final normalized = (_currentExposureOffset - _minExposure) / range;
                                   // 1.0 is top (max), 0.0 is bottom (min)
                                   final topPos = constraints.maxHeight * (1 - normalized) - 10; // -HalfKnob

                                   return Positioned(
                                     top: topPos.clamp(0, constraints.maxHeight - 20),
                                     child: Container(
                                       width: 18, 
                                       height: 18,
                                       decoration: BoxDecoration(
                                         color: Colors.white,
                                         shape: BoxShape.circle,
                                         boxShadow: [BoxShadow(color: Colors.black26, blurRadius: 4)],
                                       ),
                                     ),
                                   );
                                 }
                               ),
                             ],
                           ),
                        ),
                        const SizedBox(height: 8),
                        
                        // Moon Icon (Dark)
                        Icon(LucideIcons.moon, color: _currentExposureOffset < -0.5 ? Colors.blue[200] : Colors.white54, size: 20),
                        
                        // Value Text
                        if (_currentExposureOffset.abs() > 0.1)
                          Padding(
                            padding: const EdgeInsets.only(top: 4),
                            child: Text(
                              _currentExposureOffset > 0 ? '+${_currentExposureOffset.toStringAsFixed(1)}' : _currentExposureOffset.toStringAsFixed(1),
                              style: const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold, shadows: [Shadow(color: Colors.black, blurRadius: 2)]),
                            ),
                          ),
                      ],
                    ),
                  ),
                ),

                // Overlay UI
                SafeArea(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      // Top Bar
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            IconButton(
                              icon: const Icon(LucideIcons.x, color: Colors.white, size: 32),
                              onPressed: () => Navigator.of(context).pop(),
                            ),
                            // iOS-style Zoom Buttons
                             Container(
                               padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
                               decoration: BoxDecoration(
                                 color: Colors.black.withValues(alpha: 0.6),
                                 borderRadius: BorderRadius.circular(20),
                                 border: Border.all(color: Colors.white.withValues(alpha: 0.3), width: 1),
                               ),
                               child: Row(
                                 mainAxisSize: MainAxisSize.min,
                                 children: [
                                   _buildZoomButton('1.0', 1.0),
                                   const SizedBox(width: 8),
                                   _buildZoomButton('2.0', 2.0),
                                   const SizedBox(width: 8),
                                   _buildZoomButton('3.0', 3.0),
                                 ],
                               ),
                             ),
                          ],
                        ),
                      ),
                      // Bottom Control Area
                      Padding(
                        padding: const EdgeInsets.only(bottom: 32.0, left: 24, right: 24),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            // Gallery Button (Left)
                            IconButton(
                              icon: const Icon(LucideIcons.image, color: Colors.white, size: 32),
                              onPressed: _pickFromGallery,
                              tooltip: 'ギャラリーから選択',
                            ),
                            
                            // Shutter Button (Center)
                            GestureDetector(
                              onTap: _takePicture,
                              child: Container(
                                height: 80,
                                width: 80,
                                decoration: BoxDecoration(
                                  shape: BoxShape.circle,
                                  border: Border.all(
                                    color: _quotaLockoutTime != null ? Colors.red : Colors.white, 
                                    width: 4
                                  ),
                                  color: _isTakingPicture 
                                    ? Colors.white.withValues(alpha: 0.5) 
                                    : (_quotaLockoutTime != null ? Colors.red.withValues(alpha: 0.2) : Colors.transparent),
                                ),
                                child: Center(
                                  child: _quotaLockoutTime != null
                                    ? const Icon(LucideIcons.timer, color: Colors.white, size: 30)
                                    : Container(
                                        height: 60,
                                        width: 60,
                                        decoration: BoxDecoration(
                                          shape: BoxShape.circle,
                                          color: _quotaLockoutTime != null ? Colors.grey : Colors.white,
                                        ),
                                      ),
                                ),
                              ),
                            ),
                            
                            // Right Spacer (Balance)
                            const SizedBox(width: 48), 
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
                if (_isTakingPicture)
                  Container(
                    color: Colors.black.withValues(alpha: 0.5),
                    child: const Center(
                      child: CircularProgressIndicator(),
                    ),
                  ),
              ],
            );
          } else {
            return const Center(child: CircularProgressIndicator());
          }
        },
      ),
    );
  }

  Widget _buildZoomButton(String label, double zoom) {
    // Current Zoom Logic: Highlight if close
    final isActive = (_currentZoom - zoom).abs() < 0.3;
    
    return GestureDetector(
      onTap: () async {
        if (_controller == null || !_controller!.value.isInitialized) return;
        final targetZoom = zoom.clamp(_minZoom, _maxZoom);
        
        try {
          await _controller!.setZoomLevel(targetZoom);
          setState(() => _currentZoom = targetZoom);
        } catch (e) {
          debugPrint('Zoom error: $e');
        }
      },
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
        decoration: BoxDecoration(
          color: isActive ? Colors.white : Colors.transparent,
          borderRadius: BorderRadius.circular(16),
        ),
        child: Text(
          label,
          style: TextStyle(
            color: isActive ? Colors.black : Colors.white,
            fontSize: 14,
            fontWeight: isActive ? FontWeight.bold : FontWeight.normal,
          ),
        ),
      ),
    );
  }
}

