import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_paypal/flutter_paypal.dart';
import 'package:flutter_stripe/flutter_stripe.dart';
import 'package:get/get.dart';
import 'package:local_auth/local_auth.dart';
import 'package:ride/constant/credential.dart';
import 'package:ride/controller/home/map_passenger_controller.dart';

import '../../constant/box_name.dart';
import '../../constant/colors.dart';
import '../../constant/info.dart';
import '../../constant/links.dart';
import '../../main.dart';
import '../functions/crud.dart';
import '../functions/toast.dart';

class PaymentController extends GetxController {
  bool isLoading = false;
  bool isWalletChecked = true;
  bool isCashChecked = false;
  bool isWalletFound = false;
  bool isPromoSheetDialogue = false;
  final formKey = GlobalKey<FormState>();
  final promo = TextEditingController();
  double totalPassenger = MapPassengerController().totalPassenger;
  int? selectedAmount = 0;
  List<dynamic> totalPassengerWalletDetails = [];
  String passengerTotalWalletAmount = '';
  void updateSelectedAmount(int value) {
    selectedAmount = value;
    update();
  }

  void changePromoSheetDialogue() {
    isPromoSheetDialogue = !isPromoSheetDialogue;
    update();
  }

  getPassengerWallet() async {
    isLoading = true;
    update();

    await CRUD().get(
        link: AppLink.getWalletByPassenger,
        payload: {'passenger_id': box.read(BoxName.passengerID)}).then((value) {
      box.write(BoxName.passengerWalletTotal,
          jsonDecode(value)['message'][0]['total'].toString());
    });

    isLoading = false;
    update();
  }

  void onChangedPaymentMethodWallet(bool? value) {
    isWalletChecked = !isWalletChecked;
    isWalletChecked ? isCashChecked = false : isCashChecked = true;
    update();
  }

  void onChangedPaymentMethodCash(bool? value) {
    isCashChecked = !isCashChecked;
    isCashChecked ? isWalletChecked = false : isWalletChecked = true;
    update();
  }

  void applyPromoCodeToPassenger() async {
    //TAWJIHI
    CRUD().get(link: AppLink.getPassengersPromo, payload: {
      'promo_code': promo.text,
    }).then((value) {
      var decod = jsonDecode(value);

      if (decod["status"] == "success") {
        print(totalPassenger);
        var firstElement = decod["message"][0];
        totalPassenger = totalPassenger -
            (totalPassenger * int.parse(firstElement['amount']));
        MapPassengerController().promoTaken = true;
        update();
        print(totalPassenger);
      }
    });
  }

  late String clientSecret;

  Future<void> makePaymentStripe(
      int amount, String currency, Function method) async {
    var newAmount = amount * 100;

    try {
      // Check if local authentication is available
      bool isAvailable = await LocalAuthentication().isDeviceSupported();
      if (isAvailable) {
        // Authenticate the user
        bool didAuthenticate = await LocalAuthentication().authenticate(
          localizedReason: 'Use Touch ID or Face ID to confirm payment',
        );
        if (didAuthenticate) {
          // User authenticated successfully, proceed with payment
          clientSecret = await getClientSecret(newAmount.toString(), currency);
          await initializePaymentSheet(clientSecret);
          await Stripe.instance.presentPaymentSheet();
          method();
        } else {
          // Authentication failed, handle accordingly
          print('Authentication failed');
        }
      } else {
        // Local authentication not available, proceed with payment without authentication
        clientSecret = await getClientSecret(newAmount.toString(), currency);
        await initializePaymentSheet(clientSecret);
        await Stripe.instance.presentPaymentSheet();
        method();
      }
    } catch (e) {
      rethrow;
    }
  }

  Future<void> makePaymentPayPal(BuildContext context) async {
    try {
      // Check if local authentication is available
      bool isAvailable = await LocalAuthentication().isDeviceSupported();
      if (isAvailable) {
        // Authenticate the user
        bool didAuthenticate = await LocalAuthentication().authenticate(
          localizedReason: 'Use Touch ID or Face ID to confirm payment',
        );
        if (didAuthenticate) {
          // User authenticated successfully, proceed with payment

          if (selectedAmount != 0) {
            print(selectedAmount);
            changePromoSheetDialogue();
            Navigator.of(context).push(
              MaterialPageRoute(
                builder: (BuildContext context) => UsePaypal(
                    sandboxMode: true,
                    clientId:
                        "AW1TdvpSGbIM5iP4HJNI5TyTmwpY9Gv9dYw8_8yW5lYIbCqf326vrkrp0ce9TAqjEGMHiV3OqJM_aRT0",
                    secretKey:
                        "EHHtTDjnmTZATYBPiGzZC_AZUfMpMAzj2VZUeqlFUrRJA_C0pQNCxDccB5qoRQSEdcOnnKQhycuOWdP9",
                    returnURL: "https://samplesite.com/return",
                    cancelURL: "https://samplesite.com/cancel",
                    transactions: [
                      {
                        "amount": {
                          //sb-opsju26682403@personal.example.com
                          "total": '$selectedAmount',
                          "currency": "USD",
                          "details": {
                            "subtotal": '$selectedAmount',
                            "shipping": '0',
                            "shipping_discount": 0
                          }
                        },
                        "description": "The payment transaction description.",
                        "payment_options": const {
                          "allowed_payment_method": "INSTANT_FUNDING_SOURCE"
                        },
                        "item_list": {
                          "items": [
                            {
                              "name": "${AppInformation.appName} Wallet ",
                              "quantity": 1,
                              "price": '$selectedAmount',
                              "currency": "USD"
                            }
                          ],

                          // shipping address is not required though
                          "shipping_address": const {
                            "recipient_name":
                                "${AppInformation.appName} Wallet",
                            "line1": "Shafa Badran",
                            "line2": "",
                            "city": "Amman",
                            "country_code": "JO",
                            "postal_code": "13112",
                            "phone": "+962798583052",
                            "state": "Amman"
                          },
                        }
                      }
                    ],
                    note: "Contact us for any questions on your order.",
                    onSuccess: (Map params) async {
                      print("onSuccess: $params");
                      await CRUD()
                          .post(link: AppLink.addPassengersWallet, payload: {
                        'passenger_id':
                            box.read(BoxName.passengerID).toString(),
                        'balance': selectedAmount.toString()
                      });
                      changePromoSheetDialogue();
                      await getPassengerWallet();
                    },
                    onError: (error) {
                      print("onError: $error");
                      Toast.show(context, ' $error'.tr, AppColor.redColor);
                    },
                    onCancel: (params) {
                      print('cancelled: $params');
                      Toast.show(context, 'Pyament Cancelled .'.tr,
                          AppColor.yellowColor);
                    }),
              ),
            );
          } else {
            Toast.show(context, 'You will choose one of above !'.tr,
                AppColor.redColor);
          }
        } else {
          // Authentication failed, handle accordingly
          print('Authentication failed');
        }
      }
    } catch (e) {
      rethrow;
    }
  }

  Future<void> initializePaymentSheet(String clientSecret) async {
    await Stripe.instance.initPaymentSheet(
      paymentSheetParameters: SetupPaymentSheetParameters(
          paymentIntentClientSecret: clientSecret,
          merchantDisplayName: 'Sefer',
          billingDetails: BillingDetails(
            name: box.read(BoxName.nameDriver).toString(),
            email: box.read(BoxName.emailDriver).toString(),
            phone: box.read(BoxName.phoneDriver).toString(),
          ),
          billingDetailsCollectionConfiguration:
              const BillingDetailsCollectionConfiguration(
            name: CollectionMode.always,
            phone: CollectionMode.always,
            email: CollectionMode.always,
          )),
    );
  }

  Future<String> getClientSecret(String amount, currency) async {
    var res = await CRUD().postStripe(
      link: 'https://api.stripe.com/v1/payment_intents',
      payload: {'amount': amount, 'currency': currency},
    );

    // Convert the res object to a JSON object
    final jsonResponse = jsonDecode(res);
    print(jsonResponse);
    // Check if the client_secret property exists and is not null
    if (jsonResponse.containsKey('client_secret') &&
        jsonResponse['client_secret'] != null) {
      // Return the client_secret property
      return jsonResponse['client_secret'] as String;
    } else {
      throw Exception('Failed to fetch client secret');
    }
  }

  @override
  void onInit() {
    getPassengerWallet();
    final localAuth = LocalAuthentication();
    super.onInit();
  }
}
