import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mobile_pos/Provider/profile_provider.dart';
import 'package:mobile_pos/model/business_info_model.dart';

import '../../Settings/sales settings/model/amount_rounding_dropdown_model.dart';
import '../../vat_&_tax/model/vat_model.dart';
import '../../../model/add_to_cart_model.dart';

final cartNotifier = ChangeNotifierProvider((ref) {
  return CartNotifier(businessInformation: ref.watch(businessInfoProvider).value);
});

class CartNotifier extends ChangeNotifier {
  final BusinessInformationModel? businessInformation;

  CartNotifier({required this.businessInformation});

  @override
  void addListener(VoidCallback listener) {
    super.addListener(listener);
    roundedOption = businessInformation?.data?.saleRoundingOption ?? roundingMethods[0].value;
  }

  List<SaleCartModel> cartItemList = [];
  TextEditingController discountTextControllerFlat = TextEditingController();
  TextEditingController vatAmountController = TextEditingController();
  TextEditingController shippingChargeController = TextEditingController();

  ///_________NEW_________________________________
  num totalAmount = 0;
  num discountAmount = 0;
  num discountPercent = 0;
  num roundingAmount = 0;
  num actualTotalAmount = 0;
  num totalPayableAmount = 0;
  VatModel? selectedVat;
  num vatAmount = 0;
  bool isFullPaid = false;
  num receiveAmount = 0;
  num changeAmount = 0;
  num dueAmount = 0;
  num finalShippingCharge = 0;
  String roundedOption = roundingMethods[0].value;

  void changeSelectedVat({VatModel? data}) {
    if (data != null) {
      selectedVat = data;
    } else {
      selectedVat = null;
      vatAmount = 0;
      vatAmountController.clear();
    }

    calculatePrice();
  }

  void calculateDiscount({required String value, bool? rebuilding, String? selectedTaxType}) {
    if (value.isEmpty) {
      discountAmount = 0;
      discountPercent = 0;
      discountTextControllerFlat.clear();
    } else {
      num discountValue = num.tryParse(value) ?? 0;

      if (selectedTaxType == null) {
        EasyLoading.showError('Please select a discount type');
        discountAmount = 0;
        discountPercent = 0;
      } else if (selectedTaxType == "Flat") {
        discountAmount = discountValue;
      } else if (selectedTaxType == "Percent") {
        discountPercent = num.tryParse(discountTextControllerFlat.text) ?? 0.0;
        discountAmount = (totalAmount * discountValue) / 100;

        if (discountAmount > totalAmount) {
          discountAmount = totalAmount;
        }
      } else {
        EasyLoading.showError('Invalid discount type selected');
        discountAmount = 0;
      }

      if (discountAmount > totalAmount) {
        discountTextControllerFlat.clear();
        discountAmount = 0;
        EasyLoading.showError('Enter a valid discount');
      }
    }

    if (rebuilding == false) return;
    calculatePrice();
  }

  void updateProduct({required num productId, required String price, required String qty, required num discount}) {
    int index = cartItemList.indexWhere((element) => element.productId == productId);
    if (index != -1) {
      cartItemList[index].unitPrice = num.tryParse(price);
      cartItemList[index].quantity = num.tryParse(qty) ?? 0;
      cartItemList[index].discountAmount = discount; // Store the product-wise discount
      calculatePrice();
    }
  }

  void calculatePrice({String? receivedAmount, String? shippingCharge, bool? stopRebuild}) {
    totalAmount = 0;
    totalPayableAmount = 0;
    dueAmount = 0;

    // Calculate Subtotal with Product-wise Discounts
    for (var element in cartItemList) {
      num unitPrice = element.unitPrice ?? 0;
      num productDiscount = element.discountAmount ?? 0;
      num quantity = element.quantity;

      // Formula: (Unit Price - Discount) * Quantity
      // Note: The validation in the form ensures Discount <= Unit Price
      totalAmount += (unitPrice - productDiscount) * quantity;
    }

    totalPayableAmount = totalAmount;

    // Apply Global Discount (on the already discounted subtotal)
    if (discountAmount > totalAmount) {
      calculateDiscount(
        value: discountAmount.toString(),
        rebuilding: false,
      );
    }
    if (discountAmount >= 0) {
      totalPayableAmount -= discountAmount;
    }

    // Apply Item-wise VAT
    vatAmount = 0;
    for (var element in cartItemList) {
      num unitPrice = element.unitPrice ?? 0;
      num quantity = element.quantity;
      num taxRate = element.perItemTaxPercentage ?? 0;

      // VAT Formula: (Price * Qty * Rate%)
      // Note: We are calculating VAT on the base price, not discounted price if that's the requirement.
      // But usually VAT is on the final price.
      // The user request "QTY x Harga x % dari vat_id" implies Base Price.
      // If it should be on discounted price, we would subtract productDiscount.
      // Assuming "Harga" refers to the selling price.
      
      num itemVat = (unitPrice * quantity * taxRate) / 100;
      vatAmount += itemVat;
    }
    vatAmountController.text = vatAmount.toStringAsFixed(2);
    
    // Add Total VAT to Payable
    totalPayableAmount += vatAmount;

    // Apply Shipping
    if (shippingCharge != null) {
      finalShippingCharge = num.tryParse(shippingCharge) ?? 0;
    }
    totalPayableAmount += finalShippingCharge;

    // Rounding
    actualTotalAmount = totalPayableAmount;
    num tempTotalPayable = roundNumber(value: totalPayableAmount, roundingType: roundedOption);
    roundingAmount = tempTotalPayable - totalPayableAmount;
    totalPayableAmount = tempTotalPayable;

    // Payment Calculation
    if (receivedAmount != null) {
      receiveAmount = num.tryParse(receivedAmount) ?? 0;
    }

    changeAmount = totalPayableAmount < receiveAmount ? receiveAmount - totalPayableAmount : 0;
    dueAmount = totalPayableAmount < receiveAmount ? 0 : totalPayableAmount - receiveAmount;
    if (dueAmount <= 0) isFullPaid = true;

    if (stopRebuild ?? false) return;
    notifyListeners();
  }

  void quantityIncrease(int index) {
    final item = cartItemList[index];
    final isCombo = item.productType?.toLowerCase().contains('combo') ?? false;
    final stock = item.stock ?? 0;
    final quantity = item.quantity;

    // Allow increase if it's a Combo OR if stock is available
    if (isCombo || stock > quantity) {
      // If not a combo, perform strict stock check
      if (!isCombo && stock < quantity + 1) {
        cartItemList[index].quantity = stock;
      } else {
        cartItemList[index].quantity++;
      }
      calculatePrice();
    } else {
      EasyLoading.showError('Stock Overflow');
    }
  }

  void quantityDecrease(int index) {
    if (cartItemList[index].quantity > 1) {
      cartItemList[index].quantity--;
    }
    calculatePrice();
  }

  void addToCartRiverPod({
    required SaleCartModel cartItem,
    bool? fromEditSales,
    bool? isVariant,
  }) {
    final variantMode = isVariant ?? false;

    final index = cartItemList.indexWhere((element) => variantMode ? element.stockId == cartItem.stockId : element.productId == cartItem.productId);

    if (index != -1) {
      variantMode ? cartItemList[index].quantity = cartItem.quantity : cartItemList[index].quantity++;
    } else {
      cartItemList.add(cartItem);
    }

    if (!(fromEditSales ?? false)) {
      calculatePrice();
    }
  }

  void deleteToCart(int index) {
    cartItemList.removeAt(index);
    calculatePrice();
  }

  void deleteAllVariant({required num productId}) {
    cartItemList.removeWhere(
      (element) => element.productId == productId,
    );
    calculatePrice();
  }

  num getTotalAmount() {
    return totalPayableAmount;
  }
}    
