import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:http/http.dart' as _dio;
import 'package:lottie/lottie.dart';
import 'package:nearledaily/constants/color_constants.dart';
import '../../modules/authentication/auth.dart';
import '../../modules/product/product.dart';
import '../../modules/tenant/get_tenant.dart' hide Customer;
import '../../service/dio.dart';
import '../tenant_list/tenant_controller.dart';

class CartController extends GetxController {
  var cartItems = <CartItem>[].obs;
  var pastTenantId;
  var pastLocationId;

  var currentTenant = Rxn<Tenant>();
  final CustomDio _customDio = CustomDio(); // assuming your postData() is here
  RxBool showCouponAnimation = false.obs;
  final shake = ValueNotifier<bool>(false);

  void triggerCouponAnimation() {
    showCouponAnimation.value = true;

    Future.delayed(Duration(seconds: 2), () {
      showCouponAnimation.value = false;
    });
  }


  @override
  void onInit() {
    super.onInit();
    appliedCoupon.value = "";
    amt.value = "";
  }

  RxList<Map<String, dynamic>> coupons = <Map<String, dynamic>>[].obs;
  RxString appliedCoupon = ''.obs;
  RxString amt = ''.obs;

  void loadCoupons() async {
    try {
      isLoading.value = true;

      final tenant = currentTenant.value;

      final tenantid = tenant?.tenantid ?? '';
      final locationid = tenant?.locationid ?? 'Unknown Store';

      final url =
          "https://jupiter.nearle.app/live/api/v1/tenants/gettenantpromotions?tenantid=$tenantid&locationid=$locationid";

      final response = await http.get(Uri.parse(url));

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);

        print(url);
        final List details = data["details"] ?? [];

        coupons.value = details.map((promo) {
          return {
            "code": promo["promocode"] ?? "",
            "desc": promo["description"] ?? "",
            "amount": promo["promoamount"]?.toString() ?? "0",
            "start": promo["startdate"] ?? "",
            "end": promo["enddate"] ?? "",
          };
        }).toList();
      }
    } catch (e) {
      print("loadCoupons Error: $e");
    } finally {
      isLoading.value = false;
    }
  }



  void applyCoupon(String code) {
    appliedCoupon.value = code;


    triggerCouponAnimation();
  }

  void showCouponBottomSheet(BuildContext context) {
    final cartCtrl = Get.find<CartController>();

    cartCtrl.appliedCoupon.value = "";
    cartCtrl.amt.value = "";
    cartCtrl.coupons.clear();

    cartCtrl.loadCoupons(); // fetch coupons again


    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      builder: (context) {
        return DraggableScrollableSheet(
          initialChildSize: 0.7,
          minChildSize: 0.4,
          maxChildSize: 0.95,
          builder: (_, controller) {
            return Container(
              padding: EdgeInsets.all(16),
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.vertical(top: Radius.circular(12)),
              ),
              child: Column(
                children: [



                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(
                        "Available Coupons",
                        style: TextStyle(
                          fontSize: 18,
                          fontWeight: FontWeight.w700,
                        ),
                      ),
                      IconButton(onPressed: (){
                        Navigator.of(context).pop();
                        // triggerCouponAnimation();
                      }, icon: Icon(Icons.close))
                    ],
                  ),
                  SizedBox(height: 15),

                  Expanded(
                    child: Obx(() {
                      if (cartCtrl.isLoading.value) {
                        return Center(
                          child: Lottie.asset(
                            'assets/lotties/loading.json', // path to your Lottie JSON file
                            width: 500,
                            height: 500,
                            fit: BoxFit.contain,
                          ),
                        );
                      }

                      // Filter only valid (non-expired) coupons
                      final validCoupons = cartCtrl.coupons.where((item) {
                        try {
                          if (item["end"] == null || item["end"].toString().isEmpty) return true;
                          DateTime endDate = DateTime.parse(item["end"]);
                          DateTime today = DateTime.now();
                          DateTime onlyToday = DateTime(today.year, today.month, today.day);
                          DateTime onlyEnd = DateTime(endDate.year, endDate.month, endDate.day);
                          return !onlyEnd.isBefore(onlyToday); // keep only if not expired
                        } catch (e) {
                          return false; // invalid date → skip
                        }
                      }).toList();

                      if (validCoupons.isEmpty) {

                        return Center(
                          child: Column(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              // Lottie animation
                              Lottie.asset(
                                'assets/lotties/nodata.json', // Replace with your Lottie file path
                                width: 150,
                                height: 150,
                                fit: BoxFit.contain,
                              ),
                              const SizedBox(height: 16),
                              const Text(
                                "No coupons available",
                                style: TextStyle(
                                  fontSize: 14,
                                  fontWeight: FontWeight.w600,
                                  color: Colors.grey,
                                ),
                              ),
                            ],
                          ),
                        );
                      }

                      return ListView.builder(
                        controller: controller,
                        itemCount: validCoupons.length,
                        itemBuilder: (_, index) {
                          final item = validCoupons[index];
                          return couponTile(
                            item["code"],
                            item["desc"],
                            item["amount"],
                            start: item["start"],
                            end: item["end"],
                          );
                        },
                      );
                    }),
                  ),


                ],
              ),
            );
          },
        );
      },
    );
  }

  Widget couponTile(String code, String desc, String amount, {String? start, String? end}) {
    final cartCtrl = Get.find<CartController>();

    String formatDate(String iso) {
      try {
        DateTime dt = DateTime.parse(iso);
        return "${dt.day}-${dt.month}-${dt.year}";
      } catch (e) {
        return "";
      }
    }

    return Container(
      margin: EdgeInsets.only(bottom: 12),
      padding: EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: Color(0xFF662582).withOpacity(0.06),
        borderRadius: BorderRadius.circular(14),
        border: Border.all(color: Color(0xFF662582).withOpacity(0.3)),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.03),
            blurRadius: 4,
            offset: Offset(0, 2),
          )
        ],
      ),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Icon left
          Container(
            padding: EdgeInsets.all(10),
            decoration: BoxDecoration(
              color: Color(0xFF662582).withOpacity(0.2),
              shape: BoxShape.circle,
            ),
            child: Icon(Icons.discount, size: 18, color: Color(0xFF662582)),
          ),

          SizedBox(width: 12),

          // Text section
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  code,
                  style: TextStyle(
                    fontSize: 14,
                    fontWeight: FontWeight.w700,
                    color: Color(0xFF662582),
                  ),
                ),
                SizedBox(height: 4),

                Text(
                  desc,
                  style: TextStyle(
                    fontSize: 12,
                    color: Colors.black87,
                  ),
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                ),

                SizedBox(height: 6),

                // Expiry date

                  Padding(
                    padding: EdgeInsets.only(top: 4),
                    child: Text(
                      "Add items worth ₹100 to use this coupon",
                      style: TextStyle(
                        color: Colors.red,
                        fontSize: 11,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ),
              ],
            ),
          ),

          SizedBox(width: 10),

          // Apply Button
          Obx(() {
            double t = cartCtrl.totalCost;

            bool isApplied =
                cartCtrl.cartItems.isNotEmpty &&
                    t >= 100 &&
                    cartCtrl.appliedCoupon.value == code;


            double totalAmount = cartCtrl.totalCost; // your total

            return ValueListenableBuilder<bool>(
              valueListenable: shake,
              builder: (context, isShaking, child) {
                return AnimatedContainer(
                  duration: Duration(milliseconds: 80),
                  margin: EdgeInsets.only(left: isShaking ? 4 : 0, right: isShaking ? 4 : 0),
                  child: Column(
                    children: [
                      GestureDetector(
                        onTap: () {
                          if (totalAmount < 100) {
                            // 🔥 Trigger shake animation only
                            shake.value = true;
                            Future.delayed(Duration(milliseconds: 300), () {
                              shake.value = false;
                            });
                            return;
                          }

                          // Normal Apply / Remove logic
                          if (isApplied) {
                            cartCtrl.appliedCoupon.value = "";
                            cartCtrl.amt.value = "";
                          } else {
                            cartCtrl.amt.value = amount;
                            cartCtrl.appliedCoupon.value = code;
                          }
                        },
                        child: Container(
                          padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
                          decoration: BoxDecoration(
                            color: isApplied ? Colors.green : Color(0xFF662582),
                            borderRadius: BorderRadius.circular(8),
                          ),
                          child: Text(
                            isApplied ? "Remove" : "Apply",
                            style: TextStyle(
                              color: Colors.white,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                        ),
                      ),

                      // 🔥 Show small red error text (only when below ₹100)
                      // if (totalAmount < 100)
                      //   Padding(
                      //     padding: EdgeInsets.only(top: 4),
                      //     child: Text(
                      //       "Min ₹100 required",
                      //       style: TextStyle(
                      //         color: Colors.red,
                      //         fontSize: 11,
                      //         fontWeight: FontWeight.w600,
                      //       ),
                      //     ),
                      //   ),
                    ],
                  ),
                );
              },
            );
          }),

        ],
      ),
    );
  }



  var isLoading = true.obs;
  var customer = Rxn<Customer>();
  final TenantController tenantController = Get.find<TenantController>();

  Future<void> fetchCustomer(int customerId) async {
    isLoading.value = true;
    try {
      final url = Uri.parse(
          'https://fiesta.nearle.app/live/api/v1/mob/customers/getbyid/?customerid=$customerId');
      final response = await http.get(url);

      if (response.statusCode == 200) {
        final data = json.decode(response.body);
        if (data['status'] == true) {
          customer.value = Customer.fromJson(data['details']);
        }
      } else {
        print('Error: ${response.statusCode}');
      }
    } catch (e) {
      print('Exception: $e');
    } finally {
      isLoading.value = false;
    }
  }

// 🔹 Notify Admin Function using your postData helper
  /// Notify Admin via API
  Future<void> notifyAdmin({
    String title = "Nearle deals",
    String body = "Test -------------------------------------------------",
  }) async {
    const String endpoint = "https://jupiter.nearle.app/live/api/v1/utils/notifyadmin";
    final token = currentTenant.value?.tenanttoken?.toString() ?? "";
    final Map<String, dynamic> payload = {
      "token": [
        token
      ],
      "notification": {
        "title": title,
        "body": body,
        "sound": "ring",
        "type": "tojoin"
      }
    };

    try {
      print("📡 Sending admin notification...");

      final response = await _customDio.postData(endpoint, payload);
      print("📌 Tenant token: $token");
      print("📌 Notification title: $title");
      print("📌 Notification body: $body");
      print("✅ Admin notified successfully: $response");
      print("📌 Tenant token from tenantController: ${currentTenant.value?.tenanttoken}");
    } catch (e) {
      print("❌ Error notifying admin: $e");
    }
  }



  Future<void> addToCart(
      Product product, {
        int qty = 1,
        String? storeName,
        String? storeImage,
        String? locationId,
      }) async {

    final currentTenantId = product.tenantid.toString();
    final previousTenantId = pastTenantId?.toString();

    final currentLocationId = locationId?.toString();
    final previousLocationId = pastLocationId?.toString();

    print("Adding product from store: $currentTenantId");
    print("Past Tenant ID: $previousTenantId");
    print("Current Location ID: $currentLocationId");
    print("Past Location ID: $previousLocationId");

    final tenant = tenantController.tenants.firstWhereOrNull(
            (t) => t.tenantid == int.parse(currentTenantId)
    );

    // First item → set tenant + location
    if (cartItems.isEmpty) {
      cartItems.add(CartItem(product: product, quantity: qty));
      pastTenantId = currentTenantId;
      pastLocationId = currentLocationId;
      currentTenant.value = tenant;

      print("✅ Tenant set for cart: ${tenant?.tenantname}");
      return;
    }

    // --------- MAIN CHECK (Tenant + Location Must Match) ----------
    if (previousTenantId == currentTenantId &&
        previousLocationId == currentLocationId) {

      // Same tenant and same location → add item normally
      final index = cartItems.indexWhere(
              (item) => item.product.productid == product.productid);

      if (index >= 0) {
        cartItems[index].quantity += qty;
        cartItems.refresh();
      } else {
        cartItems.add(CartItem(product: product, quantity: qty));
      }

    } else {
      // -------- DIFFERENT TENANT or DIFFERENT LOCATION -----------
      // (Your Existing Replace Cart Logic stays SAME)

      if (Get.isBottomSheetOpen!) Get.back();
      await Future.delayed(Duration(milliseconds: 100));

      bool? replace = await Get.bottomSheet<bool>(
        SafeArea(
          child: Container(
            padding: EdgeInsets.all(16),
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [

                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Text("Replace Cart?",
                        style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
                    IconButton(
                      onPressed: () => Get.back(),
                      icon: Icon(Icons.close),
                    )
                  ],
                ),

                SizedBox(height: 16),

                Text(
                  "Looks like your cart has items from another store or location. Replace them?",
                  style: TextStyle(fontSize: 14, color: Colors.grey[700]),
                ),

                SizedBox(height: 24),

                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    TextButton(
                        onPressed: () => Get.back(result: false),
                        child: Text("No")),
                    SizedBox(width: 8),
                    ElevatedButton(
                      onPressed: () => Get.back(result: true),
                      style: ElevatedButton.styleFrom(
                          backgroundColor: ColorConstants.primaryColor),
                      child: Text("Yes", style: TextStyle(color: Colors.white)),
                    ),
                  ],
                ),
                SizedBox(height: 16),
              ],
            ),
          ),
        ),
        isDismissible: false,
        enableDrag: false,
      );

      if (replace == true) {
        cartItems.clear();
        cartItems.add(CartItem(product: product, quantity: qty));

        pastTenantId = currentTenantId;
        pastLocationId = currentLocationId;
      }
    }
  }


  double get totalTax => cartItems.fold(
    0,
        (sum, item) => sum + ((item.product.taxamount ?? 0) * item.quantity),
  );

  double get totalCostWithTax => cartItems.fold(
    0,
        (sum, item) =>
    sum + ((item.product.productcost ?? 0) + (item.product.taxamount ?? 0)) * item.quantity,
  );

  /// Remove product from cart
  void removeFromCart(Product product) {
    cartItems.removeWhere((item) => item.product.productid == product.productid);
  }

  void increaseQty(CartItem item) {
    item.quantity++;
    cartItems.refresh();
  }

  void decreaseQty(CartItem item) {
    if (item.quantity > 1) {
      item.quantity--;
    } else {
      cartItems.remove(item);
    }
    cartItems.refresh();
  }



  /// Clear cart
  void clearCart() => cartItems.clear();

  /// Total items in cart
  int get totalItems => cartItems.fold(0, (sum, item) => sum + item.quantity);

  /// Total cost of items in cart
  double get totalCost =>
      cartItems.fold(0, (sum, item) => sum + ((item.product.productcost ?? 0) * item.quantity));
}



/// Cart item class
class CartItem {
  final Product product;
  int quantity;

  CartItem({required this.product, this.quantity = 1});
}


