import 'dart:async';
import 'dart:convert';

import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import '../../constant/api_key.dart';
import '../../constant/box_name.dart';
import '../../constant/links.dart';
import '../../main.dart';
import '../../print.dart';
import '../functions/crud.dart';

class WalletAdminController extends GetxController {
  bool isLoading = false;

  late Map<String, dynamic> jsonResponse;
  List<dynamic> walletDetails = [];
  List driversWalletPoints = [];

  @override
  void onInit() {
    getWalletForEachDriverToPay();
    super.onInit();
  }

  Future getWalletAdminDash() async {
    isLoading = true;
    update();
    var res = await CRUD().get(link: AppLink.getRidesPerMonth, payload: {});
    jsonResponse = jsonDecode(res);
  }

  Future payToBankDriverAll() async {
    for (var i = 0; i < driversWalletPoints.length; i++) {
      String token = await getToken();
      await Future.delayed(const Duration(seconds: 1));
      try {
        await payToDriverBankAccount(
          token,
          driversWalletPoints[i]['total_amount'].toString(),
          driversWalletPoints[i]['accountBank'].toString(),
          driversWalletPoints[i]['bankCode'].toString(),
          driversWalletPoints[i]['name_arabic'].toString(),
          driversWalletPoints[i]['driverID'].toString(),
          driversWalletPoints[i]['phone'].toString(),
          driversWalletPoints[i]['email'].toString(),
        );
        await Future.delayed(const Duration(seconds: 3));
      } on FormatException catch (e) {
        // Handle the error or rethrow the exception as needed
      }
    }
  }

  Future<void> payToDriverBankAccount(
      String token,
      String amount,
      String bankCardNumber,
      String bankCode,
      String name,
      String driverId,
      String phone,
      String email) async {
    var headers = {
      'Authorization': 'Bearer $token',
      'Content-Type': 'application/json',
    };

    var body = jsonEncode({
      "issuer": "bank_card",
      "amount": amount,
      "full_name": name,
      "bank_card_number": bankCardNumber,
      "bank_code": bankCode,
      "bank_transaction_type": "cash_transfer"
    });

    var response = await http.post(
        Uri.parse(
            'https://stagingpayouts.paymobsolutions.com/api/secure/disburse/'),
        headers: headers,
        body: body);

    if (response.statusCode == 200) {
      var d = jsonDecode(response.body);

      if (d['status_description'] ==
          "Transaction received and validated successfully. Dispatched for being processed by the bank") {
        await addPayment('payFromSeferToDriver', driverId,
            ((-1) * double.parse(amount)).toString());
        await addSeferWallet('payFromSeferToDriver', driverId,
            ((-1) * double.parse(amount)).toString());
        await updatePaymentToPaid(driverId);
        await sendEmail(driverId, amount, phone, name, bankCardNumber, email);
      }
    } else {}
  }

  // String paymentToken = '';
  Future<String> generateToken(String amount) async {
    var res = await CRUD().post(link: AppLink.addPaymentTokenDriver, payload: {
      'driverID': box.read(BoxName.driverID).toString(),
      'amount': amount.toString(),
    });
    var d = jsonDecode(res);
    return d['message'];
  }

  Future sendEmail(
      String driverId, amount, phone, name, bankCardNumber, email) async {
    await CRUD().sendEmail(AppLink.sendEmailToDrivertransaction, {
      "driverID": driverId,
      "total_amount": amount,
      "phone": phone,
      "name_arabic": name,
      "accountBank": bankCardNumber,
      "email": email
    });
  }

  Future addSeferWallet(
      String paymentMethod, String driverID, String point) async {
    var seferToken = await generateToken(point.toString());
    await CRUD().post(link: AppLink.addSeferWallet, payload: {
      'amount': point.toString(),
      'paymentMethod': paymentMethod,
      'passengerId': 'driver',
      'token': seferToken,
      'driverId': driverID.toString(),
    });
  }

  Future addPayment(
      String paymentMethod, String driverID, String amount) async {
    var paymentToken =
        await generateToken(((double.parse(amount))).toStringAsFixed(0));
    await CRUD().post(link: AppLink.addDrivePayment, payload: {
      'rideId': DateTime.now().toIso8601String(),
      'amount': ((double.parse(amount))).toStringAsFixed(0),
      'payment_method': paymentMethod,
      'passengerID': 'myself',
      'token': paymentToken,
      'driverID': driverID.toString(),
    });
  }

  Future updatePaymentToPaid(String driverID) async {
    await CRUD().post(link: AppLink.updatePaymetToPaid, payload: {
      'driverID': driverID.toString(),
    });
  }

  Future<String> getToken() async {
    var headers = {
      'Content-Type': 'application/x-www-form-urlencoded',
      // 'Cookie':
      //     'csrftoken=74iZJ8XYyuTm5WRq2W4tpWX5eqoJLZVK5QhuDrChWpDtzpgGA269bbCWuEcW85t4'
    };
    var body = {
      'grant_type': 'password',
      'username': AK.payMobOutUserName,
      'password': AK.payMobOutPassword,
      'client_id': AK.payMobOutClient_id,
      'client_secret': AK.payMobOutClientSecrret
    };
    var res = await http.post(
      Uri.parse(
          'https://stagingpayouts.paymobsolutions.com/api/secure/o/token/'),
      headers: headers,
      body: body,
    );
    String token = '';
    if (res.statusCode == 200) {
      var decode = jsonDecode(res.body);
      token = decode['access_token'];
    }
    return token;
  }

  Future getWalletForEachDriverToPay() async {
    isLoading = true;
    update();
    var res = await CRUD()
        .postWallet(link: AppLink.getVisaForEachDriver, payload: {});
    var d = (res);
    if (d != 'failure') {
      driversWalletPoints = d['message'];
      isLoading = false;
      update();
    }
    driversWalletPoints = [];
    isLoading = false;
    update();
  }
}
