import 'dart:io';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import '../main.dart';
import '../services/collection_service.dart';
import '../services/storage_service.dart';
import '../theme/app_colors.dart';
import '../widgets/car_card.dart';

/// The "My Garage" screen — shows a collection's cars in a grid.
class GarageScreen extends StatefulWidget {
  final String collectionId;
  final String collectionName;
  final String userRole;

  const GarageScreen({
    super.key,
    required this.collectionId,
    required this.collectionName,
    this.userRole = 'owner',
  });

  bool get isOwner => userRole == 'owner';
  bool get isMember => userRole == 'member';
  bool get isViewer => userRole == 'viewer';
  bool get canModifyCars => isOwner || isMember;

  @override
  State<GarageScreen> createState() => GarageScreenState();
}

class GarageScreenState extends State<GarageScreen> {
  List<Map<String, dynamic>> _cars = [];
  bool _isLoading = true;
  bool _isLoadingMore = false;
  bool _hasMore = true;
  int _page = 0;
  static const int _pageSize = 40;

  String? _error;
  String _searchQuery = '';
  final _searchController = TextEditingController();
  final _scrollController = ScrollController();

  bool _selectionMode = false;
  final Set<int> _selectedIds = <int>{};
  final Set<int> _refreshingImageIds = <int>{};

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(_onScroll);
    _loadCars(reset: true);
  }

  @override
  void dispose() {
    _scrollController.dispose();
    _searchController.dispose();
    super.dispose();
  }

  /// Public method so other screens can trigger a refresh.
  void refresh() => _loadCars(reset: true);

  void _onScroll() {
    if (!_scrollController.hasClients || _isLoadingMore || !_hasMore) return;
    final pos = _scrollController.position;
    if (pos.pixels >= pos.maxScrollExtent - 320) {
      _loadCars();
    }
  }

  Future<void> _loadCars({bool reset = false}) async {
    if (reset) {
      _page = 0;
      _hasMore = true;
      _selectedIds.clear();
      _selectionMode = false;
    }

    if (!_hasMore && !reset) return;

    setState(() {
      if (reset || _cars.isEmpty) {
        _isLoading = true;
      } else {
        _isLoadingMore = true;
      }
      if (reset) _error = null;
    });

    try {
      final from = _page * _pageSize;
      final to = from + _pageSize - 1;

      final data = await supabase
          .from('hotwheels')
          .select(
            'id, created_at, hw_id, notes, user_image_url, global_cars(name, series, year, color, is_verified, confirmation_count)')
          .eq('collection_id', widget.collectionId)
          .order('created_at', ascending: false)
          .range(from, to);

      final rows = List<Map<String, dynamic>>.from(data);
      final withSignedUrls = await Future.wait(
        rows.map((row) async {
          final path = row['user_image_url'] as String?;
          final signed = await StorageService.createSignedUrl(path);
          return {
            ...row,
            'signed_image_url': signed,
          };
        }),
      );

      if (!mounted) return;
      setState(() {
        _cars = reset ? withSignedUrls : [..._cars, ...withSignedUrls];
        _hasMore = withSignedUrls.length == _pageSize;
        if (_hasMore) _page += 1;
        _isLoading = false;
        _isLoadingMore = false;
      });
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _error = e.toString();
        _isLoading = false;
        _isLoadingMore = false;
      });
    }
  }

  List<Map<String, dynamic>> get _filteredCars {
    if (_searchQuery.isEmpty) return _cars;
    final q = _searchQuery.toLowerCase();
    return _cars.where((car) {
      final global = car['global_cars'] as Map<String, dynamic>?;
      final id = (car['hw_id'] as String? ?? '').toLowerCase();
      final name = (global?['name'] as String? ?? '').toLowerCase();
      final series = (global?['series'] as String? ?? '').toLowerCase();
      return id.contains(q) || name.contains(q) || series.contains(q);
    }).toList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: RefreshIndicator(
        onRefresh: () => _loadCars(reset: true),
        child: CustomScrollView(
          controller: _scrollController,
          physics: const AlwaysScrollableScrollPhysics(),
          slivers: [
          SliverAppBar(
            expandedHeight: 140,
            pinned: true,
            actions: [
              if (_selectionMode && !widget.isViewer)
                IconButton(
                  tooltip: 'Cancel Selection',
                  onPressed: () => _toggleSelectionMode(false),
                  icon: const Icon(Icons.close),
                )
              else if (!widget.isViewer)
                IconButton(
                  tooltip: 'Select Cars',
                  onPressed: () => _toggleSelectionMode(true),
                  icon: const Icon(Icons.select_all),
                ),
            ],
            flexibleSpace: FlexibleSpaceBar(
              titlePadding: const EdgeInsets.only(left: 20, bottom: 16),
              title: Text(
                widget.collectionName,
                style: TextStyle(
                  fontFamily: 'Poppins',
                  fontWeight: FontWeight.w700,
                  fontSize: 22,
                  color: Colors.white,
                  shadows: [
                    Shadow(
                      color: Colors.black.withValues(alpha: 0.3),
                      blurRadius: 4,
                    ),
                  ],
                ),
              ),
              background: Container(
                decoration: BoxDecoration(
                  image: const DecorationImage(
                    image: AssetImage('assets/img/login_bg.jpg'),
                    fit: BoxFit.cover,
                  ),
                  color: Colors.black.withValues(alpha: 0.15),
                ),
                child: Container(
                  decoration: BoxDecoration(
                    gradient: LinearGradient(
                      begin: Alignment.topCenter,
                      end: Alignment.bottomCenter,
                      colors: [
                        Colors.black.withValues(alpha: 0.3),
                        Colors.black.withValues(alpha: 0.55),
                      ],
                    ),
                  ),
                  child: Align(
                    alignment: Alignment.centerRight,
                    child: Padding(
                      padding: const EdgeInsets.only(right: 24),
                      child: Icon(
                        Icons.directions_car_filled,
                        size: 72,
                        color: Colors.white.withValues(alpha: 0.18),
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ),
          SliverToBoxAdapter(
            child: Padding(
              padding: const EdgeInsets.fromLTRB(16, 16, 16, 4),
              child: Row(
                children: [
                  _StatChip(
                    icon: Icons.directions_car,
                    label: '${_cars.length}',
                    subtitle: 'Total Cars',
                  ),
                  const SizedBox(width: 12),
                  _StatChip(
                    icon: Icons.new_releases,
                    label: _recentCount(),
                    subtitle: 'This Week',
                  ),
                ],
              ),
            ),
          ),
          SliverToBoxAdapter(
            child: Padding(
              padding: const EdgeInsets.fromLTRB(16, 12, 16, 8),
              child: TextField(
                controller: _searchController,
                onChanged: (v) => setState(() => _searchQuery = v),
                decoration: InputDecoration(
                  hintText: 'Search by ID, name, or series…',
                  prefixIcon: const Icon(Icons.search),
                  suffixIcon: _searchQuery.isEmpty
                      ? null
                      : IconButton(
                          icon: const Icon(Icons.clear),
                          onPressed: () {
                            _searchController.clear();
                            setState(() => _searchQuery = '');
                          },
                        ),
                ),
              ),
            ),
          ),
          if (_isLoading)
            const SliverFillRemaining(
              child: Center(child: CircularProgressIndicator()),
            )
          else if (_error != null)
            SliverFillRemaining(
              child: _ErrorView(
                message: _error!,
                onRetry: () => _loadCars(reset: true),
              ),
            )
          else if (_filteredCars.isEmpty)
            SliverFillRemaining(
              child: _EmptyGarage(hasSearch: _searchQuery.isNotEmpty),
            )
          else
            SliverPadding(
              padding: const EdgeInsets.fromLTRB(8, 4, 8, 100),
              sliver: SliverGrid(
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  childAspectRatio: 0.72,
                  mainAxisSpacing: 4,
                  crossAxisSpacing: 0,
                ),
                delegate: SliverChildBuilderDelegate(
                  (context, index) {
                    final car = _filteredCars[index];
                    final global = car['global_cars'] as Map<String, dynamic>?;
                    final carId = car['id'] as int;
                    return CarCard(
                      hwId: car['hw_id'] as String? ?? '???',
                      name: global?['name'] as String?,
                      series: global?['series'] as String?,
                      year: global?['year'] as int?,
                      color: global?['color'] as String?,
                      isVerified: global?['is_verified'] == true,
                      imageUrl: car['signed_image_url'] as String?,
                      isSelected: _selectedIds.contains(carId),
                      addedAt: car['created_at'] != null
                          ? DateTime.tryParse(car['created_at'])
                          : null,
                      onImageError: () => _refreshSignedUrlForCar(carId),
                      onTap: () => _selectionMode
                          ? _toggleCarSelection(car)
                          : _showCarDetails(car),
                      onLongPress:
                          widget.isViewer ? null : () => _toggleCarSelection(car),
                    );
                  },
                  childCount: _filteredCars.length,
                ),
              ),
            ),
          if (_isLoadingMore)
            const SliverToBoxAdapter(
              child: Padding(
                padding: EdgeInsets.symmetric(vertical: 18),
                child: Center(child: CircularProgressIndicator(strokeWidth: 2)),
              ),
            ),
          ],
        ),
      ),
      bottomNavigationBar: _selectionMode
          && !widget.isViewer
          ? SafeArea(
              top: false,
              child: Container(
                padding:
                    const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
                decoration: BoxDecoration(
                  color: Theme.of(context).cardTheme.color,
                  border: Border(
                    top: BorderSide(
                      color: AppColors.textHint.withValues(alpha: 0.25),
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    Expanded(
                      child: Text(
                        '${_selectedIds.length} selected',
                        style: const TextStyle(fontWeight: FontWeight.w600),
                      ),
                    ),
                    OutlinedButton(
                      onPressed:
                          _selectedIds.isEmpty ? null : _relocateSelectedCars,
                      child: Text(widget.isOwner ? 'Move to...' : 'Copy to...'),
                    ),
                  ],
                ),
              ),
            )
          : null,
    );
  }

  String _recentCount() {
    final weekAgo = DateTime.now().subtract(const Duration(days: 7));
    final count = _cars.where((c) {
      final ts = c['created_at'];
      if (ts == null) return false;
      final d = DateTime.tryParse(ts.toString());
      return d != null && d.isAfter(weekAgo);
    }).length;
    return '$count';
  }

  void _toggleSelectionMode(bool enabled) {
    if (widget.isViewer && enabled) return;
    setState(() {
      _selectionMode = enabled;
      if (!enabled) {
        _selectedIds.clear();
      }
    });
  }

  void _toggleCarSelection(Map<String, dynamic> car) {
    if (widget.isViewer) return;
    final id = car['id'] as int;
    setState(() {
      _selectionMode = true;
      if (_selectedIds.contains(id)) {
        _selectedIds.remove(id);
      } else {
        _selectedIds.add(id);
      }
      if (_selectedIds.isEmpty) {
        _selectionMode = false;
      }
    });
  }

  Future<void> _relocateSelectedCars() async {
    if (_selectedIds.isEmpty) return;
    if (widget.isViewer) {
      showGlobalSnackBar('Viewer role is read-only for this collection.');
      return;
    }

    try {
      final isOwner = widget.isOwner;
      final collections = await CollectionService.getMyCollections();
      if (!mounted) return;

      final candidates = collections
          .where((c) => c.id != widget.collectionId)
          .toList(growable: false);

      if (candidates.isEmpty) {
        showGlobalSnackBar('No other collection available.', isError: true);
        return;
      }

      String? targetId;
      final confirmed = await showDialog<bool>(
        context: context,
        builder: (_) => StatefulBuilder(
          builder: (context, setSheetState) => AlertDialog(
            title: Text(isOwner ? 'Move Selected Cars' : 'Copy Selected Cars'),
            content: DropdownButtonFormField<String>(
              initialValue: targetId,
              decoration: const InputDecoration(
                labelText: 'Target collection',
              ),
              items: candidates
                  .map(
                    (c) => DropdownMenuItem<String>(
                      value: c.id,
                      child: Text(c.name),
                    ),
                  )
                  .toList(),
              onChanged: (value) => setSheetState(() => targetId = value),
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(context, false),
                child: const Text('Cancel'),
              ),
              ElevatedButton(
                onPressed: targetId == null
                    ? null
                    : () => Navigator.pop(context, true),
                child: Text(isOwner ? 'Move' : 'Copy'),
              ),
            ],
          ),
        ),
      );

      if (confirmed != true || targetId == null) return;

      if (isOwner) {
        await supabase
            .from('hotwheels')
            .update({'collection_id': targetId})
            .inFilter('id', _selectedIds.toList());
      } else {
        final sourceCars = _cars
            .where((car) => _selectedIds.contains(car['id'] as int))
            .toList(growable: false);

        final insertRows = sourceCars.map((car) {
          final notes = car['notes'] as String?;
          final imagePath = car['user_image_url'] as String?;
          return <String, dynamic>{
            'hw_id': car['hw_id'] as String,
            'user_id': supabase.auth.currentUser!.id,
            'collection_id': targetId,
            if (notes != null && notes.trim().isNotEmpty) 'notes': notes,
            if (imagePath != null && imagePath.isNotEmpty)
              'user_image_url': imagePath,
          };
        }).toList(growable: false);

        if (insertRows.isNotEmpty) {
          await supabase.from('hotwheels').insert(insertRows);
        }
      }

      if (!mounted) return;
      showGlobalSnackBar(
        isOwner
            ? '${_selectedIds.length} car(s) moved.'
            : '${_selectedIds.length} car(s) copied.',
      );
      _toggleSelectionMode(false);
      await _loadCars(reset: true);
    } catch (e) {
      showGlobalSnackBar(
        widget.isOwner ? 'Failed to move cars: $e' : 'Failed to copy cars: $e',
        isError: true,
      );
    }
  }

  Future<void> _refreshSignedUrlForCar(int carId) async {
    if (_refreshingImageIds.contains(carId)) return;

    final index = _cars.indexWhere((c) => c['id'] == carId);
    if (index == -1) return;

    final path = _cars[index]['user_image_url'] as String?;
    if (path == null || path.isEmpty) return;

    _refreshingImageIds.add(carId);
    try {
      final signed = await StorageService.createSignedUrl(path);
      if (!mounted || signed == null) return;
      setState(() {
        _cars[index] = {
          ..._cars[index],
          'signed_image_url': signed,
        };
      });
    } finally {
      _refreshingImageIds.remove(carId);
    }
  }

  void _showCarDetails(Map<String, dynamic> car) {
    if (_selectionMode) {
      _toggleCarSelection(car);
      return;
    }

    final global = car['global_cars'] as Map<String, dynamic>?;
    final hwId = car['hw_id'] as String? ?? '???';
    final name = global?['name'] as String?;
    final series = global?['series'] as String?;
    final year = global?['year'] as int?;
    final verified = global?['is_verified'] == true;
    final confirmations = (global?['confirmation_count'] as num?)?.toInt() ?? 0;
    final notes = car['notes'] as String?;
    final imageUrl = car['signed_image_url'] as String?;

    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
      ),
      builder: (_) => DraggableScrollableSheet(
        initialChildSize: 0.55,
        minChildSize: 0.3,
        maxChildSize: 0.85,
        expand: false,
        builder: (context, scrollController) => ListView(
          controller: scrollController,
          padding: const EdgeInsets.all(24),
          children: [
            // Drag handle
            Center(
              child: Container(
                width: 40,
                height: 4,
                margin: const EdgeInsets.only(bottom: 20),
                decoration: BoxDecoration(
                  color: Colors.grey.shade300,
                  borderRadius: BorderRadius.circular(2),
                ),
              ),
            ),

            // ── Car image ──
            ClipRRect(
              borderRadius: BorderRadius.circular(16),
              child: AspectRatio(
                aspectRatio: 16 / 10,
                child: imageUrl != null && imageUrl.isNotEmpty
                    ? CachedNetworkImage(
                        imageUrl: imageUrl,
                        fit: BoxFit.cover,
                        fadeInDuration: Duration.zero,
                        fadeOutDuration: Duration.zero,
                        errorWidget: (context, url, error) => Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Expanded(child: _imagePlaceholder()),
                            Padding(
                              padding: const EdgeInsets.only(bottom: 10),
                              child: TextButton.icon(
                                onPressed: () => _refreshSignedUrlForCar(car['id'] as int),
                                icon: const Icon(Icons.refresh, size: 16),
                                label: const Text('Refresh image link'),
                              ),
                            ),
                          ],
                        ),
                      )
                    : _imagePlaceholder(),
              ),
            ),
            const SizedBox(height: 8),

            // Change / Add photo button
            if (widget.canModifyCars) ...[
              Align(
                alignment: Alignment.centerRight,
                child: TextButton.icon(
                  onPressed: () => _updatePhoto(car, context),
                  icon: Icon(
                    (car['user_image_url'] as String?) != null
                        ? Icons.camera_alt
                        : Icons.add_a_photo,
                    size: 18,
                  ),
                  label: Text(
                    (car['user_image_url'] as String?) != null
                        ? 'Change Photo'
                        : 'Add Photo',
                  ),
                ),
              ),
              const SizedBox(height: 4),
            ],

            // ID badge
            Align(
              alignment: Alignment.centerLeft,
              child: Container(
                padding: const EdgeInsets.symmetric(
                    horizontal: 12, vertical: 6),
                decoration: BoxDecoration(
                  gradient: AppColors.brandGradient,
                  borderRadius: BorderRadius.circular(8),
                ),
                child: Text(
                  hwId,
                  style: const TextStyle(
                    color: Colors.white,
                    fontWeight: FontWeight.w700,
                    fontSize: 18,
                    letterSpacing: 1.5,
                  ),
                ),
              ),
            ),

            if (name != null && name.isNotEmpty) ...[
              const SizedBox(height: 16),
              Text(
                name,
                style: Theme.of(context).textTheme.headlineSmall?.copyWith(
                      fontWeight: FontWeight.w600,
                    ),
              ),
            ],

            const SizedBox(height: 12),
            const Divider(),
            const SizedBox(height: 8),

            if (series != null && series.isNotEmpty)
              _DetailRow(icon: Icons.collections, label: 'Series', value: series),
            if (year != null)
              _DetailRow(icon: Icons.calendar_today, label: 'Year', value: '$year'),
            _DetailRow(
              icon: verified ? Icons.verified : Icons.hourglass_bottom,
              label: 'Validation',
              value: verified
                  ? 'Verified by community'
                  : 'Pending verification',
            ),
            _DetailRow(
              icon: Icons.how_to_vote,
              label: 'Confirmations',
              value: '$confirmations',
            ),
            if (notes != null && notes.isNotEmpty)
              _DetailRow(icon: Icons.notes, label: 'Notes', value: notes),

            const SizedBox(height: 24),

            if (!verified) ...[
              SizedBox(
                width: double.infinity,
                child: OutlinedButton.icon(
                  onPressed: () => _confirmCatalogEntry(hwId, context),
                  icon: const Icon(Icons.thumb_up_alt_outlined, size: 18),
                  label: const Text('Confirm Catalog Entry'),
                ),
              ),
              const SizedBox(height: 10),
            ],

            SizedBox(
              width: double.infinity,
              child: OutlinedButton.icon(
                onPressed: () => _reportCatalogEntry(car, context),
                icon: const Icon(Icons.flag_outlined, size: 18),
                label: const Text('Report Catalog Issue'),
              ),
            ),

            const SizedBox(height: 12),

            if (widget.canModifyCars) ...[
              Row(
                children: [
                  Expanded(
                    child: OutlinedButton.icon(
                      onPressed: () => _relocateSingleCar(car, context),
                      icon: Icon(
                        widget.isOwner
                            ? Icons.drive_file_move_outline
                            : Icons.copy_outlined,
                        size: 18,
                      ),
                      label: Text(widget.isOwner ? 'Move' : 'Copy'),
                    ),
                  ),
                  const SizedBox(width: 8),
                  Expanded(
                    child: ElevatedButton.icon(
                      onPressed: () => _editCar(car, context),
                      icon: const Icon(Icons.edit, size: 18),
                      label: const Text('Edit'),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 8),
              SizedBox(
                width: double.infinity,
                child: OutlinedButton.icon(
                  onPressed: () => _deleteCar(car, context),
                  icon: const Icon(Icons.delete_outline, color: AppColors.error),
                  label: const Text(
                    'Remove',
                    style: TextStyle(color: AppColors.error),
                  ),
                  style: OutlinedButton.styleFrom(
                    side: const BorderSide(color: AppColors.error),
                  ),
                ),
              ),
            ] else
              const Text(
                'Viewer access: read-only',
                textAlign: TextAlign.center,
                style: TextStyle(
                  color: AppColors.textSecondary,
                  fontWeight: FontWeight.w500,
                ),
              ),
          ],
        ),
      ),
    );
  }

  Widget _imagePlaceholder() {
    final isDark = Theme.of(context).brightness == Brightness.dark;
    return Container(
      color: isDark ? AppColors.surfaceDark : AppColors.backgroundLight,
      child: Padding(
        padding: const EdgeInsets.all(18),
        child: Image.asset(
          'assets/img/icon_bg_removed.png',
          fit: BoxFit.contain,
          errorBuilder: (context, error, stackTrace) => Center(
            child: Icon(
              Icons.directions_car_filled,
              size: 48,
              color: isDark
                  ? Colors.white.withValues(alpha: 0.15)
                  : AppColors.orange.withValues(alpha: 0.25),
            ),
          ),
        ),
      ),
    );
  }

  /// Take a new photo and update the image_url for this car.
  Future<void> _updatePhoto(
      Map<String, dynamic> car, BuildContext sheetContext) async {
    if (!widget.canModifyCars) {
      showGlobalSnackBar('Viewer role is read-only for this collection.');
      return;
    }

    final picker = ImagePicker();
    final xFile = await picker.pickImage(
      source: ImageSource.camera,
      maxWidth: 1600,
      maxHeight: 1600,
      imageQuality: 90,
    );
    if (xFile == null) return;

    showGlobalSnackBar('Uploading photo…');

    final oldPath = car['user_image_url'] as String?;
    String newPath;
    try {
      newPath = await StorageService.uploadCarImage(
        file: File(xFile.path),
        entryId: car['id'] as int,
        oldPath: oldPath,
      );
    } catch (e) {
      showGlobalSnackBar(
        'Failed to upload photo. Please try a smaller/clearer image. ($e)',
        isError: true,
      );
      return;
    }

    try {
      await supabase
          .from('hotwheels')
          .update({'user_image_url': newPath})
          .eq('id', car['id']);

      showGlobalSnackBar('Photo updated!');
      if (sheetContext.mounted) Navigator.pop(sheetContext);
      _loadCars(reset: true); // refresh grid
    } catch (e) {
      showGlobalSnackBar('Failed to save: $e', isError: true);
    }
  }

  /// Open an edit dialog for this car, then update Supabase.
  Future<void> _editCar(
      Map<String, dynamic> car, BuildContext sheetContext) async {
    if (!widget.canModifyCars) {
      showGlobalSnackBar('Viewer role is read-only for this collection.');
      return;
    }

    final updated = await showDialog<Map<String, dynamic>>(
      context: sheetContext,
      builder: (_) => _EditCarDialog(car: car),
    );
    if (updated == null) return;

    try {
      await supabase
          .from('hotwheels')
          .update(updated)
          .eq('id', car['id']);

      showGlobalSnackBar('Car updated!');
      if (sheetContext.mounted) Navigator.pop(sheetContext);
      _loadCars(reset: true);
    } catch (e) {
      showGlobalSnackBar('Failed to update: $e', isError: true);
    }
  }

  Future<void> _confirmCatalogEntry(String hwId, BuildContext sheetContext) async {
    final user = supabase.auth.currentUser;
    if (user == null) return;

    try {
      final existingVote = await supabase
          .from('car_votes')
          .select('id')
          .eq('hw_id', hwId)
          .eq('user_id', user.id)
          .maybeSingle();

      if (existingVote != null) {
        showGlobalSnackBar('You already confirmed this catalog entry.');
        return;
      }

      await supabase.from('car_votes').insert({
        'hw_id': hwId,
        'user_id': user.id,
      });

      showGlobalSnackBar('Thanks! Your validation vote was recorded.');
      if (sheetContext.mounted) Navigator.pop(sheetContext);
      _loadCars(reset: true);
    } catch (e) {
      showGlobalSnackBar('Failed to submit validation vote: $e', isError: true);
    }
  }

  Future<void> _reportCatalogEntry(
    Map<String, dynamic> car,
    BuildContext sheetContext,
  ) async {
    final user = supabase.auth.currentUser;
    if (user == null) return;

    final payload = await showDialog<_CarReportDraft>(
      context: sheetContext,
      builder: (_) => const _ReportCarDialog(),
    );

    if (payload == null) return;

    final hwId = car['hw_id'] as String?;
    if (hwId == null || hwId.isEmpty) {
      showGlobalSnackBar('Cannot report this item: missing hw_id.', isError: true);
      return;
    }

    final hotwheelsId = car['id'] as int?;

    try {
      final existingOpen = await supabase
          .from('car_reports')
          .select('id')
          .eq('hw_id', hwId)
          .eq('reporter_user_id', user.id)
          .eq('status', 'open')
          .maybeSingle();

      if (existingOpen != null) {
        showGlobalSnackBar('You already have an open report for this car.');
        return;
      }

      await supabase.from('car_reports').insert({
        'hw_id': hwId,
        'hotwheels_id': hotwheelsId,
        'reporter_user_id': user.id,
        'reason': payload.reason,
        'note': payload.note,
      });

      showGlobalSnackBar('Thanks for reporting. We will review this entry.');
    } catch (e) {
      showGlobalSnackBar('Failed to submit report: $e', isError: true);
    }
  }

  Future<String?> _pickTargetCollection() async {
    final collections = await CollectionService.getMyCollections();
    if (!mounted) return null;

    final candidates = collections
        .where((c) => c.id != widget.collectionId)
        .toList(growable: false);

    if (candidates.isEmpty) {
      showGlobalSnackBar('No other collection available.', isError: true);
      return null;
    }

    String? targetId;
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (_) => StatefulBuilder(
        builder: (context, setSheetState) => AlertDialog(
          title: Text(widget.isOwner ? 'Move Car' : 'Copy Car'),
          content: DropdownButtonFormField<String>(
            initialValue: targetId,
            decoration: const InputDecoration(
              labelText: 'Target collection',
            ),
            items: candidates
                .map(
                  (c) => DropdownMenuItem<String>(
                    value: c.id,
                    child: Text(c.name),
                  ),
                )
                .toList(),
            onChanged: (value) => setSheetState(() => targetId = value),
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context, false),
              child: const Text('Cancel'),
            ),
            ElevatedButton(
              onPressed: targetId == null
                  ? null
                  : () => Navigator.pop(context, true),
              child: Text(widget.isOwner ? 'Move' : 'Copy'),
            ),
          ],
        ),
      ),
    );

    if (confirmed != true || targetId == null) return null;
    return targetId;
  }

  Future<void> _relocateSingleCar(
      Map<String, dynamic> car, BuildContext sheetContext) async {
    if (widget.isViewer) {
      showGlobalSnackBar('Viewer role is read-only for this collection.');
      return;
    }

    try {
      final targetId = await _pickTargetCollection();
      if (targetId == null) return;

      if (widget.isOwner) {
        await supabase
            .from('hotwheels')
            .update({'collection_id': targetId})
            .eq('id', car['id']);
      } else {
        final notes = car['notes'] as String?;
        final imagePath = car['user_image_url'] as String?;
        await supabase.from('hotwheels').insert({
          'hw_id': car['hw_id'] as String,
          'user_id': supabase.auth.currentUser!.id,
          'collection_id': targetId,
          if (notes != null && notes.trim().isNotEmpty) 'notes': notes,
          if (imagePath != null && imagePath.isNotEmpty)
            'user_image_url': imagePath,
        });
      }

      if (!mounted) return;
      if (sheetContext.mounted) Navigator.pop(sheetContext);
      showGlobalSnackBar(widget.isOwner
          ? '${car['hw_id']} moved to another collection.'
          : '${car['hw_id']} copied to another collection.');
      await _loadCars(reset: true);
    } catch (e) {
      showGlobalSnackBar(
        widget.isOwner ? 'Failed to move car: $e' : 'Failed to copy car: $e',
        isError: true,
      );
    }
  }

  Future<void> _deleteCar(
      Map<String, dynamic> car, BuildContext sheetContext) async {
    if (!widget.canModifyCars) {
      showGlobalSnackBar('Viewer role is read-only for this collection.');
      return;
    }

    if (!sheetContext.mounted) return;
    final confirmed = await showDialog<bool>(
      context: sheetContext,
      builder: (_) => AlertDialog(
        title: const Text('Remove Car?'),
        content: Text(
            'Remove ${car['hw_id']} from your garage? This cannot be undone.'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(sheetContext, false),
            child: const Text('Cancel'),
          ),
          ElevatedButton(
            onPressed: () => Navigator.pop(sheetContext, true),
            style: ElevatedButton.styleFrom(backgroundColor: AppColors.error),
            child: const Text('Remove'),
          ),
        ],
      ),
    );

    if (confirmed != true) return;

    try {
      // Delete image from storage first (best-effort).
      await StorageService.deleteCarImage(car['user_image_url'] as String?);

      await supabase
          .from('hotwheels')
          .delete()
          .eq('id', car['id']);

      if (!mounted) return;
      if (sheetContext.mounted) {
        Navigator.pop(sheetContext); // close bottom sheet
      }
      showGlobalSnackBar('${car['hw_id']} removed from your garage.');
      _loadCars(reset: true);
    } catch (e) {
      showGlobalSnackBar('Failed to remove: $e', isError: true);
    }
  }
}

// ── Helper widgets ──────────────────────────────────────────────────

class _StatChip extends StatelessWidget {
  final IconData icon;
  final String label;
  final String subtitle;
  const _StatChip({
    required this.icon,
    required this.label,
    required this.subtitle,
  });

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
        decoration: BoxDecoration(
          color: Theme.of(context).cardTheme.color,
          borderRadius: BorderRadius.circular(14),
          boxShadow: const [
            BoxShadow(
              color: Colors.black12,
              blurRadius: 6,
              offset: Offset(0, 2),
            ),
          ],
        ),
        child: Row(
          children: [
            Container(
              padding: const EdgeInsets.all(8),
              decoration: BoxDecoration(
                color: AppColors.orange.withValues(alpha: 0.12),
                borderRadius: BorderRadius.circular(10),
              ),
              child: Icon(icon, size: 20, color: AppColors.orange),
            ),
            const SizedBox(width: 12),
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  label,
                  style: const TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.w700,
                  ),
                ),
                Text(
                  subtitle,
                  style: const TextStyle(
                    fontSize: 11,
                    color: AppColors.textSecondary,
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

class _EmptyGarage extends StatelessWidget {
  final bool hasSearch;
  const _EmptyGarage({required this.hasSearch});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(40),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(
              hasSearch ? Icons.search_off : Icons.garage_outlined,
              size: 64,
              color: AppColors.textHint,
            ),
            const SizedBox(height: 16),
            Text(
              hasSearch ? 'No cars match your search' : 'Your garage is empty',
              style: const TextStyle(
                fontSize: 18,
                fontWeight: FontWeight.w600,
                color: AppColors.textSecondary,
              ),
            ),
            const SizedBox(height: 8),
            Text(
              hasSearch
                  ? 'Try a different search term'
                  : 'Scan your first Hot Wheels car to get started!',
              textAlign: TextAlign.center,
              style: const TextStyle(color: AppColors.textHint),
            ),
          ],
        ),
      ),
    );
  }
}

class _ErrorView extends StatelessWidget {
  final String message;
  final VoidCallback onRetry;
  const _ErrorView({required this.message, required this.onRetry});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(40),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Icon(Icons.error_outline, size: 56, color: AppColors.error),
            const SizedBox(height: 16),
            Text(message,
                textAlign: TextAlign.center,
                style: const TextStyle(color: AppColors.textSecondary)),
            const SizedBox(height: 16),
            ElevatedButton.icon(
              onPressed: onRetry,
              icon: const Icon(Icons.refresh),
              label: const Text('Retry'),
            ),
          ],
        ),
      ),
    );
  }
}

// ── Edit Car Dialog ─────────────────────────────────────────────────
class _EditCarDialog extends StatefulWidget {
  final Map<String, dynamic> car;
  const _EditCarDialog({required this.car});

  @override
  State<_EditCarDialog> createState() => _EditCarDialogState();
}

class _EditCarDialogState extends State<_EditCarDialog> {
  late final TextEditingController _notesCtrl;

  @override
  void initState() {
    super.initState();
    _notesCtrl =
        TextEditingController(text: widget.car['notes'] as String? ?? '');
  }

  @override
  void dispose() {
    _notesCtrl.dispose();
    super.dispose();
  }

  void _save() {
    final updates = <String, dynamic>{};

    final notes = _notesCtrl.text.trim();

    updates['notes'] = notes.isEmpty ? null : notes;

    Navigator.pop(context, updates);
  }

  @override
  Widget build(BuildContext context) {
    final hwId = widget.car['hw_id'] as String? ?? '???';
    return AlertDialog(
      icon: Container(
        padding: const EdgeInsets.all(12),
        decoration: const BoxDecoration(
          gradient: AppColors.brandGradient,
          shape: BoxShape.circle,
        ),
        child: const Icon(Icons.edit, color: Colors.white, size: 28),
      ),
      title: Text('Edit $hwId'),
      content: SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            TextField(
              controller: _notesCtrl,
              maxLines: 4,
              decoration: const InputDecoration(
                labelText: 'Notes',
                hintText: 'Any extra info…',
              ),
            ),
          ],
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('Cancel'),
        ),
        ElevatedButton(
          onPressed: _save,
          child: const Text('Save'),
        ),
      ],
    );
  }
}

class _CarReportDraft {
  final String reason;
  final String? note;

  const _CarReportDraft({
    required this.reason,
    this.note,
  });
}

class _ReportCarDialog extends StatefulWidget {
  const _ReportCarDialog();

  @override
  State<_ReportCarDialog> createState() => _ReportCarDialogState();
}

class _ReportCarDialogState extends State<_ReportCarDialog> {
  static const List<String> _reasons = [
    'Wrong model name',
    'Wrong series or year',
    'Duplicate catalog entry',
    'Invalid image',
    'Other',
  ];

  String _selectedReason = _reasons.first;
  final TextEditingController _noteCtrl = TextEditingController();

  @override
  void dispose() {
    _noteCtrl.dispose();
    super.dispose();
  }

  void _submit() {
    final note = _noteCtrl.text.trim();
    Navigator.pop(
      context,
      _CarReportDraft(
        reason: _selectedReason,
        note: note.isEmpty ? null : note,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      icon: const Icon(Icons.flag_outlined, color: AppColors.orange, size: 32),
      title: const Text('Report catalog issue'),
      content: SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            DropdownButtonFormField<String>(
              isExpanded: true,
              initialValue: _selectedReason,
              decoration: const InputDecoration(
                labelText: 'Reason',
              ),
              items: _reasons
                  .map(
                    (reason) => DropdownMenuItem<String>(
                      value: reason,
                      child: Text(
                        reason,
                        overflow: TextOverflow.ellipsis,
                        maxLines: 1,
                      ),
                    ),
                  )
                  .toList(),
              onChanged: (value) {
                if (value == null) return;
                setState(() => _selectedReason = value);
              },
            ),
            const SizedBox(height: 12),
            TextField(
              controller: _noteCtrl,
              maxLines: 3,
              decoration: const InputDecoration(
                labelText: 'Details (optional)',
                hintText: 'Add a short note to help moderation…',
              ),
            ),
          ],
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('Cancel'),
        ),
        ElevatedButton(
          onPressed: _submit,
          child: const Text('Submit Report'),
        ),
      ],
    );
  }
}

class _DetailRow extends StatelessWidget {
  final IconData icon;
  final String label;
  final String value;
  const _DetailRow({
    required this.icon,
    required this.label,
    required this.value,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 6),
      child: Row(
        children: [
          Icon(icon, size: 18, color: AppColors.textHint),
          const SizedBox(width: 10),
          Text(
            '$label: ',
            style: const TextStyle(
              fontWeight: FontWeight.w500,
              color: AppColors.textSecondary,
            ),
          ),
          Expanded(
            child: Text(value,
                style: const TextStyle(fontWeight: FontWeight.w500)),
          ),
        ],
      ),
    );
  }
}
