import 'dart:async'; // Timer
import 'dart:io'; // For File class
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/image_compression_service.dart';
import '../services/gamification_service.dart'; // Badge check
import '../services/network_service.dart';
import '../services/draft_service.dart';
import '../widgets/analyzing_dialog.dart';
import '../models/sake_item.dart';
import '../theme/app_colors.dart';
import 'package:lucide_icons/lucide_icons.dart';
import 'package:image_picker/image_picker.dart'; // Gallery & Camera
import '../providers/theme_provider.dart'; // userProfileProvider
import '../providers/sakenowa_providers.dart'; // sakenowa auto-matching


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;
  
  double _minZoom = 1.0;
  double _maxZoom = 1.0;
  double _currentZoom = 1.0;
  double _baseScale = 1.0;

  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;
        _minZoom = await _controller!.getMinZoomLevel();
       _maxZoom = await _controller!.getMaxZoomLevel();
       _minExposure = await _controller!.getMinExposureOffset();
       _maxExposure = await _controller!.getMaxExposureOffset();
       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 {
        final appColors = Theme.of(context).extension<AppColors>()!;
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('AI利用制限中です。あと${remaining.inSeconds}秒お待ちください。'),
            duration: const Duration(seconds: 5),
            backgroundColor: appColors.error,
          ),
        );
        return;
      }
    }

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

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

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

      final directory = await getApplicationDocumentsDirectory();
      // 1. Save temp raw file
      final tempPath = join(directory.path, '${const Uuid().v4()}_temp.jpg');
      await image.saveTo(tempPath);

      // 2. Compress to final path
      final finalPath = join(directory.path, '${const Uuid().v4()}.jpg');
      final compressedPath = await ImageCompressionService.compressForGemini(tempPath, targetPath: finalPath);

      // 3. Clean up temp file
      try {
        await File(tempPath).delete();
      } catch (e) {
        debugPrint('Warning: Failed to delete temp file: $e');
      }

      final imagePath = compressedPath;

      // Save to Gallery (Public)
      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) {
            final appColors = Theme.of(context).extension<AppColors>()!;
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text('ギャラリー保存に失敗しました: $e'),
                duration: const Duration(seconds: 4),
                backgroundColor: appColors.warning,
              ),
            );
         }
      }

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


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



  Future<void> _pickFromGallery() async {
    final picker = ImagePicker();
    // Use standard image_picker (Updated to 1.1.2 for Android 13+)
    final List<XFile> images = await picker.pickMultiImage();

    if (images.isNotEmpty && mounted) {
      // IF RETURN PATH Mode (Only supports one)
      if (widget.mode == CameraMode.returnPath) {
          final directory = await getApplicationDocumentsDirectory();
        final finalPath = join(directory.path, '${const Uuid().v4()}.jpg');
        final compressedPath = await ImageCompressionService.compressForGemini(
          images.first.path,
          targetPath: finalPath,
        );

        if (!mounted) return;
        Navigator.of(context).pop(compressedPath);
        return;
      }

      final directory = await getApplicationDocumentsDirectory();

      for (var img in images) {
        try {
          // 1. Generate permanent path
          final finalPath = join(directory.path, '${const Uuid().v4()}.jpg');

          // 2. Compress temporary cache image to permanent location
          final compressedPath = await ImageCompressionService.compressForGemini(
            img.path,
            targetPath: finalPath,
          );

          // 3. Add compressed permanent path to capture list
          setState(() {
            _capturedImages.add(compressedPath);
          });

          debugPrint('✅ Gallery image compressed & persisted: $compressedPath');
        } catch (e) {
          debugPrint('⚠️ Gallery image compression error: $e');
          // Fallback: Use original path (legacy behavior)
          setState(() {
            _capturedImages.add(img.path);
          });
        }
      }

      // Batch handle - Notification only
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('${images.length}枚の画像を読み込みました。\n右下のボタンから解析を開始してください。'),
            duration: const Duration(seconds: 3),
            action: SnackBarAction(
              label: '解析する',
              onPressed: _analyzeImages,
              textColor: Colors.yellow,
            ),
          ),
        );
      }
    }
  }

  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
      final appColors = Theme.of(context).extension<AppColors>()!;

      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();
              },
              style: OutlinedButton.styleFrom(
                foregroundColor: appColors.brandPrimary,
                side: BorderSide(color: appColors.brandPrimary),
              ),
              child: const Text('解析開始'),
            ),
            FilledButton(
              onPressed: () {
                // Return to capture (Dismiss dialog)
                Navigator.of(context).pop();
              },
              style: FilledButton.styleFrom(
                backgroundColor: appColors.brandPrimary,
                foregroundColor: Colors.white,
              ),
              child: const Text('さらに追加'),
            ),
          ],
        ),
      );
  }

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

      final isOnline = await NetworkService.isOnline();
      if (!isOnline) {
        // オフライン時: Draft として保存
        debugPrint('📴 Offline detected: Saving as draft...');

        try {
          // 🔧 FIX: 複数画像をすべて保存
          await DraftService.saveDraft(_capturedImages);

          if (!mounted) return;

          // ユーザーに通知
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      Icon(LucideIcons.wifiOff, color: Colors.orange, size: 16),
                      SizedBox(width: 8),
                      Text('オフライン検知', style: TextStyle(fontWeight: FontWeight.bold)),
                    ],
                  ),
                  SizedBox(height: 4),
                  Text('写真を「解析待ち」として保存しました。'),
                  Text('オンライン復帰後、ホーム画面から解析できます。'),
                ],
              ),
              duration: Duration(seconds: 5),
              backgroundColor: Colors.orange,
            ),
          );

          // カメラ画面を閉じる
          Navigator.of(context).pop();
          return;
        } catch (e) {
          debugPrint('⚠️ Draft save error: $e');
          if (!mounted) return;
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('Draft保存エラー: $e')),
          );
          return;
        }
      }

      // オンライン時: 通常の解析フロー
      // Show AnalyzingDialog
      if (!mounted) return;
      showDialog(
        context: context,
        barrierDismissible: false,
        builder: (context) => const AnalyzingDialog(),
      );

    try {
      // Direct Gemini Vision Analysis (OCR removed for app size reduction)
      debugPrint('📸 Starting Gemini Vision Direct Analysis for ${_capturedImages.length} images');
      final geminiService = GeminiService();
      final result = await geminiService.analyzeSakeLabel(_capturedImages);

      // 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,
          type: result.type,
          alcoholContent: result.alcoholContent,
          polishingRatio: result.polishingRatio,
          sakeMeterValue: result.sakeMeterValue,
          riceVariety: result.riceVariety,
          yeast: result.yeast,
          manufacturingYearMonth: result.manufacturingYearMonth,
        ),
        metadata: Metadata(
          createdAt: DateTime.now(),
          aiConfidence: result.confidenceScore,
        ),
      );

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

      // ✅ さけのわ自動マッチング（非同期・バックグラウンド）
      // エラーが発生しても登録フローを中断しない
      _performSakenowaMatching(sakeItem).catchError((error) {
        debugPrint('⚠️  Sakenowa auto-matching failed (non-critical): $error');
      });

      // 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);

      // Check and unlock badges
      final newBadges = await GamificationService.checkAndUnlockBadges(ref);

      // 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.displayName} (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/Badge info)
      final isDark = Theme.of(context).brightness == Brightness.dark;
      final List<Widget> messageWidgets = [
        Text('${sakeItem.displayData.displayName} を登録しました！'),
        const SizedBox(height: 4),
        Row(
          children: [
            Icon(LucideIcons.sparkles,
                 color: isDark ? Colors.yellow.shade300 : Colors.yellow,
                 size: 16),
            const SizedBox(width: 8),
            Text(
              '経験値 +10 GET! ${isLevelUp ? " (Level UP!)" : ""}',
               style: TextStyle(
                 fontWeight: FontWeight.bold,
                 color: isDark ? Colors.yellow.shade200 : Colors.yellowAccent,
               ),
            ),
          ],
        ),
      ];

      // Add badge notifications
      if (newBadges.isNotEmpty) {
        messageWidgets.add(const SizedBox(height: 8));
        for (var badge in newBadges) {
          messageWidgets.add(
            Row(
              children: [
                Text(badge.icon, style: const TextStyle(fontSize: 16)),
                const SizedBox(width: 8),
                Text(
                  'バッジ獲得: ${badge.name}',
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    color: isDark ? Colors.green.shade300 : Colors.greenAccent,
                  ),
                ),
              ],
            ),
          );
        }
      }

      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: messageWidgets,
          ),
          duration: Duration(seconds: newBadges.isNotEmpty ? 6 : 4), // Longer for badges
        ),
      );

    } 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));
             });
        }

        final appColors = Theme.of(context).extension<AppColors>()!;
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('解析エラー: $e'),
            duration: const Duration(seconds: 5),
            backgroundColor: appColors.error,
          ),
        );
      }
    }
  }

  @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 (REBUILT - No LayoutBuilder+Positioned)
                Positioned(
                  right: 0,
                  top: MediaQuery.of(context).size.height * 0.25,
                  child: GestureDetector(
                    behavior: HitTestBehavior.opaque,
                    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.12; // Perfect finger tracking!
                      final delta = -details.delta.dy * sensitivity;

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

                      final newValue = (_currentExposureOffset + delta).clamp(_minExposure, _maxExposure);

                      // Debug: Check actual value changes
                      debugPrint('Exposure Update: delta=${delta.toStringAsFixed(3)}, old=${_currentExposureOffset.toStringAsFixed(2)}, new=${newValue.toStringAsFixed(2)}, range=$_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: Container(
                      width: 80, // Wide touch area
                      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
                      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 with Knob (NO LayoutBuilder)
                          SizedBox(
                            height: 180,
                            width: 48, // Wider for easier tapping
                            child: CustomPaint(
                              key: ValueKey(_currentExposureOffset), // Force repaint on value change
                              painter: _ExposureSliderPainter(
                                currentValue: _currentExposureOffset,
                                minValue: _minExposure,
                                maxValue: _maxExposure,
                              ),
                            ),
                          ),
                          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 -> Analyze Button if images exist
                            if (_capturedImages.isNotEmpty)
                              IconButton(
                                icon: Badge(
                                  label: Text('${_capturedImages.length}'),
                                  child: const Icon(LucideIcons.playCircle, color: Colors.greenAccent, size: 40),
                                ),
                                onPressed: _analyzeImages,
                                tooltip: '解析を開始',
                              )
                            else
                              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,
          ),
        ),
      ),
    );
  }

  /// ✅ さけのわ自動マッチング処理
  ///
  /// 登録後にバックグラウンドで実行
  /// エラーが発生しても登録フローを中断しない
  Future<void> _performSakenowaMatching(SakeItem sakeItem) async {
    try {
      debugPrint('🔍 Starting sakenowa auto-matching for: ${sakeItem.displayData.displayName}');

      final matchingService = ref.read(sakenowaAutoMatchingServiceProvider);

      // マッチング実行（最小スコア: 0.7、自動適用: true）
      final result = await matchingService.matchSake(
        sakeItem: sakeItem,
        minScore: 0.7,
        autoApply: true, // マッチング成功時に自動で適用
      );

      if (result.hasMatch) {
        debugPrint('✅ Sakenowa matching successful!');
        debugPrint('   Brand: ${result.brand?.name}');
        debugPrint('   Brewery: ${result.brewery?.name}');
        debugPrint('   Score: ${result.score.toStringAsFixed(2)}');
        debugPrint('   Confident: ${result.isConfident}');
      } else {
        debugPrint('ℹ️  No sakenowa match found (score: ${result.score.toStringAsFixed(2)})');
      }
    } catch (e, stackTrace) {
      // エラーログのみ、ユーザーには通知しない（登録は成功しているため）
      debugPrint('💥 Sakenowa auto-matching error: $e');
      debugPrint('Stack trace: $stackTrace');
    }
  }
}

// Custom Painter for Exposure Slider
class _ExposureSliderPainter extends CustomPainter {
  final double currentValue;
  final double minValue;
  final double maxValue;

  _ExposureSliderPainter({
    required this.currentValue,
    required this.minValue,
    required this.maxValue,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final trackPaint = Paint()
      ..color = Colors.white.withValues(alpha: 0.3)
      ..strokeWidth = 4
      ..strokeCap = StrokeCap.round;

    final centerLinePaint = Paint()
      ..color = Colors.white54
      ..strokeWidth = 2;

    final knobPaint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill;    final knobShadowPaint = Paint()
      ..color = Colors.black26
      ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 4);    // Draw vertical track (centered)
    final trackX = size.width / 2;
    canvas.drawLine(
      Offset(trackX, 10),
      Offset(trackX, size.height - 10),
      trackPaint,
    );    // Draw center marker
    canvas.drawLine(
      Offset(trackX - 6, size.height / 2),
      Offset(trackX + 6, size.height / 2),
      centerLinePaint,
    );    // Calculate knob position
    final range = maxValue - minValue;
    if (range > 0) {
      // Normalize currentValue to 0.0-1.0 range
      // minValue (e.g., -4.0) -> 0.0 (bottom)
      // 0.0 (center) -> 0.5 (middle)
      // maxValue (e.g., +4.0) -> 1.0 (top)
      final normalized = (currentValue - minValue) / range;
      // Map to Y coordinate: 0.0 (normalized) -> bottom, 1.0 (normalized) -> top
      final knobY = (size.height - 20) * (1.0 - normalized) + 10;
      // Draw knob shadow
      canvas.drawCircle(Offset(trackX, knobY), 7, knobShadowPaint);
      // Draw knob
      canvas.drawCircle(Offset(trackX, knobY), 6, knobPaint);
    }
  }  @override
  bool shouldRepaint(_ExposureSliderPainter oldDelegate) {
    return oldDelegate.currentValue != currentValue ||
        oldDelegate.minValue != minValue ||
        oldDelegate.maxValue != maxValue;
  }
}
