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_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/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:proxibuy/services/mqtt_service.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? _mqttMessageSubscription;
  StreamSubscription? _connectivitySubscription;
  Timer? _locationTimer;
  bool _isSubscribedToOffers = false;
  bool _isGpsEnabled = false;

  @override
  void initState() {
    super.initState();
    _initializePage();
    _initConnectivityListener();
    _fetchInitialReservations(); // <-- فراخوانی متد جدید
  }

  // ******** شروع متد جدید ********
  // این متد تعداد اولیه رزروها را برای نمایش روی آیکون دریافت می‌کند
  Future<void> _fetchInitialReservations() async {
    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();

        // به‌روزرسانی Cubit با لیست شناسه‌ها
        context.read<ReservationCubit>().setReservedIds(reservedIds);
      }
    } catch (e) {
      // اگر خطایی رخ دهد، مشکلی نیست. فقط عدد نمایش داده نمی‌شود
      debugPrint("Error fetching initial reservations: $e");
    }
  }
  // ******** پایان متد جدید ********

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

    await _loadPreferences();
    _checkAndConnectMqtt();
    _initLocationListener();
  }

  void _initConnectivityListener() {
    _connectivitySubscription = Connectivity().onConnectivityChanged.listen((
      List<ConnectivityResult> results,
    ) {
      if (!results.contains(ConnectivityResult.none)) {
        print("ℹ️ Network connection restored.");
        _checkAndConnectMqtt();
      } else {
        print("ℹ️ Network connection lost.");
      }
    });
  }

  Future<void> _checkAndConnectMqtt() async {
    final mqttService = context.read<MqttService>();
    if (!mqttService.isConnected) {
      print("--- OffersPage: MQTT not connected. Attempting to connect...");
      final storage = const FlutterSecureStorage();
      final token = await storage.read(key: 'accessToken');
      if (token != null && token.isNotEmpty) {
        try {
          await mqttService.connect(token);
          if (mqttService.isConnected && mounted) {
            _subscribeToUserOffersOnLoad();
          }
        } catch (e) {
          print("❌ OffersPage: Error connecting to MQTT: $e");
        }
      }
    } else {
      print("--- OffersPage: MQTT already connected.");
      _subscribeToUserOffersOnLoad();
    }
  }

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

  Future<void> _subscribeToUserOffersOnLoad() async {
    final storage = const FlutterSecureStorage();
    final userID = await storage.read(key: 'userID');
    if (userID != null && mounted) {
      _subscribeToUserOffers(userID);
    }
  }

  void _initLocationListener() {
    _checkInitialGpsStatus();
    _locationServiceSubscription = Geolocator.getServiceStatusStream().listen((
      status,
    ) {
      final isEnabled = status == ServiceStatus.enabled;
      if (mounted && _isGpsEnabled != isEnabled) {
        setState(() {
          _isGpsEnabled = isEnabled;
        });
      }

      if (isEnabled) {
        _startSendingLocationUpdates();
      } else {
        print("❌ Location Service Disabled. Stopping updates.");
        _locationTimer?.cancel();
        context.read<OffersBloc>().add(ClearOffers());
      }
    });
  }

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

  void _startSendingLocationUpdates() {
    print("🚀 Starting periodic location updates.");
    _locationTimer?.cancel();
    _locationTimer = Timer.periodic(const Duration(seconds: 30), (timer) {
      _sendLocationUpdate();
    });
    _sendLocationUpdate();
  }

  Future<void> _sendLocationUpdate() async {
    final mqttService = context.read<MqttService>();
    if (!mqttService.isConnected) {
      print("⚠️ MQTT not connected in OffersPage. Cannot send location.");
      return;
    }

    try {
      LocationPermission permission = await Geolocator.checkPermission();
      if (permission == LocationPermission.denied) {
        permission = await Geolocator.requestPermission();
      }

      if (permission == LocationPermission.denied ||
          permission == LocationPermission.deniedForever) {
        print("🚫 Location permission denied by user.");
        return;
      }

      final position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high,
      );

      const storage = FlutterSecureStorage();
      final userID = await storage.read(key: 'userID');

      if (userID == null) {
        print("⚠️ UserID not found. Cannot send location.");
        return;
      }

      final payload = {"userID": userID, "lat": 32.6685, "lng": 51.6826};

      mqttService.publish("proxybuy/sendGps", payload);
    } catch (e) {
      print("❌ Error sending location update in OffersPage: $e");
    }
  }

  void _subscribeToUserOffers(String userID) {
    if (_isSubscribedToOffers) return;

    final mqttService = context.read<MqttService>();
    final topic = 'user-proxybuy/$userID';
    mqttService.subscribe(topic);
    _isSubscribedToOffers = true;

    _mqttMessageSubscription = mqttService.messages.listen((message) {
      final data = message['data'];

      if (data == null) {
        if (mounted) {
          context.read<OffersBloc>().add(const OffersReceivedFromMqtt([]));
        }
        return;
      }

      if (data is List) {
        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) {
          print("❌ Error parsing offers from MQTT: $e");
          print(stackTrace);
        }
      }
    });
  }

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

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

  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 (result == true && mounted) {
                    _loadPreferences();
                  }
                },
                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: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _buildFavoriteCategoriesSection(),
              OffersView(isGpsEnabled: _isGpsEnabled),
            ],
          ),
        ),
      ),
    );
  }
}

class OffersView extends StatelessWidget {
  final bool isGpsEnabled;

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

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<OffersBloc, OffersState>(
      builder: (context, state) {
        if (!isGpsEnabled) {
          return _buildGpsActivationUI(context);
        }

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

          final groupedOffers = groupBy(
            state.offers,
            (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('جست‌وجوی تصادفی'),
            ],
          ),
        ),
      ),
    );
  }
}
