// lib/screens/home_screen.dart
import 'dart:async';
import 'dart:ui';
import '../core/utils/error_utils.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../core/auth/auth_guard.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:intl/intl.dart';

import '../features/events/models/event_models.dart';
import '../features/events/services/events_service.dart';
import 'calendar_screen.dart';
import 'profile_screen.dart';
import 'contribute_screen.dart';
import 'learn_more_screen.dart';
import 'search_screen.dart';
import '../core/app_decoration.dart';
import 'package:geocoding/geocoding.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';
import '../features/gamification/providers/gamification_provider.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

/// Main screen that hosts 4 tabs in an IndexedStack (Home, Calendar, Contribute, Profile).
class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateMixin {
  int _selectedIndex = 0;
  String _username = '';
  String _location = '';
  String _pincode = 'all';

  final EventsService _eventsService = EventsService();

  // backend-driven
  List<EventModel> _allEvents = []; // master copy, never filtered
  List<EventModel> _events = [];
  List<EventTypeModel> _types = [];
  int _selectedTypeId = -1; // -1 == All
  bool _categoriesExpanded = false;

  bool _loading = true;

  // Hero carousel
  final PageController _heroPageController = PageController(viewportFraction: 0.88);
  late final ValueNotifier<int> _heroPageNotifier;
  Timer? _autoScrollTimer;

  @override
  void initState() {
    super.initState();
    _heroPageNotifier = ValueNotifier(0);
    _loadUserDataAndEvents();
    _startAutoScroll();
  }

  @override
  void dispose() {
    _autoScrollTimer?.cancel();
    _heroPageController.dispose();
    _heroPageNotifier.dispose();
    super.dispose();
  }

  void _startAutoScroll({Duration delay = const Duration(seconds: 5)}) {
    _autoScrollTimer?.cancel();
    _autoScrollTimer = Timer.periodic(delay, (timer) {
      if (_heroEvents.isEmpty) return;
      final nextPage = (_heroPageNotifier.value + 1) % _heroEvents.length;
      if (_heroPageController.hasClients) {
        _heroPageController.animateToPage(
          nextPage,
          duration: const Duration(milliseconds: 400),
          curve: Curves.easeInOut,
        );
      }
    });
  }

  Future<void> _loadUserDataAndEvents() async {
    setState(() => _loading = true);
    final prefs = await SharedPreferences.getInstance();
    _username = prefs.getString('display_name') ?? prefs.getString('username') ?? '';
    final storedLocation = prefs.getString('location') ?? 'Whitefield, Bengaluru';
    // Fix legacy lat,lng strings saved before the reverse-geocoding fix
    final coordMatch = RegExp(r'^(-?\d+\.?\d*),\s*(-?\d+\.?\d*)$').firstMatch(storedLocation);
    if (coordMatch != null) {
      _location = 'Current Location';
      // Reverse geocode in background to get actual place name
      _reverseGeocodeAndSave(
        double.parse(coordMatch.group(1)!),
        double.parse(coordMatch.group(2)!),
        prefs,
      );
    } else {
      _location = storedLocation;
    }
    _pincode = prefs.getString('pincode') ?? 'all';

    try {
      // Fetch types and events in parallel for faster loading
      final results = await Future.wait([
        _events_service_getEventTypesSafe(),
        _events_service_getEventsSafe(_pincode),
      ]);
      final types = results[0] as List<EventTypeModel>;
      final events = results[1] as List<EventModel>;
      if (mounted) {
        setState(() {
          _types = types;
          _allEvents = events;
          _events = events;
          _selectedTypeId = -1;
          _cachedFilteredEvents = null;
          _cachedEventDates = null;
          _loading = false;
        });
      }
    } catch (e) {
      if (mounted) {
        setState(() => _loading = false);
        ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(userFriendlyError(e))));
      }
    }
  }

  Future<void> _reverseGeocodeAndSave(double lat, double lng, SharedPreferences prefs) async {
    try {
      final placemarks = await placemarkFromCoordinates(lat, lng);
      if (placemarks.isNotEmpty) {
        final p = placemarks.first;
        final parts = <String>[];
        if ((p.subLocality ?? '').isNotEmpty) parts.add(p.subLocality!);
        if ((p.locality ?? '').isNotEmpty) parts.add(p.locality!);
        if ((p.subAdministrativeArea ?? '').isNotEmpty) parts.add(p.subAdministrativeArea!);
        final label = parts.isNotEmpty ? parts.join(', ') : 'Current Location';
        await prefs.setString('location', label);
        if (mounted) setState(() => _location = label);
        return;
      }
    } catch (_) {}
    await prefs.setString('location', 'Current Location');
  }

  Future<List<EventTypeModel>> _events_service_getEventTypesSafe() async {
    try {
      return await _eventsService.getEventTypes();
    } catch (_) {
      return <EventTypeModel>[];
    }
  }

  Future<List<EventModel>> _events_service_getEventsSafe(String pincode) async {
    try {
      return await _eventsService.getEventsByPincode(pincode);
    } catch (_) {
      return <EventModel>[];
    }
  }

  Future<void> _refresh() async {
    await _loadUserDataAndEvents();
  }

  void _bookEventAtIndex(int index) {
    if (index >= 0 && index < _events.length) {
      setState(() => _events.removeAt(index));
    }
  }

  Widget _categoryChip({
    required String label,
    required bool selected,
    required VoidCallback onTap,
    String? imageUrl,
    IconData? icon,
  }) {
    final theme = Theme.of(context);
    return GestureDetector(
      onTap: onTap,
      child: Container(
        width: 110,
        decoration: BoxDecoration(
          color: selected ? theme.colorScheme.primary : Colors.white,
          borderRadius: BorderRadius.circular(18),
          border: Border.all(
            color: selected ? theme.colorScheme.primary : const Color(0xFFE5E7EB),
            width: 1.5,
          ),
          boxShadow: [
            BoxShadow(
              color: selected
                  ? theme.colorScheme.primary.withValues(alpha: 0.35)
                  : Colors.black.withValues(alpha: 0.08),
              blurRadius: selected ? 12 : 8,
              offset: const Offset(0, 4),
            ),
          ],
        ),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // Image / Icon area
            SizedBox(
              height: 56,
              width: 56,
              child: imageUrl != null && imageUrl.isNotEmpty
                  ? ClipRRect(
                      borderRadius: BorderRadius.circular(12),
                      child: CachedNetworkImage(
                        imageUrl: imageUrl,
                        memCacheWidth: 112,
                        memCacheHeight: 112,
                        fit: BoxFit.contain,
                        placeholder: (_, __) => Icon(
                          icon ?? Icons.category,
                          size: 36,
                          color: selected ? Colors.white.withOpacity(0.5) : theme.colorScheme.primary.withOpacity(0.3),
                        ),
                        errorWidget: (_, __, ___) => Icon(
                          icon ?? Icons.category,
                          size: 36,
                          color: selected ? Colors.white : theme.colorScheme.primary,
                        ),
                      ),
                    )
                  : Icon(
                      icon ?? Icons.category,
                      size: 36,
                      color: selected ? Colors.white : theme.colorScheme.primary,
                    ),
            ),
            const SizedBox(height: 10),
            // Label
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 6),
              child: Text(
                label,
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
                textAlign: TextAlign.center,
                style: TextStyle(
                  fontSize: 13,
                  fontWeight: FontWeight.w700,
                  color: selected
                      ? Colors.white
                      : theme.textTheme.bodyLarge?.color ?? Colors.black87,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _openLocationSearch() async {
    final selected = await Navigator.of(context).push(PageRouteBuilder(
      opaque: false,
      pageBuilder: (context, animation, secondaryAnimation) => const SearchScreen(),
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        return FadeTransition(opacity: animation, child: child);
      },
      transitionDuration: const Duration(milliseconds: 220),
    ));

    if (selected != null && selected is String) {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setString('location', selected);
      setState(() {
        _location = selected;
      });
      await _refresh();
    }
  }

  void _openEventSearch() {
    final theme = Theme.of(context);
    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      builder: (ctx) {
        return DraggableScrollableSheet(
          expand: false,
          initialChildSize: 0.6,
          minChildSize: 0.3,
          maxChildSize: 0.95,
          builder: (context, scrollController) {
            String query = '';
            List<EventModel> results = List.from(_events);
            return StatefulBuilder(builder: (context, setModalState) {
              void _onQueryChanged(String v) {
                query = v.trim().toLowerCase();
                final r = _events.where((e) {
                  final title = (e.title ?? e.name ?? '').toLowerCase();
                  return title.contains(query);
                }).toList();
                setModalState(() {
                  results = r;
                });
              }

              return Container(
                decoration: BoxDecoration(
                  color: theme.cardColor,
                  borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
                ),
                child: SafeArea(
                  top: false,
                  child: SingleChildScrollView(
                    controller: scrollController,
                    padding: const EdgeInsets.fromLTRB(16, 12, 16, 24),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Center(
                          child: Container(
                            width: 48,
                            height: 6,
                            decoration: BoxDecoration(color: theme.dividerColor, borderRadius: BorderRadius.circular(6)),
                          ),
                        ),
                        const SizedBox(height: 12),
                        Row(
                          children: [
                            Expanded(
                              child: Container(
                                height: 48,
                                padding: const EdgeInsets.symmetric(horizontal: 12),
                                decoration: BoxDecoration(color: theme.cardColor, borderRadius: BorderRadius.circular(12), border: Border.all(color: theme.dividerColor)),
                                child: Row(
                                  children: [
                                    Icon(Icons.search, color: theme.hintColor),
                                    const SizedBox(width: 8),
                                    Expanded(
                                      child: TextField(
                                        style: theme.textTheme.bodyLarge,
                                        decoration: InputDecoration(
                                          hintText: 'Search events by name',
                                          hintStyle: theme.textTheme.bodyMedium?.copyWith(color: theme.hintColor),
                                          border: InputBorder.none,
                                        ),
                                        autofocus: true,
                                        onChanged: _onQueryChanged,
                                        textInputAction: TextInputAction.search,
                                        onSubmitted: (v) => _onQueryChanged(v),
                                      ),
                                    )
                                  ],
                                ),
                              ),
                            ),
                            const SizedBox(width: 8),
                            IconButton(
                              icon: Icon(Icons.close, color: theme.iconTheme.color),
                              onPressed: () => Navigator.of(context).pop(),
                            )
                          ],
                        ),
                        const SizedBox(height: 12),
                        if (_loading)
                          Center(child: CircularProgressIndicator(color: theme.colorScheme.primary))
                        else if (results.isEmpty)
                          Padding(
                            padding: const EdgeInsets.symmetric(vertical: 24),
                            child: Center(child: Text(query.isEmpty ? 'Type to search events' : 'No events found', style: theme.textTheme.bodyMedium?.copyWith(color: theme.hintColor))),
                          )
                        else
                          ConstrainedBox(
                            constraints: const BoxConstraints(maxHeight: 400),
                            child: ListView.separated(
                            shrinkWrap: false,
                            physics: const ClampingScrollPhysics(),
                            itemBuilder: (ctx, idx) {
                              final ev = results[idx];
                              final img = (ev.thumbImg != null && ev.thumbImg!.isNotEmpty) ? ev.thumbImg! : (ev.images.isNotEmpty ? ev.images.first.image : null);
                              final title = ev.title ?? ev.name ?? '';
                              final subtitle = ev.startDate ?? '';
                              return ListTile(
                                contentPadding: const EdgeInsets.symmetric(horizontal: 0, vertical: 8),
                                leading: img != null && img.isNotEmpty
                                    ? ClipRRect(
                                        borderRadius: BorderRadius.circular(8),
                                        child: CachedNetworkImage(
                                          imageUrl: img,
                                          memCacheWidth: 112,
                                          memCacheHeight: 112,
                                          width: 56,
                                          height: 56,
                                          fit: BoxFit.cover,
                                          placeholder: (_, __) => Container(width: 56, height: 56, color: theme.dividerColor),
                                          errorWidget: (_, __, ___) => Container(width: 56, height: 56, color: theme.dividerColor, child: Icon(Icons.event, color: theme.hintColor)),
                                        ),
                                      )
                                    : Container(width: 56, height: 56, decoration: BoxDecoration(color: theme.dividerColor, borderRadius: BorderRadius.circular(8)), child: Icon(Icons.event, color: theme.hintColor)),
                                title: Text(title, maxLines: 1, overflow: TextOverflow.ellipsis, style: theme.textTheme.bodyLarge),
                                subtitle: Text(subtitle, maxLines: 1, overflow: TextOverflow.ellipsis, style: theme.textTheme.bodyMedium?.copyWith(color: theme.hintColor)),
                                onTap: () {
                                  Navigator.of(context).pop();
                                  if (ev.id != null) {
                                    Navigator.of(context).push(MaterialPageRoute(builder: (_) => LearnMoreScreen(eventId: ev.id, initialEvent: ev)));
                                  }
                                },
                              );
                            },
                            separatorBuilder: (_, __) => Divider(color: theme.dividerColor),
                            itemCount: results.length,
                          )), // ConstrainedBox
                      ],
                    ),
                  ),
                ),
              );
            });
          },
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Scaffold(
      backgroundColor: theme.scaffoldBackgroundColor,
      body: Stack(
        children: [
          // IndexedStack keeps each tab alive and preserves state.
          // RepaintBoundary isolates each tab so inactive tabs don't trigger repaints.
          IndexedStack(
            index: _selectedIndex,
            children: [
              RepaintBoundary(child: _buildHomeContent()), // index 0
              const RepaintBoundary(child: CalendarScreen()), // index 1
              RepaintBoundary(
                child: ChangeNotifierProvider(
                  create: (_) => GamificationProvider(),
                  child: const ContributeScreen(),
                ),
              ), // index 2 (full page, scrollable)
              const RepaintBoundary(child: ProfileScreen()), // index 3
            ],
          ),

          // Floating bottom navigation (always visible)
          Positioned(
            left: 16,
            right: 16,
            bottom: 16,
            child: _buildFloatingBottomNav(),
          ),
        ],
      ),
    );
  }

  Widget _buildFloatingBottomNav() {
    const activeColor = Color(0xFF2563EB);
    const inactiveColor = Color(0xFF9CA3AF);

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(16),
        boxShadow: [
          BoxShadow(color: Colors.black.withOpacity(0.08), blurRadius: 16, offset: const Offset(0, -2)),
        ],
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          _bottomNavItem(0, Icons.home_outlined, Icons.home, 'Home'),
          _bottomNavItem(1, Icons.calendar_today_outlined, Icons.calendar_today, 'Calendar'),
          _bottomNavItem(2, Icons.front_hand_outlined, Icons.front_hand, 'Contribute'),
          _bottomNavItem(3, Icons.person_outline, Icons.person, 'Profile'),
        ],
      ),
    );
  }

  Widget _bottomNavItem(int index, IconData outlinedIcon, IconData filledIcon, String label) {
    const activeColor = Color(0xFF2563EB);
    const inactiveColor = Color(0xFF9CA3AF);
    final active = _selectedIndex == index;

    return GestureDetector(
      onTap: () {
        if (index == 2 && !AuthGuard.requireLogin(context, reason: 'Sign in to contribute events and earn rewards.')) return;
        if (index == 3 && !AuthGuard.requireLogin(context, reason: 'Sign in to view your profile.')) return;
        setState(() => _selectedIndex = index);
      },
      behavior: HitTestBehavior.opaque,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(
              active ? filledIcon : outlinedIcon,
              color: active ? activeColor : inactiveColor,
              size: 24,
            ),
            const SizedBox(height: 4),
            Text(
              label,
              style: TextStyle(
                color: active ? activeColor : inactiveColor,
                fontSize: 11,
                fontWeight: active ? FontWeight.w600 : FontWeight.w400,
              ),
            ),
          ],
        ),
      ),
    );
  }


  // Get hero events (first 4 events for the carousel)
  List<EventModel> get _heroEvents => _events.take(6).toList();

  String _formatDate(String dateStr) {
    try {
      final dt = DateTime.parse(dateStr);
      return DateFormat('d MMM yyyy').format(dt);
    } catch (_) {
      return dateStr;
    }
  }

  String _getEventTypeName(EventModel event) {
    if (event.eventTypeId != null && event.eventTypeId! > 0) {
      final match = _types.where((t) => t.id == event.eventTypeId);
      if (match.isNotEmpty && match.first.name.isNotEmpty) {
        return match.first.name.toUpperCase();
      }
    }
    return 'EVENT';
  }

  // Date filter state
  String _selectedDateFilter = '';
  DateTime? _selectedCustomDate;

  // Cached filtered events to avoid repeated DateTime.parse() calls
  List<EventModel>? _cachedFilteredEvents;
  String _cachedFilterKey = '';

  // Cached event dates for calendar dots
  Set<DateTime>? _cachedEventDates;

  /// Returns all events filtered by date only (ignores category selection).
  /// Used by Top Events and category sections so they always show all types.
  List<EventModel> get _allFilteredByDate {
    if (_selectedDateFilter.isEmpty) return _allEvents;
    // Reuse the same date-filter logic as _filteredEvents but on _allEvents
    final now = DateTime.now();
    final today = DateTime(now.year, now.month, now.day);
    DateTime filterStart;
    DateTime filterEnd;
    switch (_selectedDateFilter) {
      case 'Today':
        filterStart = today;
        filterEnd = today;
        break;
      case 'Tomorrow':
        filterStart = today.add(const Duration(days: 1));
        filterEnd = filterStart;
        break;
      case 'This week':
        filterStart = today;
        filterEnd = today.add(Duration(days: 7 - today.weekday));
        break;
      case 'Date':
        if (_selectedCustomDate == null) return _allEvents;
        filterStart = DateTime(_selectedCustomDate!.year, _selectedCustomDate!.month, _selectedCustomDate!.day);
        filterEnd = filterStart;
        break;
      default:
        return _allEvents;
    }
    return _allEvents.where((e) {
      try {
        final s = DateTime.parse(e.startDate);
        final eEnd = DateTime.parse(e.endDate);
        final eStart = DateTime(s.year, s.month, s.day);
        final eEndDay = DateTime(eEnd.year, eEnd.month, eEnd.day);
        return !eEndDay.isBefore(filterStart) && !eStart.isAfter(filterEnd);
      } catch (_) {
        return false;
      }
    }).toList();
  }

  /// Returns the subset of [_events] that match the active date-filter chip.
  /// Uses caching to avoid re-parsing dates on every access.
  List<EventModel> get _filteredEvents {
    if (_selectedDateFilter.isEmpty) return _events;

    // Build a cache key from filter state
    final cacheKey = '$_selectedDateFilter|$_selectedCustomDate|${_events.length}';
    if (_cachedFilteredEvents != null && _cachedFilterKey == cacheKey) {
      return _cachedFilteredEvents!;
    }

    final now = DateTime.now();
    final today = DateTime(now.year, now.month, now.day);

    DateTime filterStart;
    DateTime filterEnd;

    switch (_selectedDateFilter) {
      case 'Today':
        filterStart = today;
        filterEnd = today;
        break;
      case 'Tomorrow':
        final tomorrow = today.add(const Duration(days: 1));
        filterStart = tomorrow;
        filterEnd = tomorrow;
        break;
      case 'This week':
        // Monday–Sunday of the current week
        final weekday = today.weekday; // 1=Mon
        filterStart = today.subtract(Duration(days: weekday - 1));
        filterEnd = filterStart.add(const Duration(days: 6));
        break;
      case 'Date':
        if (_selectedCustomDate == null) return _events;
        filterStart = _selectedCustomDate!;
        filterEnd = _selectedCustomDate!;
        break;
      default:
        return _events;
    }

    _cachedFilteredEvents = _events.where((e) {
      try {
        final eStart = DateTime.parse(e.startDate);
        final eEnd = DateTime.parse(e.endDate);
        // Event overlaps with filter range
        return !eEnd.isBefore(filterStart) && !eStart.isAfter(filterEnd);
      } catch (_) {
        return false;
      }
    }).toList();
    _cachedFilterKey = cacheKey;
    return _cachedFilteredEvents!;
  }

  Future<void> _onDateChipTap(String label) async {
    if (label == 'Date') {
      // Open custom calendar dialog
      final picked = await _showCalendarDialog();
      if (picked != null) {
        setState(() {
          _selectedCustomDate = picked;
          _selectedDateFilter = 'Date';
          _cachedFilteredEvents = null; // invalidate cache
        });
        _showFilteredEventsSheet(
          '${picked.day.toString().padLeft(2, '0')} ${_monthName(picked.month)} ${picked.year}',
        );
      } else if (_selectedDateFilter == 'Date') {
        setState(() {
          _selectedDateFilter = '';
          _selectedCustomDate = null;
          _cachedFilteredEvents = null;
        });
      }
    } else {
      setState(() {
        _selectedDateFilter = label;
        _selectedCustomDate = null;
        _cachedFilteredEvents = null; // invalidate cache
      });
      _showFilteredEventsSheet(label);
    }
  }

  String _monthName(int m) {
    const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    return months[m - 1];
  }

  /// Shows a bottom sheet with events matching the current filter chip.
  void _showFilteredEventsSheet(String title) {
    final theme = Theme.of(context);
    final filtered = _filteredEvents;
    final count = filtered.length;

    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      barrierColor: Colors.black.withValues(alpha: 0.5),
      builder: (ctx) {
        return DraggableScrollableSheet(
          expand: false,
          initialChildSize: 0.55,
          minChildSize: 0.3,
          maxChildSize: 0.85,
          builder: (context, scrollController) {
            return Container(
              decoration: const BoxDecoration(
                color: Color(0xFFEAEFFE), // lavender sheet bg matching web
                borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
              ),
              child: Column(
                children: [
                  // Drag handle
                  Padding(
                    padding: const EdgeInsets.only(top: 12, bottom: 8),
                    child: Center(
                      child: Container(
                        width: 40,
                        height: 5,
                        decoration: BoxDecoration(
                          color: Colors.grey.shade400,
                          borderRadius: BorderRadius.circular(3),
                        ),
                      ),
                    ),
                  ),

                  // Header row: title + close button
                  Padding(
                    padding: const EdgeInsets.fromLTRB(20, 4, 12, 12),
                    child: Row(
                      children: [
                        Expanded(
                          child: Text(
                            '$title ($count)',
                            style: const TextStyle(
                              fontSize: 20,
                              fontWeight: FontWeight.w700,
                              color: Color(0xFF1A1A1A),
                            ),
                          ),
                        ),
                        GestureDetector(
                          onTap: () {
                            Navigator.of(context).pop();
                            setState(() {
                              _selectedDateFilter = '';
                              _selectedCustomDate = null;
                            });
                          },
                          child: Container(
                            width: 32,
                            height: 32,
                            decoration: BoxDecoration(
                              color: Colors.grey.shade300,
                              shape: BoxShape.circle,
                            ),
                            child: const Icon(Icons.close, size: 18, color: Color(0xFF1A1A1A)),
                          ),
                        ),
                      ],
                    ),
                  ),

                  // Events list
                  Expanded(
                    child: filtered.isEmpty
                        ? Padding(
                            padding: const EdgeInsets.all(24),
                            child: Container(
                              width: double.infinity,
                              padding: const EdgeInsets.symmetric(vertical: 32, horizontal: 16),
                              decoration: BoxDecoration(
                                color: Colors.white,
                                borderRadius: BorderRadius.circular(16),
                              ),
                              child: const Text(
                                '\u{1F3D7}\u{FE0F} No events scheduled for this period',
                                textAlign: TextAlign.center,
                                style: TextStyle(
                                  fontSize: 15,
                                  fontWeight: FontWeight.w500,
                                  color: Color(0xFF6B7280),
                                ),
                              ),
                            ),
                          )
                        : ListView.builder(
                            controller: scrollController,
                            padding: const EdgeInsets.fromLTRB(16, 0, 16, 24),
                            itemCount: filtered.length,
                            itemBuilder: (ctx, idx) {
                              final ev = filtered[idx];
                              return _buildSheetEventCard(ev, theme);
                            },
                          ),
                  ),
                ],
              ),
            );
          },
        );
      },
    ).whenComplete(() {
      // Clear filter when sheet is dismissed
      setState(() {
        _selectedDateFilter = '';
        _selectedCustomDate = null;
      });
    });
  }

  /// Builds an event card for the filter bottom sheet, matching web design.
  Widget _buildSheetEventCard(EventModel ev, ThemeData theme) {
    final title = ev.title ?? ev.name ?? '';
    final dateLabel = ev.startDate ?? '';
    final location = ev.place ?? 'Location';
    final imageUrl = (ev.thumbImg != null && ev.thumbImg!.isNotEmpty)
        ? ev.thumbImg!
        : (ev.images.isNotEmpty ? ev.images.first.image : null);

    Widget imageWidget;
    if (imageUrl != null && imageUrl.isNotEmpty && imageUrl.startsWith('http')) {
      imageWidget = ClipRRect(
        borderRadius: BorderRadius.circular(12),
        child: CachedNetworkImage(
          imageUrl: imageUrl,
          memCacheWidth: 160,
          memCacheHeight: 160,
          width: 80,
          height: 80,
          fit: BoxFit.cover,
          placeholder: (_, __) => Container(
            width: 80, height: 80,
            decoration: BoxDecoration(color: Colors.grey.shade200, borderRadius: BorderRadius.circular(12)),
            child: const Center(child: SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2))),
          ),
          errorWidget: (_, __, ___) => Container(
            width: 80, height: 80,
            decoration: BoxDecoration(color: Colors.grey.shade200, borderRadius: BorderRadius.circular(12)),
            child: Icon(Icons.image, color: Colors.grey.shade400),
          ),
        ),
      );
    } else {
      imageWidget = Container(
        width: 80, height: 80,
        decoration: BoxDecoration(color: Colors.grey.shade200, borderRadius: BorderRadius.circular(12)),
        child: Icon(Icons.image, color: Colors.grey.shade400),
      );
    }

    return GestureDetector(
      onTap: () {
        Navigator.of(context).pop();
        if (ev.id != null) {
          Navigator.of(context).push(MaterialPageRoute(builder: (_) => LearnMoreScreen(eventId: ev.id, initialEvent: ev)));
        }
      },
      child: Container(
        margin: const EdgeInsets.only(bottom: 12),
        padding: const EdgeInsets.all(12),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(16),
          boxShadow: [
            BoxShadow(
              color: Colors.black.withValues(alpha: 0.04),
              blurRadius: 8,
              offset: const Offset(0, 2),
            ),
          ],
        ),
        child: Row(
          children: [
            imageWidget,
            const SizedBox(width: 12),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    title,
                    maxLines: 2,
                    overflow: TextOverflow.ellipsis,
                    style: const TextStyle(
                      fontSize: 15,
                      fontWeight: FontWeight.w700,
                      color: Color(0xFF1A1A1A),
                    ),
                  ),
                  const SizedBox(height: 4),
                  Row(
                    children: [
                      Icon(Icons.calendar_today, size: 13, color: Colors.grey.shade500),
                      const SizedBox(width: 4),
                      Expanded(
                        child: Text(
                          dateLabel,
                          style: TextStyle(fontSize: 13, color: Colors.grey.shade500),
                          overflow: TextOverflow.ellipsis,
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 2),
                  Row(
                    children: [
                      Icon(Icons.location_on_outlined, size: 13, color: Colors.grey.shade500),
                      const SizedBox(width: 4),
                      Expanded(
                        child: Text(
                          location,
                          style: TextStyle(fontSize: 13, color: Colors.grey.shade500),
                          overflow: TextOverflow.ellipsis,
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 4),
                  Text(
                    'Free',
                    style: TextStyle(
                      fontSize: 14,
                      fontWeight: FontWeight.w600,
                      color: theme.colorScheme.primary,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// Collect all event dates (start + end range) to show dots on the calendar.
  /// Cached to avoid re-parsing on every calendar open.
  Set<DateTime> get _eventDates {
    if (_cachedEventDates != null) return _cachedEventDates!;
    final dates = <DateTime>{};
    for (final e in _allEvents) {
      try {
        final start = DateTime.parse(e.startDate);
        final end = DateTime.parse(e.endDate);
        var d = DateTime(start.year, start.month, start.day);
        final last = DateTime(end.year, end.month, end.day);
        while (!d.isAfter(last)) {
          dates.add(d);
          d = d.add(const Duration(days: 1));
        }
      } catch (_) {}
    }
    _cachedEventDates = dates;
    return dates;
  }

  /// Show a custom calendar dialog matching the app design.
  Future<DateTime?> _showCalendarDialog() {
    DateTime viewMonth = _selectedCustomDate ?? DateTime.now();
    DateTime? selected = _selectedCustomDate;
    final eventDates = _eventDates;

    return showDialog<DateTime>(
      context: context,
      barrierColor: Colors.black54,
      builder: (ctx) {
        return StatefulBuilder(builder: (ctx, setDialogState) {
          final now = DateTime.now();
          final today = DateTime(now.year, now.month, now.day);

          // Calendar calculations
          final firstDayOfMonth = DateTime(viewMonth.year, viewMonth.month, 1);
          final daysInMonth = DateTime(viewMonth.year, viewMonth.month + 1, 0).day;
          final startWeekday = firstDayOfMonth.weekday; // 1=Mon

          const months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
          const dayHeaders = ['M', 'T', 'W', 'T', 'F', 'S', 'S'];

          return Center(
            child: Container(
              margin: const EdgeInsets.symmetric(horizontal: 28),
              padding: const EdgeInsets.fromLTRB(20, 24, 20, 20),
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(24),
                boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.15), blurRadius: 20, offset: const Offset(0, 8))],
              ),
              child: Material(
                color: Colors.transparent,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    // Month navigation
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        _calendarNavButton(Icons.chevron_left, () {
                          setDialogState(() {
                            viewMonth = DateTime(viewMonth.year, viewMonth.month - 1, 1);
                          });
                        }),
                        Text(
                          '${months[viewMonth.month - 1]} ${viewMonth.year}',
                          style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF1A1A2E)),
                        ),
                        _calendarNavButton(Icons.chevron_right, () {
                          setDialogState(() {
                            viewMonth = DateTime(viewMonth.year, viewMonth.month + 1, 1);
                          });
                        }),
                      ],
                    ),
                    const SizedBox(height: 20),

                    // Day of week headers
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: dayHeaders.map((d) => SizedBox(
                        width: 36,
                        child: Center(child: Text(d, style: TextStyle(color: Colors.grey[500], fontWeight: FontWeight.w600, fontSize: 13))),
                      )).toList(),
                    ),
                    const SizedBox(height: 12),

                    // Calendar grid
                    ...List.generate(6, (weekRow) {
                      return Padding(
                        padding: const EdgeInsets.only(bottom: 4),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceAround,
                          children: List.generate(7, (weekCol) {
                            final cellIndex = weekRow * 7 + weekCol;
                            final dayNum = cellIndex - (startWeekday - 1) + 1;

                            if (dayNum < 1 || dayNum > daysInMonth) {
                              return const SizedBox(width: 36, height: 44);
                            }

                            final cellDate = DateTime(viewMonth.year, viewMonth.month, dayNum);
                            final isToday = cellDate == today;
                            final isSelected = selected != null &&
                                cellDate.year == selected!.year &&
                                cellDate.month == selected!.month &&
                                cellDate.day == selected!.day;
                            final hasEvent = eventDates.contains(cellDate);

                            return GestureDetector(
                              onTap: () {
                                setDialogState(() => selected = cellDate);
                              },
                              child: SizedBox(
                                width: 36,
                                height: 44,
                                child: Column(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: [
                                    Container(
                                      width: 34,
                                      height: 34,
                                      decoration: BoxDecoration(
                                        color: isSelected
                                            ? const Color(0xFF2563EB)
                                            : Colors.transparent,
                                        shape: BoxShape.circle,
                                        border: isToday && !isSelected
                                            ? Border.all(color: const Color(0xFF2563EB), width: 1.5)
                                            : null,
                                      ),
                                      child: Center(
                                        child: Text(
                                          '$dayNum',
                                          style: TextStyle(
                                            fontSize: 15,
                                            fontWeight: (isToday || isSelected) ? FontWeight.w700 : FontWeight.w500,
                                            color: isSelected
                                                ? Colors.white
                                                : isToday
                                                    ? const Color(0xFF2563EB)
                                                    : const Color(0xFF374151),
                                          ),
                                        ),
                                      ),
                                    ),
                                    // Event dot
                                    if (hasEvent)
                                      Container(
                                        width: 5,
                                        height: 5,
                                        decoration: BoxDecoration(
                                          color: isSelected ? Colors.white : const Color(0xFFEF4444),
                                          shape: BoxShape.circle,
                                        ),
                                      )
                                    else
                                      const SizedBox(height: 5),
                                  ],
                                ),
                              ),
                            );
                          }),
                        ),
                      );
                    }),

                    const SizedBox(height: 12),

                    // Done button
                    SizedBox(
                      width: 160,
                      height: 48,
                      child: ElevatedButton(
                        onPressed: () => Navigator.of(ctx).pop(selected),
                        style: ElevatedButton.styleFrom(
                          backgroundColor: const Color(0xFF2563EB),
                          foregroundColor: Colors.white,
                          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
                          elevation: 0,
                        ),
                        child: const Text('Done', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          );
        });
      },
    );
  }

  Widget _calendarNavButton(IconData icon, VoidCallback onTap) {
    return InkWell(
      onTap: onTap,
      borderRadius: BorderRadius.circular(20),
      child: Container(
        width: 40,
        height: 40,
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          border: Border.all(color: Colors.grey[300]!),
        ),
        child: Icon(icon, color: const Color(0xFF374151), size: 22),
      ),
    );
  }

  Widget _buildHomeContent() {
    return Container(
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: [
            Color(0xFF1A0A2E), // deep purple
            Color(0xFF16213E), // dark navy
            Color(0xFF0A0A0A), // near black
          ],
          stops: [0.0, 0.4, 0.8],
        ),
      ),
      child: CustomScrollView(
        slivers: [
          // Hero section (dark bg)
          SliverToBoxAdapter(child: _buildHeroSection()),
          // White bottom section
          SliverToBoxAdapter(
            child: Container(
              decoration: const BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.vertical(top: Radius.circular(30)),
              ),
              child: _buildWhiteSection(),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildHeroSection() {
    return SafeArea(
      bottom: false,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          // Top bar: location pill + search button
          Padding(
            padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                GestureDetector(
                  onTap: _openLocationSearch,
                  child: Container(
                    padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
                    decoration: BoxDecoration(
                      color: Colors.white.withOpacity(0.15),
                      borderRadius: BorderRadius.circular(25),
                      border: Border.all(color: Colors.white.withOpacity(0.2)),
                    ),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        const Icon(Icons.location_on_outlined, color: Colors.white, size: 18),
                        const SizedBox(width: 6),
                        Text(
                          _location.length > 20 ? '${_location.substring(0, 20)}...' : _location,
                          style: const TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500),
                        ),
                        const SizedBox(width: 4),
                        const Icon(Icons.keyboard_arrow_down, color: Colors.white, size: 18),
                      ],
                    ),
                  ),
                ),
                GestureDetector(
                  onTap: _openEventSearch,
                  child: Container(
                    width: 48,
                    height: 48,
                    decoration: BoxDecoration(
                      color: Colors.white.withOpacity(0.15),
                      shape: BoxShape.circle,
                      border: Border.all(color: Colors.white.withOpacity(0.2)),
                    ),
                    child: const Icon(Icons.search, color: Colors.white, size: 24),
                  ),
                ),
              ],
            ),
          ),
          const SizedBox(height: 24),

          // Featured carousel
          _heroEvents.isEmpty
              ? _loading
                  ? const Padding(
                      padding: EdgeInsets.symmetric(horizontal: 8),
                      child: SizedBox(
                        height: 320,
                        child: _HeroShimmer(),
                      ),
                    )
                  : const SizedBox(
                      height: 280,
                      child: Center(
                        child: Text('No events available',
                            style: TextStyle(color: Colors.white70)),
                      ),
                    )
              : Column(
                  children: [
                    RepaintBoundary(
                      child: SizedBox(
                        height: 320,
                        child: PageView.builder(
                          controller: _heroPageController,
                          onPageChanged: (page) {
                            _heroPageNotifier.value = page;
                            // 8s delay after manual swipe for full read time
                            _startAutoScroll(delay: const Duration(seconds: 8));
                          },
                          itemCount: _heroEvents.length,
                          itemBuilder: (context, index) {
                            // Scale animation: active card = 1.0, adjacent = 0.94
                            return AnimatedBuilder(
                              animation: _heroPageController,
                              builder: (context, child) {
                                double scale = index == _heroPageNotifier.value ? 1.0 : 0.94;
                                if (_heroPageController.position.haveDimensions) {
                                  scale = (1.0 -
                                          (_heroPageController.page! - index).abs() * 0.06)
                                      .clamp(0.94, 1.0);
                                }
                                return Transform.scale(scale: scale, child: child);
                              },
                              child: _buildHeroEventImage(_heroEvents[index]),
                            );
                          },
                        ),
                      ),
                    ),
                    const SizedBox(height: 16),
                    // Pagination dots
                    _buildCarouselDots(),
                  ],
                ),
          const SizedBox(height: 24),
        ],
      ),
    );
  }

  Widget _buildCarouselDots() {
    return ValueListenableBuilder<int>(
      valueListenable: _heroPageNotifier,
      builder: (context, currentPage, _) {
        return SizedBox(
          height: 44,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: List.generate(
              _heroEvents.isEmpty ? 5 : _heroEvents.length,
              (i) {
                final isActive = i == currentPage;
                return GestureDetector(
                  onTap: () {
                    if (_heroPageController.hasClients) {
                      _heroPageController.animateToPage(i,
                          duration: const Duration(milliseconds: 300), curve: Curves.easeInOut);
                    }
                  },
                  child: SizedBox(
                    width: 44,
                    height: 44,
                    child: Center(
                      child: AnimatedContainer(
                        duration: const Duration(milliseconds: 200),
                        width: isActive ? 24 : 8,
                        height: 8,
                        decoration: BoxDecoration(
                          color: isActive
                              ? Colors.white
                              : Colors.white.withValues(alpha: 0.4),
                          borderRadius: BorderRadius.circular(4),
                        ),
                      ),
                    ),
                  ),
                );
              },
            ),
          ),
        );
      },
    );
  }

  /// Build a hero image card with the image only (rounded),
  /// and the title text placed below the image.
  Widget _buildHeroEventImage(EventModel event) {
    String? img;
    if (event.thumbImg != null && event.thumbImg!.isNotEmpty) {
      img = event.thumbImg;
    } else if (event.images.isNotEmpty && event.images.first.image.isNotEmpty) {
      img = event.images.first.image;
    }

    const double radius = 24.0;

    return GestureDetector(
      onTap: () {
        if (event.id != null) {
          Navigator.push(context,
              MaterialPageRoute(builder: (_) => LearnMoreScreen(eventId: event.id, initialEvent: event)));
        }
      },
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 8),
        child: ClipRRect(
          borderRadius: BorderRadius.circular(radius),
          child: Stack(
            fit: StackFit.expand,
            children: [
              // ── Layer 0: Event image (full-bleed) ──
              img != null && img.isNotEmpty
                  ? CachedNetworkImage(
                      imageUrl: img,
                      memCacheWidth: 700,
                      memCacheHeight: 400,
                      fit: BoxFit.cover,
                      placeholder: (_, __) => const _HeroShimmer(radius: radius),
                      errorWidget: (_, __, ___) =>
                          Container(decoration: AppDecoration.blueGradientRounded(radius)),
                    )
                  : Container(decoration: AppDecoration.blueGradientRounded(radius)),

              // ── Layer 1: Bottom gradient overlay (text readability) ──
              Positioned.fill(
                child: DecoratedBox(
                  decoration: BoxDecoration(
                    gradient: LinearGradient(
                      begin: Alignment.topCenter,
                      end: Alignment.bottomCenter,
                      stops: const [0.35, 1.0],
                      colors: [
                        Colors.transparent,
                        Colors.black.withOpacity(0.78),
                      ],
                    ),
                  ),
                ),
              ),

              // ── Layer 2: Event type glassmorphism badge (top-left) ──
              Positioned(
                top: 14,
                left: 14,
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(20),
                  child: BackdropFilter(
                    filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
                    child: Container(
                      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
                      decoration: BoxDecoration(
                        color: Colors.white.withValues(alpha: 0.18),
                        borderRadius: BorderRadius.circular(20),
                        border: Border.all(color: Colors.white.withValues(alpha: 0.28)),
                      ),
                      child: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          const Icon(Icons.star_rounded, color: Colors.amber, size: 13),
                          const SizedBox(width: 4),
                          Text(
                            _getEventTypeName(event),
                            style: const TextStyle(
                              color: Colors.white,
                              fontSize: 10,
                              fontWeight: FontWeight.w800,
                              letterSpacing: 0.6,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ),

              // ── Layer 3: Title + metadata (bottom overlay) ──
              Positioned(
                bottom: 18,
                left: 16,
                right: 16,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Text(
                      event.title ?? event.name ?? '',
                      maxLines: 2,
                      overflow: TextOverflow.ellipsis,
                      style: const TextStyle(
                        color: Colors.white,
                        fontSize: 20,
                        fontWeight: FontWeight.w800,
                        height: 1.25,
                        shadows: [
                          Shadow(color: Colors.black54, blurRadius: 6, offset: Offset(0, 2)),
                        ],
                      ),
                    ),
                    const SizedBox(height: 8),
                    Row(
                      children: [
                        if (event.startDate != null) ...[
                          const Icon(Icons.calendar_today_rounded,
                              color: Colors.white70, size: 12),
                          const SizedBox(width: 4),
                          Text(
                            _formatDate(event.startDate!),
                            style: const TextStyle(
                                color: Colors.white70,
                                fontSize: 12,
                                fontWeight: FontWeight.w500),
                          ),
                          const SizedBox(width: 10),
                        ],
                        if (event.place != null && event.place!.isNotEmpty) ...[
                          const Icon(Icons.location_on_rounded,
                              color: Colors.white70, size: 12),
                          const SizedBox(width: 4),
                          Flexible(
                            child: Text(
                              event.place!,
                              overflow: TextOverflow.ellipsis,
                              style: const TextStyle(
                                  color: Colors.white70,
                                  fontSize: 12,
                                  fontWeight: FontWeight.w500),
                            ),
                          ),
                        ],
                      ],
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildWhiteSection() {
    return Padding(
      padding: const EdgeInsets.fromLTRB(16, 24, 16, 0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Search bar
          GestureDetector(
            onTap: _openEventSearch,
            child: Container(
              width: double.infinity,
              padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
              decoration: BoxDecoration(
                color: const Color(0xFFF3F4F6),
                borderRadius: BorderRadius.circular(28),
              ),
              child: const Text(
                'Search events, artists or attractions',
                style: TextStyle(color: Color(0xFF9CA3AF), fontSize: 14),
              ),
            ),
          ),
          const SizedBox(height: 16),

          // Date filter chips
          SizedBox(
            height: 40,
            child: ListView(
              scrollDirection: Axis.horizontal,
              children: [
                _dateChip(label: 'Date', icon: Icons.calendar_today, hasDropdown: true),
                const SizedBox(width: 8),
                _dateChip(label: 'Today'),
                const SizedBox(width: 8),
                _dateChip(label: 'Tomorrow'),
                const SizedBox(width: 8),
                _dateChip(label: 'This week'),
              ],
            ),
          ),
          const SizedBox(height: 24),

          // Top Events
          const Text(
            'Top Events',
            style: TextStyle(
              color: Color(0xFF111827),
              fontSize: 20,
              fontWeight: FontWeight.bold,
            ),
          ),
          const SizedBox(height: 16),
          SizedBox(
            height: 200,
            child: _allFilteredByDate.isEmpty && _loading
                ? const Center(child: CircularProgressIndicator())
                : _allFilteredByDate.isEmpty
                    ? Center(child: Text(
                        _selectedDateFilter.isNotEmpty ? 'No events for "$_selectedDateFilter"' : 'No events found',
                        style: const TextStyle(color: Color(0xFF9CA3AF)),
                      ))
                    : ListView.separated(
                        scrollDirection: Axis.horizontal,
                        itemCount: _allFilteredByDate.length,
                        separatorBuilder: (_, __) => const SizedBox(width: 12),
                        itemBuilder: (context, index) => _buildTopEventCard(_allFilteredByDate[index]),
                      ),
          ),
          const SizedBox(height: 24),

          // Events Around You
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              const Text(
                'Events Around You',
                style: TextStyle(
                  color: Color(0xFF111827),
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                ),
              ),
              TextButton(
                onPressed: () => setState(() => _categoriesExpanded = !_categoriesExpanded),
                child: Text(
                  _categoriesExpanded ? 'Show Less' : 'View All',
                  style: const TextStyle(color: Color(0xFF2563EB), fontWeight: FontWeight.w600),
                ),
              ),
            ],
          ),
          const SizedBox(height: 12),

          // Category chips — horizontal scroll (collapsed) or wrap grid (expanded)
          AnimatedCrossFade(
            duration: const Duration(milliseconds: 300),
            crossFadeState: _categoriesExpanded ? CrossFadeState.showSecond : CrossFadeState.showFirst,
            // Collapsed: horizontal scroll
            firstChild: SizedBox(
              height: 140,
              child: ListView(
                scrollDirection: Axis.horizontal,
                children: [
                  _categoryChip(
                    label: 'All Events',
                    icon: Icons.grid_view_rounded,
                    selected: _selectedTypeId == -1,
                    onTap: () => _onSelectType(-1),
                  ),
                  const SizedBox(width: 12),
                  for (final t in _types) ...[
                    _categoryChip(
                      label: t.name,
                      imageUrl: t.iconUrl,
                      icon: _getIconForType(t.name),
                      selected: _selectedTypeId == t.id,
                      onTap: () => _onSelectType(t.id),
                    ),
                    const SizedBox(width: 12),
                  ],
                ],
              ),
            ),
            // Expanded: wrap grid showing all categories
            secondChild: Wrap(
              spacing: 10,
              runSpacing: 10,
              children: [
                _categoryChip(
                  label: 'All Events',
                  icon: Icons.grid_view_rounded,
                  selected: _selectedTypeId == -1,
                  onTap: () => _onSelectType(-1),
                ),
                for (final t in _types)
                  _categoryChip(
                    label: t.name,
                    imageUrl: t.iconUrl,
                    icon: _getIconForType(t.name),
                    selected: _selectedTypeId == t.id,
                    onTap: () => _onSelectType(t.id),
                  ),
              ],
            ),
          ),
          const SizedBox(height: 16),

          // Event sections — shelves (All) or filtered list (specific category)
          if (_loading)
            const Padding(
              padding: EdgeInsets.all(40),
              child: Center(child: CircularProgressIndicator()),
            )
          else if (_allFilteredByDate.isEmpty && _selectedDateFilter.isNotEmpty)
            Padding(
              padding: const EdgeInsets.all(40),
              child: Center(child: Text(
                'No events for "$_selectedDateFilter"',
                style: const TextStyle(color: Color(0xFF9CA3AF)),
              )),
            )
          else
            AnimatedSwitcher(
              duration: const Duration(milliseconds: 300),
              switchInCurve: Curves.easeOut,
              switchOutCurve: Curves.easeIn,
              child: _selectedTypeId == -1
                  // "All Events" — show category shelf sections
                  ? Column(
                      key: const ValueKey('shelves'),
                      children: [
                        for (final t in _types)
                          if (_allFilteredByDate.where((e) => e.eventTypeId == t.id).isNotEmpty) ...[
                            _buildTypeSection(t),
                            const SizedBox(height: 18),
                          ],
                      ],
                    )
                  // Specific category — show vertical list of events for that category only
                  : Column(
                      key: ValueKey('filtered_$_selectedTypeId'),
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        // Category name header
                        Padding(
                          padding: const EdgeInsets.only(bottom: 14),
                          child: Row(
                            children: [
                              Expanded(
                                child: Text(
                                  _types.firstWhere((t) => t.id == _selectedTypeId, orElse: () => _types.first).name,
                                  style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF111827)),
                                ),
                              ),
                              Text(
                                '${_allFilteredByDate.where((e) => e.eventTypeId == _selectedTypeId).length} events',
                                style: const TextStyle(fontSize: 13, color: Color(0xFF9CA3AF)),
                              ),
                            ],
                          ),
                        ),
                        // Event cards
                        for (final e in _allFilteredByDate.where((e) => e.eventTypeId == _selectedTypeId))
                          _buildFullWidthCard(e),
                        if (_allFilteredByDate.where((e) => e.eventTypeId == _selectedTypeId).isEmpty)
                          const Padding(
                            padding: EdgeInsets.all(40),
                            child: Center(child: Text('No events in this category', style: TextStyle(color: Color(0xFF9CA3AF)))),
                          ),
                      ],
                    ),
            ),

          // Bottom padding for nav bar
          const SizedBox(height: 100),
        ],
      ),
    );
  }

  Widget _dateChip({required String label, IconData? icon, bool hasDropdown = false}) {
    final isSelected = _selectedDateFilter == label;
    // For 'Date' chip, show the picked date instead of just "Date"
    String displayLabel = label;
    if (label == 'Date' && isSelected && _selectedCustomDate != null) {
      final d = _selectedCustomDate!;
      const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
      displayLabel = '${d.day} ${months[d.month - 1]}';
    }
    return GestureDetector(
      onTap: () => _onDateChipTap(label),
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
        decoration: BoxDecoration(
          color: isSelected ? const Color(0xFF2563EB) : const Color(0xFFF3F4F6),
          borderRadius: BorderRadius.circular(20),
          border: Border.all(color: isSelected ? const Color(0xFF2563EB) : const Color(0xFFE5E7EB)),
        ),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            if (icon != null) ...[
              Icon(icon, size: 16, color: isSelected ? Colors.white : const Color(0xFF374151)),
              const SizedBox(width: 6),
            ],
            Text(
              displayLabel,
              style: TextStyle(
                color: isSelected ? Colors.white : const Color(0xFF374151),
                fontSize: 13,
                fontWeight: FontWeight.w500,
              ),
            ),
            if (hasDropdown) ...[
              const SizedBox(width: 4),
              Icon(Icons.keyboard_arrow_down, size: 16, color: isSelected ? Colors.white : const Color(0xFF374151)),
            ],
          ],
        ),
      ),
    );
  }

  Widget _buildTopEventCard(EventModel event) {
    String? img;
    if (event.thumbImg != null && event.thumbImg!.isNotEmpty) {
      img = event.thumbImg;
    } else if (event.images.isNotEmpty && event.images.first.image.isNotEmpty) {
      img = event.images.first.image;
    }

    return GestureDetector(
      onTap: () {
        if (event.id != null) {
          Navigator.push(context, MaterialPageRoute(builder: (_) => LearnMoreScreen(eventId: event.id, initialEvent: event)));
        }
      },
      child: Container(
        width: 150,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(16),
        ),
        clipBehavior: Clip.antiAlias,
        child: Stack(
          fit: StackFit.expand,
          children: [
            // Background image
            img != null && img.isNotEmpty
                ? CachedNetworkImage(
                    imageUrl: img,
                    memCacheWidth: 300,
                    memCacheHeight: 200,
                    fit: BoxFit.cover,
                    width: double.infinity,
                    height: double.infinity,
                    placeholder: (_, __) => Container(
                      color: const Color(0xFF374151),
                      child: const Center(child: SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white38))),
                    ),
                    errorWidget: (_, __, ___) => Container(
                      color: const Color(0xFF374151),
                      child: const Icon(Icons.image, color: Colors.white38, size: 40),
                    ),
                  )
                : Container(
                    color: const Color(0xFF374151),
                    child: const Icon(Icons.image, color: Colors.white38, size: 40),
                  ),
            // Dark gradient overlay at bottom
            Positioned(
              left: 0,
              right: 0,
              bottom: 0,
              height: 80,
              child: Container(
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment.topCenter,
                    end: Alignment.bottomCenter,
                    colors: [Colors.transparent, Colors.black.withOpacity(0.7)],
                  ),
                ),
              ),
            ),
            // Title text at bottom left
            Positioned(
              left: 12,
              right: 12,
              bottom: 12,
              child: Text(
                event.title ?? event.name ?? '',
                maxLines: 2,
                overflow: TextOverflow.ellipsis,
                style: const TextStyle(
                  color: Colors.white,
                  fontSize: 14,
                  fontWeight: FontWeight.bold,
                  height: 1.2,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// Build a type section that follows your requested layout rules:
  /// - If type has <= 5 events => single horizontal row of compact cards.
  /// - If type has >= 6 events => arrange events into column groups of 3 (so visually there are 3 rows across horizontally scrollable columns).
  Widget _buildTypeSection(EventTypeModel type) {
    final theme = Theme.of(context);
    final eventsForType = _allFilteredByDate.where((e) => e.eventTypeId == type.id).toList();
    final n = eventsForType.length;

    // Header row
    Widget header = Padding(
      padding: const EdgeInsets.symmetric(horizontal: 4),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(type.name, style: theme.textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold)),
          TextButton(
            onPressed: () {
              _onSelectType(type.id);
            },
            child: Text('View All', style: TextStyle(color: theme.colorScheme.primary, fontWeight: FontWeight.w600)),
          ),
        ],
      ),
    );

    // If <= 5 events: show one horizontal row using _buildHorizontalEventCard
    if (n <= 5) {
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          header,
          const SizedBox(height: 8),
          SizedBox(
            height: 290, // card height: image 180 + text ~110
            child: ListView.separated(
              scrollDirection: Axis.horizontal,
              padding: const EdgeInsets.symmetric(horizontal: 8),
              itemBuilder: (ctx, idx) => _buildHorizontalEventCard(eventsForType[idx]),
              separatorBuilder: (_, __) => const SizedBox(width: 12),
              itemCount: eventsForType.length,
            ),
          ),
        ],
      );
    }

    // For 6+ events: arrange into columns where each column has up to 3 stacked cards.
    final columnsCount = (n / 3).ceil();
    final columnWidth = 260.0; // narrower so second column peeks in
    final verticalCardHeight = 120.0; // each stacked card height matches sample

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        header,
        const SizedBox(height: 8),

        // Container height must accommodate 3 stacked cards + small gaps
        SizedBox(
          height: (verticalCardHeight * 3) + 16, // 3 cards + spacing
          child: ListView.separated(
            scrollDirection: Axis.horizontal,
            padding: const EdgeInsets.symmetric(horizontal: 8),
            separatorBuilder: (_, __) => const SizedBox(width: 12),
            itemBuilder: (ctx, colIndex) {
              // Build one column: contains up to 3 items: indices colIndex*3 + 0/1/2
              return Container(
                width: columnWidth,
                child: Column(
                  children: [
                    // top card
                    if ((colIndex * 3 + 0) < n)
                      SizedBox(
                        height: verticalCardHeight,
                        child: _buildStackedCard(eventsForType[colIndex * 3 + 0]),
                      )
                    else
                      const SizedBox(height: 0),
                    const SizedBox(height: 8),
                    // middle card
                    if ((colIndex * 3 + 1) < n)
                      SizedBox(
                        height: verticalCardHeight,
                        child: _buildStackedCard(eventsForType[colIndex * 3 + 1]),
                      )
                    else
                      const SizedBox(height: 0),
                    const SizedBox(height: 8),
                    // bottom card
                    if ((colIndex * 3 + 2) < n)
                      SizedBox(
                        height: verticalCardHeight,
                        child: _buildStackedCard(eventsForType[colIndex * 3 + 2]),
                      )
                    else
                      const SizedBox(height: 0),
                  ],
                ),
              );
            },
            itemCount: columnsCount,
          ),
        ),
      ],
    );
  }

  /// A stacked card styled to match your sample (left square thumbnail, bold title).
  /// REMOVED: price/rating row (per your request).
  Widget _buildStackedCard(EventModel e) {
    final theme = Theme.of(context);
    String? img;
    if (e.thumbImg != null && e.thumbImg!.isNotEmpty) {
      img = e.thumbImg;
    } else if (e.images.isNotEmpty && e.images.first.image.isNotEmpty) {
      img = e.images.first.image;
    }

    return GestureDetector(
      onTap: () {
        if (e.id != null) Navigator.push(context, MaterialPageRoute(builder: (_) => LearnMoreScreen(eventId: e.id, initialEvent: e)));
      },
      child: Container(
        margin: const EdgeInsets.symmetric(vertical: 0),
        decoration: BoxDecoration(
          color: theme.cardColor,
          borderRadius: BorderRadius.circular(16),
          boxShadow: [BoxShadow(color: theme.shadowColor.withOpacity(0.06), blurRadius: 12, offset: const Offset(0, 8))],
        ),
        padding: const EdgeInsets.all(12),
        child: Row(
          children: [
            // thumbnail square (rounded)
            ClipRRect(
              borderRadius: BorderRadius.circular(12),
              child: img != null && img.isNotEmpty
                  ? CachedNetworkImage(
                      imageUrl: img,
                      memCacheWidth: 192,
                      memCacheHeight: 192,
                      width: 96,
                      height: double.infinity,
                      fit: BoxFit.cover,
                      placeholder: (_, __) => Container(width: 96, color: theme.dividerColor, child: const Center(child: SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2)))),
                      errorWidget: (_, __, ___) => Container(width: 96, color: theme.dividerColor),
                    )
                  : Container(width: 96, height: double.infinity, color: theme.dividerColor),
            ),
            const SizedBox(width: 14),
            Expanded(
              child: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [
                Text(e.title ?? e.name ?? '', maxLines: 2, overflow: TextOverflow.ellipsis, style: theme.textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold, fontSize: 18)),
                // removed price/rating row here per request
              ]),
            ),
            // optional heart icon aligned top-right
            Icon(Icons.favorite_border, color: theme.hintColor),
          ],
        ),
      ),
    );
  }

  /// Compact card used inside the one-row layout for small counts (<=5).
  /// Matches Figma: vertical card with image, date badge, title, location, "Free".
  Widget _buildHorizontalEventCard(EventModel e) {
    final theme = Theme.of(context);
    String? img;
    if (e.thumbImg != null && e.thumbImg!.isNotEmpty) {
      img = e.thumbImg;
    } else if (e.images.isNotEmpty && e.images.first.image.isNotEmpty) {
      img = e.images.first.image;
    }

    // Parse day & month for the date badge
    String day = '';
    String month = '';
    try {
      final parts = e.startDate.split('-');
      if (parts.length == 3) {
        day = int.parse(parts[2]).toString();
        const months = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC'];
        month = months[int.parse(parts[1]) - 1];
      }
    } catch (_) {}

    final venue = e.venueName ?? e.place ?? '';

    return GestureDetector(
      onTap: () {
        if (e.id != null) Navigator.push(context, MaterialPageRoute(builder: (_) => LearnMoreScreen(eventId: e.id, initialEvent: e)));
      },
      child: SizedBox(
        width: 220,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Image with date badge
            Stack(
              children: [
                ClipRRect(
                  borderRadius: BorderRadius.circular(18),
                  child: img != null && img.isNotEmpty
                      ? CachedNetworkImage(
                          imageUrl: img,
                          memCacheWidth: 440,
                          memCacheHeight: 360,
                          width: 220,
                          height: 180,
                          fit: BoxFit.cover,
                          placeholder: (_, __) => Container(
                            width: 220,
                            height: 180,
                            decoration: BoxDecoration(
                              color: theme.dividerColor,
                              borderRadius: BorderRadius.circular(18),
                            ),
                            child: const Center(child: SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2))),
                          ),
                          errorWidget: (_, __, ___) => Container(
                            width: 220,
                            height: 180,
                            decoration: BoxDecoration(
                              color: theme.dividerColor,
                              borderRadius: BorderRadius.circular(18),
                            ),
                            child: Icon(Icons.image, size: 40, color: theme.hintColor),
                          ),
                        )
                      : Container(
                          width: 220,
                          height: 180,
                          decoration: BoxDecoration(
                            color: theme.dividerColor,
                            borderRadius: BorderRadius.circular(18),
                          ),
                          child: Icon(Icons.image, size: 40, color: theme.hintColor),
                        ),
                ),
                // Date badge
                if (day.isNotEmpty)
                  Positioned(
                    top: 10,
                    right: 10,
                    child: Container(
                      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(12),
                        boxShadow: [
                          BoxShadow(
                            color: Colors.black.withOpacity(0.08),
                            blurRadius: 6,
                            offset: const Offset(0, 2),
                          ),
                        ],
                      ),
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Text(
                            day,
                            style: const TextStyle(
                              fontSize: 16,
                              fontWeight: FontWeight.w800,
                              color: Colors.black87,
                              height: 1.1,
                            ),
                          ),
                          Text(
                            month,
                            style: const TextStyle(
                              fontSize: 11,
                              fontWeight: FontWeight.w700,
                              color: Colors.black54,
                              height: 1.2,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
              ],
            ),
            const SizedBox(height: 10),
            // Title
            Text(
              e.title ?? e.name ?? '',
              maxLines: 2,
              overflow: TextOverflow.ellipsis,
              style: theme.textTheme.titleMedium?.copyWith(
                fontWeight: FontWeight.bold,
                fontSize: 16,
              ),
            ),
            if (venue.isNotEmpty) ...[
              const SizedBox(height: 4),
              Text(
                venue,
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
                style: theme.textTheme.bodySmall?.copyWith(
                  color: theme.hintColor,
                  fontSize: 13,
                ),
              ),
            ],
            const SizedBox(height: 4),
            Text(
              'Free',
              style: TextStyle(
                color: theme.colorScheme.primary,
                fontWeight: FontWeight.w700,
                fontSize: 14,
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// Format a date string (YYYY-MM-DD) to short display like "4 Mar".
  String _formatDateShort(String dateStr) {
    try {
      final parts = dateStr.split('-');
      if (parts.length == 3) {
        final day = int.parse(parts[2]);
        const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
        final month = months[int.parse(parts[1]) - 1];
        return '$day $month';
      }
    } catch (_) {}
    return dateStr;
  }

  /// Full width card used when a single type is selected (vertical list).
  /// Matches Figma: large image, badge, title, date + venue.
  Widget _buildFullWidthCard(EventModel e) {
    final theme = Theme.of(context);
    String? img;
    if (e.thumbImg != null && e.thumbImg!.isNotEmpty) {
      img = e.thumbImg;
    } else if (e.images.isNotEmpty && e.images.first.image.isNotEmpty) {
      img = e.images.first.image;
    }

    // Build date range string
    final startShort = _formatDateShort(e.startDate);
    final endShort = _formatDateShort(e.endDate);
    final dateRange = startShort == endShort ? startShort : '$startShort - $endShort';

    final venue = e.venueName ?? e.place ?? '';

    return GestureDetector(
      onTap: () {
        if (e.id != null) Navigator.push(context, MaterialPageRoute(builder: (_) => LearnMoreScreen(eventId: e.id, initialEvent: e)));
      },
      child: Container(
        margin: const EdgeInsets.only(bottom: 18),
        decoration: BoxDecoration(
          color: theme.cardColor,
          borderRadius: BorderRadius.circular(20),
          boxShadow: [
            BoxShadow(color: theme.shadowColor.withOpacity(0.10), blurRadius: 16, offset: const Offset(0, 6)),
          ],
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Image with badge
            Stack(
              children: [
                ClipRRect(
                  borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
                  child: img != null && img.isNotEmpty
                      ? CachedNetworkImage(
                          imageUrl: img,
                          memCacheWidth: 800,
                          memCacheHeight: 400,
                          width: double.infinity,
                          height: 200,
                          fit: BoxFit.cover,
                          placeholder: (_, __) => Container(
                            width: double.infinity,
                            height: 200,
                            decoration: BoxDecoration(
                              color: theme.dividerColor,
                              borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
                            ),
                            child: const Center(child: SizedBox(width: 28, height: 28, child: CircularProgressIndicator(strokeWidth: 2))),
                          ),
                          errorWidget: (_, __, ___) => Container(
                            width: double.infinity,
                            height: 200,
                            decoration: BoxDecoration(
                              color: theme.dividerColor,
                              borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
                            ),
                            child: Icon(Icons.image, size: 48, color: theme.hintColor),
                          ),
                        )
                      : Container(
                          width: double.infinity,
                          height: 200,
                          decoration: BoxDecoration(
                            color: theme.dividerColor,
                            borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
                          ),
                          child: Icon(Icons.image, size: 48, color: theme.hintColor),
                        ),
                ),
                // "ADDED BY EVENTIFY" badge
                Positioned(
                  top: 14,
                  left: 14,
                  child: Container(
                    padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                    decoration: BoxDecoration(
                      color: theme.colorScheme.primary,
                      borderRadius: BorderRadius.circular(20),
                    ),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: const [
                        Icon(Icons.star, color: Colors.white, size: 14),
                        SizedBox(width: 4),
                        Text(
                          'ADDED BY EVENTIFY',
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 11,
                            fontWeight: FontWeight.w700,
                            letterSpacing: 0.5,
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
            // Title + date/venue
            Padding(
              padding: const EdgeInsets.fromLTRB(16, 14, 16, 16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    e.title ?? e.name ?? '',
                    style: theme.textTheme.titleMedium?.copyWith(
                      fontWeight: FontWeight.bold,
                      fontSize: 17,
                    ),
                    maxLines: 2,
                    overflow: TextOverflow.ellipsis,
                  ),
                  const SizedBox(height: 8),
                  Row(
                    children: [
                      Icon(Icons.calendar_today_outlined, size: 14, color: theme.hintColor),
                      const SizedBox(width: 4),
                      Text(
                        dateRange,
                        style: theme.textTheme.bodySmall?.copyWith(
                          color: theme.hintColor,
                          fontSize: 13,
                        ),
                      ),
                      if (venue.isNotEmpty) ...[
                        const SizedBox(width: 12),
                        Icon(Icons.location_on_outlined, size: 14, color: theme.hintColor),
                        const SizedBox(width: 3),
                        Expanded(
                          child: Text(
                            venue,
                            style: theme.textTheme.bodySmall?.copyWith(
                              color: theme.hintColor,
                              fontSize: 13,
                            ),
                            maxLines: 1,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                      ],
                    ],
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  IconData _getIconForType(String typeName) {
    final name = typeName.toLowerCase();
    if (name.contains('music')) return Icons.music_note;
    if (name.contains('art') || name.contains('comedy')) return Icons.palette;
    if (name.contains('festival')) return Icons.celebration;
    if (name.contains('heritage') || name.contains('history')) return Icons.account_balance;
    if (name.contains('sport')) return Icons.sports;
    if (name.contains('food')) return Icons.restaurant;
    return Icons.event;
  }

  void _onSelectType(int id) {
    setState(() {
      _selectedTypeId = id;
      _events = id == -1 ? List.from(_allEvents) : _allEvents.where((e) => e.eventTypeId == id).toList();
      _cachedFilteredEvents = null;
    });
  }

  String _getShortEmailLabel() {
    try {
      final parts = _username.split('@');
      if (parts.isNotEmpty && parts[0].isNotEmpty) return parts[0];
    } catch (_) {}
    return 'You';
  }
}

/// Animated shimmer placeholder shown while a hero card image is loading.
/// Renders a blue-toned scan-line effect matching the app's colour palette.
class _HeroShimmer extends StatefulWidget {
  final double radius;
  const _HeroShimmer({this.radius = 24.0});

  @override
  State<_HeroShimmer> createState() => _HeroShimmerState();
}

class _HeroShimmerState extends State<_HeroShimmer>
    with SingleTickerProviderStateMixin {
  late final AnimationController _ctrl;

  @override
  void initState() {
    super.initState();
    _ctrl = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1400),
    )..repeat();
  }

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

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _ctrl,
      builder: (_, __) {
        final x = -1.5 + _ctrl.value * 3.0;
        return Container(
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(widget.radius),
            gradient: LinearGradient(
              begin: Alignment(x - 1.0, 0),
              end: Alignment(x, 0),
              colors: const [
                Color(0xFF1A2A4A),
                Color(0xFF2D4580),
                Color(0xFF1A2A4A),
              ],
            ),
          ),
        );
      },
    );
  }
}
