
import 'dart:async';
import 'package:collection/collection.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_background_service/flutter_background_service.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_svg/svg.dart';
import 'package:geolocator/geolocator.dart';
import 'package:proxibuy/core/config/api_config.dart';
import 'package:proxibuy/core/config/app_colors.dart';
import 'package:proxibuy/core/gen/assets.gen.dart';
import 'package:proxibuy/data/models/offer_model.dart';
import 'package:proxibuy/presentation/notification_preferences/bloc/notification_preferences_bloc.dart';
import 'package:proxibuy/presentation/notification_preferences/bloc/notification_preferences_event.dart';
import 'package:proxibuy/presentation/offer/bloc/offer_bloc.dart';
import 'package:proxibuy/presentation/offer/bloc/offer_event.dart';
import 'package:proxibuy/presentation/offer/bloc/offer_state.dart';
import 'package:proxibuy/presentation/offer/bloc/widgets/category_offers_row.dart';
import 'package:proxibuy/presentation/pages/notification_preferences_page.dart';
import 'package:proxibuy/presentation/pages/reserved_list_page.dart';
import 'package:proxibuy/presentation/reservation/cubit/reservation_cubit.dart';
import 'package:proxibuy/presentation/widgets/gps_dialog.dart';
import 'package:proxibuy/presentation/widgets/notification_permission_dialog.dart';
import 'package:shared_preferences/shared_preferences.dart';

class OffersPage extends StatefulWidget {
  final bool showDialogsOnLoad;

  const OffersPage({super.key, this.showDialogsOnLoad = false});

  @override
  State<OffersPage> createState() => _OffersPageState();
}

class _OffersPageState extends State<OffersPage> {
  List<String> _selectedCategories = [];
  StreamSubscription? _locationServiceSubscription;
  StreamSubscription? _connectivitySubscription;
  bool _isGpsEnabled = false;
  bool _isConnectedToInternet = true;

  @override
  void initState() {
    super.initState();
    _checkInitialConnectivity();
    _initializePage();
    _initConnectivityListener();
    _fetchInitialReservations();
  }

  @override
  void dispose() {
    _locationServiceSubscription?.cancel();
    _connectivitySubscription?.cancel();
    super.dispose();
  }

  Future<void> _checkInitialConnectivity() async {
    final connectivityResult = await Connectivity().checkConnectivity();
    if (!mounted) return;
    setState(() {
      _isConnectedToInternet =
          !connectivityResult.contains(ConnectivityResult.none);
    });
  }

  Future<void> _initializePage() async {
    if (widget.showDialogsOnLoad) {
      WidgetsBinding.instance.addPostFrameCallback((_) async {
        if (mounted) {
          await showNotificationPermissionDialog(context);
          await showGPSDialog(context);
        }
      });
    }
    await _loadPreferences();
    _initLocationListener();
    _listenToBackgroundService();
  }

  void _listenToBackgroundService() {
    FlutterBackgroundService().on('update').listen((event) {
      if (event == null || event['offers'] == null) return;

      final data = event['offers']['data'];
      if (data == null || data is! List) {
        if (mounted) {
          context.read<OffersBloc>().add(const OffersReceivedFromMqtt([]));
        }
        return;
      }

      try {
        List<OfferModel> offers = data
            .whereType<Map<String, dynamic>>()
            .map((json) => OfferModel.fromJson(json))
            .toList();

        if (mounted) {
          context.read<OffersBloc>().add(OffersReceivedFromMqtt(offers));
        }
      } catch (e, stackTrace) {
        debugPrint("❌ Error parsing offers from Background Service: $e");
        debugPrint(stackTrace.toString());
      }
    });
  }

  void _initConnectivityListener() {
    _connectivitySubscription =
        Connectivity().onConnectivityChanged.listen((results) {
      final hasConnection = !results.contains(ConnectivityResult.none);
      if (mounted && _isConnectedToInternet != hasConnection) {
        setState(() {
          _isConnectedToInternet = hasConnection;
        });

        if (hasConnection) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('اتصال به اینترنت برقرار شد.'),
              backgroundColor: Colors.green,
            ),
          );
        } else {
          context.read<OffersBloc>().add(ClearOffers());
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('اتصال به اینترنت قطع شد.'),
              backgroundColor: Colors.red,
            ),
          );
        }
      }
    });
  }

  Future<void> _fetchInitialReservations() async {
    if (!_isConnectedToInternet) return;
    try {
      const storage = FlutterSecureStorage();
      final token = await storage.read(key: 'accessToken');
      if (token == null) return;

      final dio = Dio();
      final response = await dio.get(
        ApiConfig.baseUrl + ApiConfig.getReservations,
        options: Options(headers: {'Authorization': 'Bearer $token'}),
      );

      if (response.statusCode == 200 && mounted) {
        final List<dynamic> reserves = response.data['reserves'];
        final List<String> reservedIds = reserves
            .map((reserveData) =>
                (reserveData['Discount']['ID'] as String?) ?? '')
            .where((id) => id.isNotEmpty)
            .toList();

        context.read<ReservationCubit>().setReservedIds(reservedIds);
      }
    } catch (e) {
      debugPrint("Error fetching initial reservations: $e");
    }
  }

  void _initLocationListener() {
    _checkInitialGpsStatus();
    _locationServiceSubscription =
        Geolocator.getServiceStatusStream().listen((status) {
      final isEnabled = status == ServiceStatus.enabled;
      if (mounted && _isGpsEnabled != isEnabled) {
        setState(() {
          _isGpsEnabled = isEnabled;
        });
        if (!isEnabled) {
          context.read<OffersBloc>().add(ClearOffers());
        }
      }
    });
  }

  Future<void> _checkInitialGpsStatus() async {
    final status = await Geolocator.isLocationServiceEnabled();
    if (mounted) {
      setState(() {
        _isGpsEnabled = status;
      });
    }
  }

  Future<void> _loadPreferences() async {
    final prefs = await SharedPreferences.getInstance();
    final savedCategories =
        prefs.getStringList('user_selected_categories') ?? [];

    if (mounted) {
      setState(() {
        _selectedCategories = savedCategories;
      });
    }
  }

  Future<void> _handleRefresh() {
    final completer = Completer<void>();
    final service = FlutterBackgroundService();

    final timeout = Timer(const Duration(seconds: 20), () {
      if (!completer.isCompleted) {
        completer.completeError('Request timed out.');
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
                content: Text('Request timed out. Please try again.')),
          );
        }
      }
    });

    final StreamSubscription<Map<String, dynamic>?> subscription =
        service.on('update').listen((event) {
      if (!completer.isCompleted) {
        completer.complete();
      }
    });

    completer.future.whenComplete(() {
      subscription.cancel();
      timeout.cancel();
    });

    service.invoke('force_refresh');

    return completer.future;
  }

  Widget _buildFavoriteCategoriesSection() {
    return Padding(
      padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              const Text(
                'دسته‌بندی‌های مورد علاقه شما',
                style: TextStyle(fontSize: 19, fontWeight: FontWeight.bold),
              ),
              TextButton(
                onPressed: () async {
                  final result = await Navigator.of(context).push<bool>(
                    MaterialPageRoute(
                      builder: (context) => const NotificationPreferencesPage(
                        loadFavoritesOnStart: true,
                      ),
                    ),
                  );

                  if (!mounted) return;

                  context
                      .read<NotificationPreferencesBloc>()
                      .add(ResetSubmissionStatus());

                  await _loadPreferences();

                  if (result == true) {
                    _handleRefresh();
                  }
                },
                child: Row(
                  children: [
                    SvgPicture.asset(Assets.icons.edit.path),
                    const SizedBox(width: 4),
                    const Text(
                      'ویرایش',
                      style: TextStyle(color: AppColors.active),
                    ),
                  ],
                ),
              ),
            ],
          ),
          const Divider(height: 1),
          const SizedBox(height: 12),
          if (_selectedCategories.isEmpty)
            const Padding(
              padding: EdgeInsets.only(bottom: 8.0),
              child: Text(
                'شما هنوز دسته‌بندی مورد علاقه خود را انتخاب نکرده‌اید.',
                style: TextStyle(color: Colors.grey),
              ),
            )
          else
            Wrap(
              spacing: 8.0,
              runSpacing: 8.0,
              children: _selectedCategories.map((category) {
                return Container(
                  padding: const EdgeInsets.symmetric(
                    horizontal: 12.0,
                    vertical: 6.0,
                  ),
                  decoration: BoxDecoration(
                    border: Border.all(color: Colors.grey.shade300),
                    borderRadius: BorderRadius.circular(20.0),
                  ),
                  child: Text(category),
                );
              }).toList(),
            ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.rtl,
      child: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.white,
          automaticallyImplyLeading: false,
          title: Padding(
            padding: const EdgeInsets.symmetric(
              horizontal: 15.0,
              vertical: 0.0,
            ),
            child: Assets.icons.logoWithName.svg(height: 40, width: 200),
          ),
          actions: [
            IconButton(
                onPressed: () {}, icon: Assets.icons.notification.svg()),
            BlocBuilder<ReservationCubit, ReservationState>(
              builder: (context, state) {
                final reservedCount = state.reservedProductIds.length;
                return Stack(
                  alignment: Alignment.center,
                  children: [
                    IconButton(
                      onPressed: () {
                        Navigator.of(context).push(
                          MaterialPageRoute(
                            builder: (_) => const ReservedListPage(),
                          ),
                        );
                      },
                      icon: Assets.icons.scanBarcode.svg(),
                    ),
                    if (reservedCount > 0)
                      Positioned(
                        top: 0,
                        right: 2,
                        child: GestureDetector(
                          onTap: () {
                            Navigator.of(context).push(
                              MaterialPageRoute(
                                builder: (_) => const ReservedListPage(),
                              ),
                            );
                          },
                          child: Container(
                            padding: const EdgeInsets.all(4),
                            decoration: BoxDecoration(
                              color: Colors.green,
                              shape: BoxShape.circle,
                              border:
                                  Border.all(color: Colors.white, width: 1.5),
                            ),
                            constraints: const BoxConstraints(
                              minWidth: 18,
                              minHeight: 18,
                            ),
                            child: Padding(
                              padding: const EdgeInsets.fromLTRB(2, 4, 2, 2),
                              child: Text(
                                '$reservedCount',
                                style: const TextStyle(
                                  color: Colors.white,
                                  fontSize: 11,
                                  fontWeight: FontWeight.bold,
                                ),
                                textAlign: TextAlign.center,
                              ),
                            ),
                          ),
                        ),
                      ),
                  ],
                );
              },
            ),
            const SizedBox(width: 8),
          ],
        ),
        body: RefreshIndicator(
          onRefresh: _handleRefresh,
          child: SingleChildScrollView(
            physics: const AlwaysScrollableScrollPhysics(),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                _buildFavoriteCategoriesSection(),
                OffersView(
                  isGpsEnabled: _isGpsEnabled,
                  isConnectedToInternet: _isConnectedToInternet,
                  selectedCategories: _selectedCategories,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class OffersView extends StatelessWidget {
  final bool isGpsEnabled;
  final bool isConnectedToInternet;
  final List<String> selectedCategories;

  const OffersView({
    super.key,
    required this.isGpsEnabled,
    required this.isConnectedToInternet,
    required this.selectedCategories,
  });

  @override
  Widget build(BuildContext context) {
    if (!isConnectedToInternet) {
      return _buildNoInternetUI(context);
    }

    if (!isGpsEnabled) {
      return _buildGpsActivationUI(context);
    }

    return BlocBuilder<OffersBloc, OffersState>(
      builder: (context, state) {
        if (state is OffersInitial) {
          return const SizedBox(
            height: 300,
            child: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  CircularProgressIndicator(),
                  SizedBox(height: 20),
                  Text("در حال یافتن بهترین پیشنهادها برای شما..."),
                ],
              ),
            ),
          );
        }

        if (state is OffersLoadSuccess) {
          final filteredOffers = selectedCategories.isEmpty
              ? state.offers
              : state.offers
                  .where((offer) => selectedCategories.contains(offer.category))
                  .toList();

          if (filteredOffers.isEmpty) {
            return const SizedBox(
              height: 300,
              child: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text("فعلاً تخفیفی در این اطراف نیست!"),
                    Text("کمی قدم بزنید..."),
                  ],
                ),
              ),
            );
          }

          final groupedOffers = groupBy(
            filteredOffers,
            (OfferModel offer) => offer.category,
          );
          final categories = groupedOffers.keys.toList();

          return ListView.builder(
            shrinkWrap: true,
            physics: const NeverScrollableScrollPhysics(),
            padding: const EdgeInsets.only(top: 16),
            itemCount: categories.length,
            itemBuilder: (context, index) {
              final category = categories[index];
              final offersForCategory = groupedOffers[category]!;

              return CategoryOffersRow(
                categoryTitle: category,
                offers: offersForCategory,
              ).animate().fade(duration: 500.ms).slideY(
                  begin: 0.3, duration: 400.ms, curve: Curves.easeOut);
            },
          );
        }

        if (state is OffersLoadFailure) {
          return SizedBox(
            height: 200,
            child: Center(child: Text("خطا در بارگذاری: ${state.error}")),
          );
        }

        return const SizedBox.shrink();
      },
    );
  }

  Widget _buildGpsActivationUI(BuildContext context) {
    return Center(
      child: SizedBox(
        child: Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              const SizedBox(height: 85),
              SvgPicture.asset(Assets.images.emptyHome.path),
              const SizedBox(height: 60),
              ElevatedButton(
                onPressed: () async {
                  await Geolocator.openLocationSettings();
                },
                style: ElevatedButton.styleFrom(
                  backgroundColor: AppColors.confirm,
                  foregroundColor: Colors.white,
                  disabledBackgroundColor: Colors.grey,
                  padding: const EdgeInsets.symmetric(
                    vertical: 12,
                    horizontal: 125,
                  ),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(50),
                  ),
                ),
                child: const Text(
                  'فعال‌سازی GPS',
                  style: TextStyle(
                    fontFamily: 'Dana',
                    fontSize: 16,
                    fontWeight: FontWeight.normal,
                  ),
                ),
              ),
              const SizedBox(height: 15),
              const Text('جست‌وجوی تصادفی'),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildNoInternetUI(BuildContext context) {
    return SizedBox(
      height: 300,
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(Icons.wifi_off_rounded, size: 80, color: Colors.grey[400]),
            const SizedBox(height: 20),
            const Text(
              "اتصال به اینترنت برقرار نیست",
              style: TextStyle(fontSize: 18, color: Colors.grey),
            ),
            const SizedBox(height: 10),
            const Text(
              "لطفاً اتصال خود را بررسی کرده و دوباره تلاش کنید.",
              style: TextStyle(color: Colors.grey),
            ),
          ],
        ),
      ),
    );
  }
}