import 'dart:async';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

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

class HomeDesktopScreen extends StatefulWidget {
  final bool skipSidebarEntranceAnimation;
  const HomeDesktopScreen({Key? key, this.skipSidebarEntranceAnimation = false}) : super(key: key);

  @override
  State<HomeDesktopScreen> createState() => _HomeDesktopScreenState();
}

class _HomeDesktopScreenState extends State<HomeDesktopScreen> with SingleTickerProviderStateMixin {
  final EventsService _eventsService = EventsService();

  // Navigation state
  int selectedMenu = 0; // 0 = Home, 1 = Calendar, 2 = Profile, 3 = Bookings, 4 = Contribute, 5 = Settings

  // Backend-driven data for Home
  List<EventModel> _events = [];
  List<EventTypeModel> _types = [];
  bool _loading = true;
  bool _loadingTypes = true;

  // Selection: either a backend id (event type) or a fixed label filter.
  int _SelectedTypeId = -1;
  String? _selectedTypeLabel;

  // fixed categories required by product
  final List<String> _fixedCategories = [
    'All Events',
  ];

  // User prefs
  String _username = 'Guest';
  String _location = 'Unknown';
  String _pincode = 'all';
  String? _profileImage;

  // Sidebar text animation
  late final AnimationController _sidebarTextController;
  late final Animation<double> _sidebarTextOpacity;

  // Sidebar width constant (used when computing main content width)
  static const double _sidebarWidth = 220;

  // Topbar compact breakpoint (content width)
  static const double _compactTopBarWidth = 720;

  // --- marquee (featured events) fields ---
  late final ScrollController _marqueeController;
  Timer? _marqueeTimer;
  // Speed in pixels per second
  double _marqueeSpeed = 40.0;
  final Duration _marqueeTick = const Duration(milliseconds: 16);

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

    _sidebarTextController = AnimationController(vsync: this, duration: const Duration(milliseconds: 420));
    _sidebarTextOpacity = Tween<double>(begin: 0.0, end: 1.0).animate(CurvedAnimation(parent: _sidebarTextController, curve: Curves.easeOut));

    _marqueeController = ScrollController();

    if (widget.skipSidebarEntranceAnimation) {
      _sidebarTextController.value = 1.0;
    } else {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (mounted) _sidebarTextController.forward();
      });
    }

    // load initial data for home only
    _loadPreferencesAndData();
  }

  @override
  void dispose() {
    _sidebarTextController.dispose();
    _marqueeTimer?.cancel();
    _marqueeController.dispose();
    super.dispose();
  }

  // ------------------------ Data loaders ------------------------
  Future<void> _loadPreferencesAndData() async {
    setState(() {
      _loading = true;
      _loadingTypes = true;
    });

    final prefs = await SharedPreferences.getInstance();
    // UI display name should come from display_name (profile). Backend identity is separate.
    _username = prefs.getString('display_name') ?? prefs.getString('username') ?? 'Jane Doe';
    _location = prefs.getString('location') ?? 'Whitefield, Bengaluru';
    _pincode = prefs.getString('pincode') ?? 'all';
    _profileImage = prefs.getString('profileImage');

    await Future.wait([
      _fetchEventTypes(),
      _fetchEventsByPincode(_pincode),
    ]);

    if (mounted) setState(() {
      _loading = false;
      _loadingTypes = false;
    });

    // start marquee when we have events
    _restartMarquee();
  }

  Future<void> _fetchEventTypes() async {
    try {
      final types = await _eventsService.getEventTypes();
      if (mounted) setState(() => _types = types);
    } catch (e) {
      if (mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Failed to load categories: ${e.toString()}')));
    }
  }

  Future<void> _fetchEventsByPincode(String pincode) async {
    try {
      final events = await _eventsService.getEventsByPincode(pincode);
      if (mounted) setState(() => _events = events);
    } catch (e) {
      if (mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Failed to load events: ${e.toString()}')));
    }

    // ensure marquee restarts when event list changes
    _restartMarquee();
  }

  /// Public refresh entry used by UI (pull-to-refresh).
  Future<void> _refreshHome() async {
    // Prevent duplicate refresh triggers
    if (_loading) return;

    setState(() => _loading = true);
    try {
      await _loadPreferencesAndData();
    } finally {
      // _loadPreferencesAndData normally clears _loading, but ensure we reset if needed.
      if (mounted && _loading) setState(() => _loading = false);
    }
  }

  // ------------------------ Helpers ------------------------
  String? _chooseEventImage(EventModel e) {
    if (e.thumbImg != null && e.thumbImg!.trim().isNotEmpty) return e.thumbImg!.trim();
    if (e.images.isNotEmpty && e.images.first.image.trim().isNotEmpty) return e.images.first.image.trim();
    return null;
  }

  Widget _profileAvatar() {
    // If profile image exists and is a network URL -> show it
    if (_profileImage != null && _profileImage!.trim().isNotEmpty) {
      final url = _profileImage!.trim();

      if (url.startsWith('http')) {
        return CircleAvatar(
          radius: 20,
          backgroundColor: Colors.grey.shade200,
          backgroundImage: NetworkImage(url),
          onBackgroundImageError: (_, __) {},
          child: const Icon(Icons.person, color: Colors.transparent),
        );
      }
    }

    // Fallback → initials (clean & readable)
    final name = _username.trim();
    String initials = 'U';

    if (name.isNotEmpty) {
      if (name.contains('@')) {
        // Email → first letter only
        initials = name[0].toUpperCase();
      } else {
        final parts = name.split(' ').where((p) => p.isNotEmpty).toList();
        initials = parts.isEmpty ? 'U' : parts.take(2).map((p) => p[0].toUpperCase()).join();
      }
    }

    return CircleAvatar(
      radius: 20,
      backgroundColor: Colors.blue.shade600,
      child: Text(
        initials,
        style: const TextStyle(
          color: Colors.white,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }

  // ------------------------ Marquee control ------------------------
  void _restartMarquee() {
    // stop previous timer
    _marqueeTimer?.cancel();
    if (_events.isEmpty) {
      // reset position
      if (_marqueeController.hasClients) _marqueeController.jumpTo(0);
      return;
    }

    // Wait for next frame so scroll metrics are available (after the duplicated row is built)
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!mounted) return;
      if (!_marqueeController.hasClients) {
        // Try again next frame
        WidgetsBinding.instance.addPostFrameCallback((_) => _restartMarquee());
        return;
      }

      final maxScroll = _marqueeController.position.maxScrollExtent;
      if (maxScroll <= 0) {
        // Nothing to scroll
        return;
      }

      // Start a periodic timer that increments offset smoothly
      final tickSeconds = _marqueeTick.inMilliseconds / 1000.0;
      final delta = _marqueeSpeed * tickSeconds;

      _marqueeTimer?.cancel();
      _marqueeTimer = Timer.periodic(_marqueeTick, (_) {
        if (!mounted || !_marqueeController.hasClients) return;

        final cur = _marqueeController.offset;
        final max = _marqueeController.position.maxScrollExtent;
        final half = max / 2.0; // because we duplicate the list twice

        double next = cur + delta;
        if (next >= max) {
          // wrap back by half (seamless loop — instant jump is intentional)
          final wrapped = next - half;
          _marqueeController.jumpTo(wrapped.clamp(0.0, max));
        } else {
          // smooth incremental scroll synced to ticker duration
          _marqueeController.animateTo(
            next,
            duration: _marqueeTick,
            curve: Curves.linear,
          );
        }
      });
    });
  }

  // ------------------------ Filtering logic ------------------------
  List<EventModel> get _filteredEvents {
    if (_selectedTypeLabel != null && _selectedTypeLabel!.toLowerCase() != 'all events') {
      final label = _selectedTypeLabel!.toLowerCase();
      return _events.where((e) {
        final nameFromBackend = (e.eventTypeId != null && e.eventTypeId! > 0)
            ? (_types.firstWhere((t) => t.id == e.eventTypeId, orElse: () => EventTypeModel(id: -1, name: '', iconUrl: null)).name)
            : '';
        final candidateNames = <String?>[
          e.venueName,
          e.title,
          e.name,
          nameFromBackend,
        ];
        return candidateNames.any((c) => c != null && c.toLowerCase().contains(label));
      }).toList();
    }

    if (_SelectedTypeId != -1) {
      return _events.where((e) => e.eventTypeId == _SelectedTypeId).toList();
    }

    return _events;
  }

  void _selectBackendType(int id) {
    setState(() {
      _SelectedTypeId = id;
      _selectedTypeLabel = null;
    });
  }

  void _selectFixedLabel(String label) {
    setState(() {
      if (label.toLowerCase() == 'all events') {
        _SelectedTypeId = -1;
        _selectedTypeLabel = null;
      } else {
        _SelectedTypeId = -1;
        _selectedTypeLabel = label;
      }
    });
  }

  // ------------------------ Left panel (nav) ------------------------
  Widget _buildLeftPanel() {
    final theme = Theme.of(context);
    // Layout: top area (logo + nav list) scrolls if necessary, bottom area (host panel + settings) remains pinned.
    return Container(
      width: _sidebarWidth,
      decoration: const BoxDecoration(
        image: DecorationImage(
          image: AssetImage('assets/images/gradient_dark_blue.png'),
          fit: BoxFit.cover,
        ),
      ),
      child: SafeArea(
        child: Column(
          children: [
            const SizedBox(height: 18),
            FadeTransition(
              opacity: _sidebarTextOpacity,
              child: Padding(
                padding: const EdgeInsets.symmetric(vertical: 8.0),
                child: Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 18.0),
                  child: Text('EVENTIFY', style: theme.textTheme.titleMedium?.copyWith(color: theme.colorScheme.onPrimary, fontWeight: FontWeight.bold, fontSize: 18)),
                ),
              ),
            ),
            const SizedBox(height: 16),

            // Expandable nav list
            Expanded(
              child: SingleChildScrollView(
                physics: const ClampingScrollPhysics(),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    _navItem(icon: Icons.home, label: 'Home', idx: 0),
                    _navItem(icon: Icons.location_on, label: 'Events near you', idx: 0),
                    _navItem(icon: Icons.calendar_today, label: 'Upcoming events', idx: 0),
                    _navItem(icon: Icons.calendar_view_month, label: 'Calendar', idx: 1),

                    // <-- Profile between Calendar and Contribute
                    _navItem(icon: Icons.person, label: 'Profile', idx: 2),

                    _navItem(icon: Icons.add, label: 'Contribute', idx: 4),
                    const SizedBox(height: 12),
                    // optionally more items...
                  ],
                ),
              ),
            ),

            // bottom pinned area
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 12.0),
              child: Column(
                children: [
                  _buildHostPanel(),
                  const SizedBox(height: 12),
                  _navItem(icon: Icons.settings, label: 'Settings', idx: 5),
                  const SizedBox(height: 12),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildHostPanel() {
    final theme = Theme.of(context);
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        image: const DecorationImage(
          image: AssetImage('assets/images/gradient_dark_blue.png'),
          fit: BoxFit.cover,
        ),
        borderRadius: BorderRadius.circular(12),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('Hosting a private or ticketed event?', style: theme.textTheme.bodyMedium?.copyWith(color: theme.colorScheme.onPrimary, fontWeight: FontWeight.bold)),
          const SizedBox(height: 6),
          Text('Schedule a call back for setting up event.', style: theme.textTheme.bodySmall?.copyWith(color: theme.colorScheme.onPrimary.withOpacity(0.85), fontSize: 12)),
          const SizedBox(height: 10),
          ElevatedButton(onPressed: () {}, style: ElevatedButton.styleFrom(backgroundColor: theme.colorScheme.primary), child: Text('Schedule Call', style: theme.textTheme.labelLarge?.copyWith(color: theme.colorScheme.onPrimary))),
        ],
      ),
    );
  }

  Widget _navItem({required IconData icon, required String label, required int idx}) {
    final theme = Theme.of(context);
    final selected = selectedMenu == idx;
    final color = selected ? theme.colorScheme.onPrimary : theme.colorScheme.onPrimary.withOpacity(0.9);
    return ListTile(
      leading: Icon(icon, color: color),
      title: Text(label, style: TextStyle(color: color)),
      dense: true,
      onTap: () {
        setState(() {
          selectedMenu = idx;
        });
        if (idx == 0) _refreshHome();
      },
    );
  }

  // ------------------------ Top bar (common, responsive) ------------------------
  Widget _buildTopBar() {
    // The top bar sits inside the white content area (to the right of the sidebar).
    // The search box is centered inside the content area (slightly toward the right because of fixed width).
    final theme = Theme.of(context);
    return LayoutBuilder(builder: (context, constraints) {
      final isCompact = constraints.maxWidth < _compactTopBarWidth;

      return Padding(
        padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 18),
        child: Row(
          children: [
            // Left: location or icon when compact
            if (!isCompact)
              _fullLocationWidget()
            else
              IconButton(
                tooltip: 'Location',
                onPressed: () {},
                icon: Icon(Icons.location_on, color: theme.iconTheme.color),
              ),

            const SizedBox(width: 12),

            // Center: place the search bar centered in content area using Center + fixed width box.
            if (!isCompact)
              Expanded(
                child: Align(
                  alignment: Alignment.center,
                  child: Padding(
                    // ⬇️ Increase LEFT padding to move search bar more to the right
                    padding: const EdgeInsets.only(left: 120),
                    child: SizedBox(
                      width: 520,
                      height: 44,
                      child: TextField(
                        decoration: InputDecoration(
                          filled: true,
                          fillColor: theme.cardColor,
                          prefixIcon: Icon(Icons.search, color: theme.hintColor),
                          hintText: 'Search events, pages, features...',
                          hintStyle: theme.textTheme.bodyMedium?.copyWith(color: theme.hintColor),
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(12),
                            borderSide: BorderSide.none,
                          ),
                        ),
                        style: theme.textTheme.bodyLarge,
                      ),
                    ),
                  ),
                ),
              )
            else
              IconButton(
                tooltip: 'Search',
                onPressed: () {},
                icon: Icon(Icons.search, color: theme.iconTheme.color),
              ),

            // Spacer ensures right side stays right-aligned
            const Spacer(),

            // Right: notifications + (optionally username) + avatar
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Stack(
                  children: [
                    IconButton(onPressed: () {}, icon: Icon(Icons.notifications_none, color: theme.iconTheme.color)),
                    Positioned(right: 6, top: 6, child: CircleAvatar(radius: 8, backgroundColor: Colors.red, child: Text('2', style: theme.textTheme.bodySmall?.copyWith(color: Colors.white, fontSize: 10)))),
                  ],
                ),
                const SizedBox(width: 8),
                if (!isCompact) ...[
                  Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                    Text(_username, style: theme.textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.bold)),
                    Text('Explorer', style: theme.textTheme.bodySmall?.copyWith(color: theme.hintColor, fontSize: 12)),
                  ]),
                  const SizedBox(width: 8),
                ],
                GestureDetector(onTap: () => _openProfile(), child: _profileAvatar()),
              ],
            ),
          ],
        ),
      );
    });
  }

  Widget _fullLocationWidget() {
    final theme = Theme.of(context);
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text('Location', style: theme.textTheme.bodySmall?.copyWith(color: theme.hintColor, fontSize: 12)),
        const SizedBox(height: 4),
        Row(children: [
          Icon(Icons.location_on, size: 18, color: theme.hintColor),
          const SizedBox(width: 6),
          Text(_location, style: theme.textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w600)),
          const SizedBox(width: 6),
          Icon(Icons.arrow_drop_down, size: 18, color: theme.hintColor),
        ]),
      ],
    );
  }

  void _openProfile() {
    setState(() => selectedMenu = 2);
  }

  // ------------------------ Home content (index 0) ------------------------
  Widget _homeContent() {
    final theme = Theme.of(context);

    // Entire home content is a vertical scrollable wrapped in RefreshIndicator for pull-to-refresh behaviour.
    return RefreshIndicator(
      onRefresh: _refreshHome,
      color: theme.colorScheme.primary,
      child: SingleChildScrollView(
        physics: const AlwaysScrollableScrollPhysics(),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const SizedBox(height: 8),

            // HERO / welcome panel
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 24.0),
              child: Container(
                padding: const EdgeInsets.all(20),
                decoration: AppDecoration.blueGradientRounded(16),
                child: Row(
                  children: [
                    // left welcome
                    Expanded(
                      flex: 6,
                      child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                        Text('Welcome Back,', style: theme.textTheme.bodyMedium?.copyWith(color: Colors.white.withOpacity(0.9), fontSize: 16)),
                        const SizedBox(height: 6),
                        Text(_username, style: const TextStyle(color: Colors.white, fontSize: 30, fontWeight: FontWeight.bold)),
                      ]),
                    ),

                    const SizedBox(width: 16),

                    // right: horizontal featured events (backend-driven)
                    Expanded(
                      flex: 4,
                      child: SizedBox(
                        height: 90,
                        child: _events.isEmpty
                            ? const SizedBox()
                            : _buildMarqueeFeaturedEvents(),
                      ),
                    ),
                  ],
                ),
              ),
            ),

            const SizedBox(height: 18),

            // Events header
            Padding(
              padding: const EdgeInsets.fromLTRB(24, 0, 24, 8),
              child: Row(children: [
                Expanded(child: Text('Events Around You', style: theme.textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold))),
                TextButton(onPressed: () {}, child: Text('View All', style: theme.textTheme.bodyMedium)),
              ]),
            ),

            // type chips: fixed categories first, then backend categories
            if (!_loadingTypes) SizedBox(height: 56, child: _buildTypeChips()),

            const SizedBox(height: 14),

            // events area: use LayoutBuilder to decide between grid and horizontal scroll
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 24),
              child: LayoutBuilder(
                builder: (context, constraints) {
                  // constraints.maxWidth is the available width inside the white content area (after padding)
                  return _buildEventsArea(constraints.maxWidth);
                },
              ),
            ),

            const SizedBox(height: 40),
          ],
        ),
      ),
    );
  }

  /// Build marquee (continuous leftward scroll) by duplicating the events list and using a ScrollController.
  Widget _buildMarqueeFeaturedEvents() {
    // Duplicate events for seamless loop
    final display = <EventModel>[];
    display.addAll(_events);
    display.addAll(_events);

    return ClipRRect(
      borderRadius: BorderRadius.circular(8),
      child: SingleChildScrollView(
        controller: _marqueeController,
        scrollDirection: Axis.horizontal,
        physics: const NeverScrollableScrollPhysics(),
        child: Row(
          children: List.generate(display.length, (i) {
            final e = display[i];
            final img = _chooseEventImage(e);
            return Padding(
              padding: const EdgeInsets.only(right: 12.0),
              child: SizedBox(width: 220, child: _miniEventCard(e, img)),
            );
          }),
        ),
      ),
    );
  }

  Widget _buildTypeChips() {
    final chips = <Widget>[];

    // fixed categories first
    for (final name in _fixedCategories) {
      final isSelected = _selectedTypeLabel != null ? _selectedTypeLabel == name : (name == 'All Events' && _SelectedTypeId == -1 && _selectedTypeLabel == null);
      chips.add(_chipWidget(
        label: name,
        onTap: () => _selectFixedLabel(name),
        selected: isSelected,
      ));
    }

    // then backend categories (if any)
    for (final t in _types) {
      final isSelected = (_selectedTypeLabel == null && _SelectedTypeId == t.id);
      chips.add(_chipWidget(label: t.name, onTap: () => _selectBackendType(t.id), selected: isSelected));
    }

    return ListView.separated(
      padding: const EdgeInsets.symmetric(horizontal: 24),
      scrollDirection: Axis.horizontal,
      itemBuilder: (_, idx) => chips[idx],
      separatorBuilder: (_, __) => const SizedBox(width: 8),
      itemCount: chips.length,
    );
  }

  Widget _chipWidget({
    required String label,
    required VoidCallback onTap,
    required bool selected,
  }) {
    final theme = Theme.of(context);
    return InkWell(
      borderRadius: BorderRadius.circular(10),
      onTap: onTap,
      child: Container(
        height: 40, // 👈 fixed height for all chips
        alignment: Alignment.center,
        padding: const EdgeInsets.symmetric(horizontal: 16),
        decoration: BoxDecoration(
          color: selected ? theme.colorScheme.primary.withOpacity(0.08) : theme.cardColor,
          borderRadius: BorderRadius.circular(10), // 👈 box shape (not pill)
          border: Border.all(
            color: selected ? theme.colorScheme.primary : theme.dividerColor,
            width: 1,
          ),
        ),
        child: Text(
          label,
          style: TextStyle(
            fontSize: 14,
            fontWeight: FontWeight.w600,
            color: selected ? theme.colorScheme.primary : theme.textTheme.bodyLarge?.color,
          ),
        ),
      ),
    );
  }

  // ------------------------
  // EVENTS AREA: fixed 3-columns grid on wide widths; fallback horizontal on narrow widths.
  // ------------------------
  Widget _buildEventsArea(double contentWidth) {
    // Preferred card width you'd like to keep (matches your reference)
    const double preferredCardWidth = 360.0;
    const double cardHeight = 220.0; // matches reference proportions
    const double spacing = 18.0;

    final list = _filteredEvents;
    final theme = Theme.of(context);

    if (_loading) {
      return Padding(padding: const EdgeInsets.only(top: 32), child: Center(child: CircularProgressIndicator(color: theme.colorScheme.primary)));
    }
    if (list.isEmpty) {
      return Padding(padding: const EdgeInsets.symmetric(vertical: 40), child: Center(child: Text('No events available', style: theme.textTheme.bodyMedium)));
    }

    // Determine if we have space to show exactly 3 columns.
    // Required width for 3 columns = 3 * preferredCardWidth + 2 * spacing
    final double requiredWidthForThree = preferredCardWidth * 3 + spacing * 2;

    if (contentWidth >= requiredWidthForThree) {
      // Enough space: force a 3-column grid (this ensures exactly 3 cards per row)
      return GridView.builder(
        shrinkWrap: true,
        physics: const NeverScrollableScrollPhysics(),
        itemCount: list.length,
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3, // always 3 when space allows
          mainAxisExtent: cardHeight,
          crossAxisSpacing: spacing,
          mainAxisSpacing: spacing,
        ),
        itemBuilder: (ctx, idx) {
          final e = list[idx];
          final img = _chooseEventImage(e);
          return _eventCardForGrid(e, img);
        },
      );
    } else {
      // Not enough space for 3 columns — use horizontal scroll preserving card width.
      // This keeps behaviour sensible on narrower desktop windows.
      final double preferredWidth = preferredCardWidth;
      return SizedBox(
        height: cardHeight,
        child: ListView.separated(
          scrollDirection: Axis.horizontal,
          itemCount: list.length,
          separatorBuilder: (_, __) => const SizedBox(width: spacing),
          itemBuilder: (ctx, idx) {
            final e = list[idx];
            final img = _chooseEventImage(e);
            return SizedBox(width: preferredWidth, child: _eventCardForFixedSize(e, img, preferredWidth));
          },
        ),
      );
    }
  }

  // small horizontal card used inside HERO right area
  Widget _miniEventCard(EventModel e, String? img) {
    final theme = Theme.of(context);
    return Container(
      width: 220,
      padding: const EdgeInsets.all(8),
      decoration: BoxDecoration(color: theme.cardColor, borderRadius: BorderRadius.circular(12)),
      child: Row(children: [
        ClipRRect(
          borderRadius: BorderRadius.circular(8),
          child: img != null
              ? CachedNetworkImage(
                  imageUrl: img,
                  memCacheWidth: 128,
                  memCacheHeight: 128,
                  width: 64,
                  height: 64,
                  fit: BoxFit.cover,
                  placeholder: (_, __) => Container(width: 64, height: 64, color: Theme.of(context).dividerColor),
                  errorWidget: (_, __, ___) => Container(width: 64, height: 64, color: Theme.of(context).dividerColor, child: const Icon(Icons.event, size: 24, color: Colors.grey)),
                )
              : Container(width: 64, height: 64, color: Theme.of(context).dividerColor),
        ),
        const SizedBox(width: 8),
        Expanded(
          child: Column(mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [
            Text(e.title ?? e.name ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.bold)),
            const SizedBox(height: 6),
            Text(e.startDate ?? '', style: Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).hintColor, fontSize: 12)),
          ]),
        ),
      ]),
    );
  }

  // ---------- Cards ----------
  // Card used in grid (we can rely on grid cell having fixed height)
  Widget _eventCardForGrid(EventModel e, String? img) {
    final theme = Theme.of(context);

    // Styling constants to match reference
    const double cardRadius = 16.0;
    const double imageHeight = 140.0;
    const double horizontalPadding = 12.0;
    const double verticalPadding = 10.0;

    // Friendly formatted date label
    final dateLabel = (e.startDate != null && e.endDate != null && e.startDate == e.endDate)
        ? e.startDate!
        : ((e.startDate != null && e.endDate != null) ? '${e.startDate} - ${e.endDate}' : (e.startDate ?? ''));

    return GestureDetector(
      onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => LearnMoreScreen(eventId: e.id))),
      child: Container(
        decoration: BoxDecoration(
          color: theme.cardColor,
          borderRadius: BorderRadius.circular(cardRadius),
          boxShadow: [
            BoxShadow(color: Colors.black.withOpacity(0.08), blurRadius: 18, offset: const Offset(0, 10)),
            BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 6, offset: const Offset(0, 3)),
          ],
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // image flush to top corners
            ClipRRect(
              borderRadius: const BorderRadius.vertical(top: Radius.circular(cardRadius)),
              child: img != null
                  ? CachedNetworkImage(
                      imageUrl: img,
                      memCacheWidth: 600,
                      memCacheHeight: 280,
                      width: double.infinity,
                      height: imageHeight,
                      fit: BoxFit.cover,
                      placeholder: (_, __) => Container(height: imageHeight, color: theme.dividerColor),
                      errorWidget: (_, __, ___) => Container(height: imageHeight, color: theme.dividerColor),
                    )
                  : Container(height: imageHeight, width: double.infinity, color: theme.dividerColor),
            ),

            // content area
            Padding(
              padding: const EdgeInsets.fromLTRB(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  // Title (2 lines)
                  Text(
                    e.title ?? e.name ?? '',
                    maxLines: 2,
                    overflow: TextOverflow.ellipsis,
                    style: theme.textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w700, fontSize: 14),
                  ),

                  const SizedBox(height: 8),

                  // single row: date • location (icons small, subtle)
                  Row(
                    children: [
                      // calendar small badge
                      Container(
                        width: 18,
                        height: 18,
                        decoration: BoxDecoration(color: theme.colorScheme.primary.withOpacity(0.12), borderRadius: BorderRadius.circular(4)),
                        child: Icon(Icons.calendar_today, size: 12, color: theme.colorScheme.primary),
                      ),
                      const SizedBox(width: 8),
                      Expanded(
                        child: Text(
                          dateLabel,
                          maxLines: 1,
                          overflow: TextOverflow.ellipsis,
                          style: theme.textTheme.bodySmall?.copyWith(color: theme.hintColor, fontSize: 13),
                        ),
                      ),

                      const Padding(
                        padding: EdgeInsets.symmetric(horizontal: 8.0),
                        child: Text('•', style: TextStyle(color: Colors.black26)),
                      ),

                      Container(
                        width: 18,
                        height: 18,
                        decoration: BoxDecoration(color: theme.colorScheme.primary.withOpacity(0.12), borderRadius: BorderRadius.circular(4)),
                        child: Icon(Icons.location_on, size: 12, color: theme.colorScheme.primary),
                      ),
                      const SizedBox(width: 8),
                      Expanded(
                        child: Text(
                          e.place ?? '',
                          maxLines: 1,
                          overflow: TextOverflow.ellipsis,
                          style: theme.textTheme.bodySmall?.copyWith(color: theme.hintColor, fontSize: 13),
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  // Card used in horizontal list (fixed width)
  Widget _eventCardForFixedSize(EventModel e, String? img, double width) {
    final theme = Theme.of(context);

    // Styling constants to match grid card
    const double cardRadius = 16.0;
    const double imageHeight = 140.0;
    const double horizontalPadding = 12.0;
    const double verticalPadding = 10.0;

    final dateLabel = (e.startDate != null && e.endDate != null && e.startDate == e.endDate)
        ? e.startDate!
        : ((e.startDate != null && e.endDate != null) ? '${e.startDate} - ${e.endDate}' : (e.startDate ?? ''));

    return GestureDetector(
      onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => LearnMoreScreen(eventId: e.id))),
      child: Container(
        width: width,
        decoration: BoxDecoration(
          color: theme.cardColor,
          borderRadius: BorderRadius.circular(cardRadius),
          boxShadow: [
            BoxShadow(color: Colors.black.withOpacity(0.08), blurRadius: 18, offset: const Offset(0, 10)),
            BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 6, offset: const Offset(0, 3)),
          ],
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: [
            ClipRRect(
              borderRadius: const BorderRadius.vertical(top: Radius.circular(cardRadius)),
              child: img != null
                  ? CachedNetworkImage(
                      imageUrl: img,
                      memCacheWidth: 600,
                      memCacheHeight: 296,
                      width: width,
                      height: imageHeight,
                      fit: BoxFit.cover,
                      placeholder: (_, __) => Container(height: imageHeight, color: theme.dividerColor),
                      errorWidget: (_, __, ___) => Container(height: imageHeight, color: theme.dividerColor),
                    )
                  : Container(height: imageHeight, width: width, color: theme.dividerColor),
            ),

            Padding(
              padding: const EdgeInsets.fromLTRB(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: MainAxisSize.min,
                children: [
                  Text(
                    e.title ?? e.name ?? '',
                    maxLines: 2,
                    overflow: TextOverflow.ellipsis,
                    style: theme.textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w700, fontSize: 14),
                  ),
                  const SizedBox(height: 8),
                  Row(
                    children: [
                      Container(
                        width: 18,
                        height: 18,
                        decoration: BoxDecoration(color: theme.colorScheme.primary.withOpacity(0.12), borderRadius: BorderRadius.circular(4)),
                        child: Icon(Icons.calendar_today, size: 12, color: theme.colorScheme.primary),
                      ),
                      const SizedBox(width: 8),
                      Flexible(child: Text(dateLabel, maxLines: 1, overflow: TextOverflow.ellipsis, style: theme.textTheme.bodySmall?.copyWith(color: theme.hintColor, fontSize: 13))),
                      const Padding(
                        padding: EdgeInsets.symmetric(horizontal: 8.0),
                        child: Text('•', style: TextStyle(color: Colors.black26)),
                      ),
                      Container(
                        width: 18,
                        height: 18,
                        decoration: BoxDecoration(color: theme.colorScheme.primary.withOpacity(0.12), borderRadius: BorderRadius.circular(4)),
                        child: Icon(Icons.location_on, size: 12, color: theme.colorScheme.primary),
                      ),
                      const SizedBox(width: 8),
                      Expanded(child: Text(e.place ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: theme.textTheme.bodySmall?.copyWith(color: theme.hintColor, fontSize: 13))),
                    ],
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  // ------------------------ Page routing ------------------------
  Widget _getCurrentPage() {
    switch (selectedMenu) {
      case 1:
        return const CalendarScreen();
      case 2:
        return const ProfileScreen();
      case 3:
        return BookingScreen(onBook: () {}, image: '');
      case 4:
        return ChangeNotifierProvider(
          create: (_) => GamificationProvider(),
          child: const ContributeScreen(),
        );
      case 5:
        return const SettingsScreen();
      default:
        return _homeContent();
    }
  }

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

    return Scaffold(
      backgroundColor: theme.scaffoldBackgroundColor,
      body: Row(
        children: [
          _buildLeftPanel(),
          Expanded(
            child: Column(
              children: [
                // Show top bar ONLY when Home is active
                if (selectedMenu == 0) _buildTopBar(),
                // Page content under the top bar (or directly if top bar hidden)
                Expanded(child: _getCurrentPage()),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
