import 'dart:convert';
import 'package:siro_rider/constant/style.dart';
import 'package:siro_rider/views/home/map_page_passenger.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:local_auth/local_auth.dart';
import 'package:siro_rider/controller/home/map/ride_lifecycle_controller.dart';
import 'package:webview_flutter/webview_flutter.dart';

import '../../constant/box_name.dart';
import '../../constant/links.dart';
import '../../main.dart';
import '../../print.dart';
import '../firebase/notification_service.dart';
import '../functions/crud.dart';
import 'paymob/e_cash_screen.dart';
import '../../views/home/my_wallet/payment_screen_mtn.dart';
import '../../views/home/my_wallet/payment_screen_cliq.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();
  final walletphoneController = TextEditingController();
  double totalPassenger = double.parse(
      Get.find<RideLifecycleController>().totalPassenger.toString());
  int? selectedAmount = 0;
  List<dynamic> totalPassengerWalletDetails = [];
  String passengerTotalWalletAmount = '';
  String ip = '1';
  DateTime now = DateTime.now();
  late int timestamp;

  void updateSelectedAmount(int value) {
    selectedAmount = value;
    update();
  }

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

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

    await CRUD().getWallet(
        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();
  }

  String paymentToken = '';
  
  Future<void> addPassengersWallet(String amount) async {
    try {
      await CRUD().postWallet(link: AppLink.addPassengersWallet, payload: {
        'passenger_id': box.read(BoxName.passengerID).toString(),
        'amount': amount,
      });
      await getPassengerWallet();
    } catch (e) {
      Log.print(e.toString());
    }
  }


  Future<String> generateTokenPassenger(String amount) async {
    var res =
        await CRUD().post(link: AppLink.addPaymentTokenPassenger, payload: {
      'passengerId': box.read(BoxName.passengerID).toString(),
      'amount': amount.toString(),
    });
    var d = jsonDecode(res);
    return d['message'];
  }

  Future<String> generateTokenDriver(String amount) async {
    var res = await CRUD().post(link: AppLink.addPaymentTokenDriver, payload: {
      'driverID': Get.find<RideLifecycleController>().driverId,
      'amount': amount.toString(),
    });
    var d = jsonDecode(res);
    return d['message'];
  }

  Future<void> payToDriverForCancelAfterAppliedAndHeNearYou(
      String rideId) async {
    {
      double costOfWaiting5Minute = box.read(BoxName.countryCode) == 'Egypt'
          ? (4 * .08) + (5 * 1)
          // 4 indicate foe 4 km ditance from driver start move to passenger
          : (4 * .06) + (5 * .06); //for Eygpt other like jordan .06 per minute
      var paymentTokenWait =
          await generateTokenDriver(costOfWaiting5Minute.toString());
      var res =
          await CRUD().postWallet(link: AppLink.addDrivePayment, payload: {
        'rideId': rideId,
        'amount': costOfWaiting5Minute.toString(),
        'payment_method': 'cancel-from-near',
        'passengerID': box.read(BoxName.passengerID).toString(),
        'token': paymentTokenWait,
        'driverID': Get.find<RideLifecycleController>().driverId.toString(),
      });
      var paymentTokenWait1 =
          await generateTokenDriver(costOfWaiting5Minute.toString());
      var res1 = await CRUD()
          .postWallet(link: AppLink.addDriversWalletPoints, payload: {
        'paymentID': 'rideId$rideId',
        'amount': (costOfWaiting5Minute).toStringAsFixed(0),
        'paymentMethod': 'cancel-from-near',
        'token': paymentTokenWait1,
        'driverID': Get.find<RideLifecycleController>().driverId.toString(),
      });

      if (res != 'failure') {
        await NotificationService.sendNotification(
          category: 'Cancel',
          target: Get.find<RideLifecycleController>().driverToken.toString(),
          title: 'Cancel'.tr,
          body:
              'Trip Cancelled. The cost of the trip will be added to your wallet.'
                  .tr,
          isTopic: false, // Important: this is a token
          tone: 'cancel',
          driverList: [],
        );
      }
      var paymentTokenWaitPassenger1 =
          await generateTokenPassenger((costOfWaiting5Minute * -1).toString());
      await CRUD().postWallet(link: AppLink.addPassengersWallet, payload: {
        'passenger_id': box.read(BoxName.passengerID).toString(),
        'balance': (costOfWaiting5Minute * -1).toString(),
        'token': paymentTokenWaitPassenger1,
      });
      Get.offAll(const MapPagePassenger());
    }
  }

  void onChangedPaymentMethodWallet(bool? value) {
    if (box.read(BoxName.passengerWalletTotal) == null ||
        double.parse(box.read(BoxName.passengerWalletTotal).toString()) <
            totalPassenger) {
      isWalletChecked = false;
      isWalletChecked ? isCashChecked = true : isCashChecked = true;
      update();
    } else {
      isWalletChecked = !isWalletChecked;
      isWalletChecked ? isCashChecked = false : isCashChecked = true;
      update();
    }
  }

  void onChangedPaymentMethodCash(bool? value) {
    if (box.read(BoxName.passengerWalletTotal) == null ||
        double.parse(box.read(BoxName.passengerWalletTotal)) < totalPassenger) {
      isWalletChecked = false;
      isCashChecked = !isCashChecked;
      isCashChecked ? isWalletChecked = false : isWalletChecked = false;
      update();
    } else {
      isCashChecked = !isCashChecked;
      isCashChecked ? isWalletChecked = false : isWalletChecked = true;
      update();
    }
  }

  Future<void> payWithEcash(BuildContext context, String amount) async {
    try {
      // 1. يمكنك استخدام نفس طريقة التحقق بالبصمة إذا أردت
      bool isAvailable = await LocalAuthentication().isDeviceSupported();
      if (isAvailable) {
        bool didAuthenticate = await LocalAuthentication().authenticate(
          localizedReason: 'Use Touch ID or Face ID to confirm payment',
        );

        if (didAuthenticate) {
          // 2. استدعاء الـ Endpoint الجديد على السيرفر الخاص بك
          var res = await CRUD().postWallet(
            link: AppLink.payWithEcashPassenger,
            payload: {
              // ✅ أرسل البيانات التي يحتاجها السيرفر الخاص بـ ecash
              "amount": amount,
              "passengerId": box.read(BoxName.passengerID),
            },
          );

          // 3. التأكد من أن السيرفر أعاد رابط الدفع بنجاح
          if (res != null &&
              res['status'] == 'success' &&
              res['message'] != null) {
            final String paymentUrl = res['message'];
            // 4. الانتقال إلى شاشة الدفع الجديدة الخاصة بـ ecash
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) =>
                    EcashPaymentScreen(paymentUrl: paymentUrl),
              ),
            );
          } else {
            // عرض رسالة خطأ في حال فشل السيرفر في إنشاء الرابط
            Get.defaultDialog(
              title: 'Error'.tr,
              content: Text(
                'Failed to initiate payment. Please try again.'.tr,
                style: AppStyle.title,
              ),
            );
          }
        }
      }
    } catch (e) {
      Get.defaultDialog(
        title: 'Error'.tr,
        content: Text(
          'An error occurred during the payment process.'.tr,
          style: AppStyle.title,
        ),
      );
    }
  }

  Future<void> payWithSyriaTelWallet(String amount, String currency) async {
    // helper لفتح لودينغ بأمان
    Future<void> _showLoading() async {
      if (!(Get.isDialogOpen ?? false)) {
        Get.dialog(const Center(child: CircularProgressIndicator()),
            barrierDismissible: false);
      }
    }

    // helper لإغلاق أي حوار مفتوح
    void _closeAnyDialog() {
      if (Get.isDialogOpen ?? false) {
        Get.back();
      }
    }

    await _showLoading();
    try {
      final phone = box.read(BoxName.phoneWallet) as String;
      final passengerId = box.read(BoxName.passengerID).toString();
      final formattedAmount = double.parse(amount).toStringAsFixed(0);

      Log.print("🚀 Syriatel payment start");
      Log.print(
          "📦 Payload => passengerId:$passengerId amount:$formattedAmount phone:$phone");

      // مصادقة حيوية (اختياري)
      final auth = LocalAuthentication();
      if (await auth.isDeviceSupported()) {
        final ok = await auth.authenticate(
          localizedReason: 'استخدم بصمة الإصبع أو الوجه لتأكيد الدفع',
        );
        if (!ok) {
          _closeAnyDialog();
          Log.print("❌ User did not authenticate");
          return;
        }
      }

      // 1) بدء عملية الدفع
      final startRaw = await CRUD().postWalletMtn(
        link: AppLink.payWithSyriatelStart,
        payload: {
          "amount": formattedAmount,
          "passengerId": passengerId,
          "phone": phone,
          "lang": box.read(BoxName.lang) ?? 'ar',
        },
      );

      Log.print("✅ Server response (start): $startRaw");

      // تحويل الاستجابة إلى Map
      late final Map<String, dynamic> startRes;
      if (startRaw is Map<String, dynamic>) {
        startRes = startRaw;
      } else if (startRaw is String) {
        startRes = json.decode(startRaw) as Map<String, dynamic>;
      } else {
        throw Exception("Unexpected start response type");
      }

      if (startRes['status'] != 'success') {
        final msg =
            (startRes['message'] ?? 'Failed to start payment').toString();
        throw Exception(msg);
      }

      final messageData = startRes['message'] as Map<String, dynamic>;
      final transactionID = messageData['transactionID'].toString();
      Log.print("📄 transactionID: $transactionID");
//
      // 2) اطلب من المستخدم إدخال OTP عبر Get.dialog (بدون context)
      _closeAnyDialog(); // أغلق اللودينغ أولاً
      final otpController = TextEditingController();
      final otp = await Get.dialog<String>(
        AlertDialog(
          title: const Text("أدخل كود التحقق"),
          content: TextField(
            controller: otpController,
            keyboardType: TextInputType.number,
            decoration: const InputDecoration(hintText: "كود OTP"),
          ),
          actions: [
            TextButton(
              child: const Text("تأكيد"),
              onPressed: () => Get.back(result: otpController.text.trim()),
            ),
            TextButton(
              child: const Text("إلغاء"),
              onPressed: () => Get.back(result: null),
            ),
          ],
        ),
        barrierDismissible: false,
      );

      if (otp == null || otp.isEmpty) {
        Log.print("❌ OTP not provided");
        return;
      }
      Log.print("🔐 OTP: $otp");

      await _showLoading();

      // 3) تأكيد الدفع
      final confirmRaw = await CRUD().postWallet(
        link: AppLink.payWithSyriatelConfirm,
        payload: {
          "transactionID": transactionID,
          "otp": otp,
        },
      );

      _closeAnyDialog(); // أغلق اللودينغ

      Log.print("✅ Response (confirm): $confirmRaw");

      late final Map<String, dynamic> confirmRes;
      if (confirmRaw is Map<String, dynamic>) {
        confirmRes = confirmRaw;
      } else if (confirmRaw is String) {
        confirmRes = json.decode(confirmRaw) as Map<String, dynamic>;
      } else {
        throw Exception("Unexpected confirm response type");
      }

      if (confirmRes['status'] == 'success') {
        Get.defaultDialog(
          title: "✅ نجاح",
          content: const Text("تمت عملية الدفع وإضافة الرصيد إلى محفظتك."),
        );
      } else {
        final msg = (confirmRes['message'] ?? 'فشل في تأكيد الدفع').toString();
        Get.defaultDialog(
          title: "❌ فشل",
          content: Text(msg),
        );
      }
    } catch (e, s) {
      Log.print("🔥 Error during Syriatel Wallet payment:\n$e\n$s");
      _closeAnyDialog();
      Get.defaultDialog(
        title: 'حدث خطأ',
        content: Text(e.toString().replaceFirst("Exception: ", "")),
      );
    }
  }

  Future<void> payWithMTNWallet(BuildContext context, String amount, String currency) async {
    try {
      final phone = walletphoneController.text.trim();
      if (phone.isEmpty) {
        Get.defaultDialog(title: 'Error'.tr, content: Text('Please enter phone number'.tr));
        return;
      }
      
      Get.dialog(const Center(child: CircularProgressIndicator()), barrierDismissible: false);
      
      var res = await CRUD().postWalletMtn(
        link: AppLink.createMtnInvoice,
        payload: {
          "amount": amount,
          "user_id": box.read(BoxName.passengerID).toString(),
          "user_type": "passenger",
          "mtn_phone": phone,
        },
      );
      
      Get.back(); // close loading
      
      late final Map<String, dynamic> resMap;
      if (res is Map<String, dynamic>) {
        resMap = res;
      } else if (res is String) {
        resMap = json.decode(res) as Map<String, dynamic>;
      } else {
        throw Exception("Unexpected response type");
      }

      if (resMap['status'] == 'success') {
        Get.to(() => PaymentScreenMtn(
          invoiceNumber: resMap['invoice_number'],
          mtnNumber: resMap['mtn_payment_number'] ?? '---',
          amount: double.parse(amount),
        ));
      } else {
        Get.defaultDialog(
          title: 'Error'.tr,
          content: Text(resMap['message']?.toString() ?? 'Failed to create invoice'.tr),
        );
      }
    } catch (e) {
      if (Get.isDialogOpen ?? false) Get.back();
      Get.defaultDialog(title: 'Error'.tr, content: Text(e.toString()));
    }
  }

  Future<void> payWithClickWallet(BuildContext context, String amount, String currency) async {
    try {
      final phone = walletphoneController.text.trim();
      if (phone.isEmpty) {
        Get.defaultDialog(title: 'Error'.tr, content: Text('Please enter phone number'.tr));
        return;
      }
      
      Get.dialog(const Center(child: CircularProgressIndicator()), barrierDismissible: false);
      
      var res = await CRUD().postWalletMtn(
        link: AppLink.createCliqInvoice,
        payload: {
          "amount": amount,
          "user_id": box.read(BoxName.passengerID).toString(),
          "user_type": "passenger",
          "click_phone": phone,
        },
      );
      
      Get.back(); // close loading
      
      late final Map<String, dynamic> resMap;
      if (res is Map<String, dynamic>) {
        resMap = res;
      } else if (res is String) {
        resMap = json.decode(res) as Map<String, dynamic>;
      } else {
        throw Exception("Unexpected response type");
      }

      if (resMap['status'] == 'success') {
        Get.to(() => PaymentScreenCliq(
          invoiceNumber: resMap['invoice_number'],
          cliqAlias: resMap['cliq_alias'] ?? '---',
          amount: double.parse(amount),
        ));
      } else {
        Get.defaultDialog(
          title: 'Error'.tr,
          content: Text(resMap['message']?.toString() ?? 'Failed to create invoice'.tr),
        );
      }
    } catch (e) {
      if (Get.isDialogOpen ?? false) Get.back();
      Get.defaultDialog(title: 'Error'.tr, content: Text(e.toString()));
    }
  }

  @override
  void onInit() {
    timestamp = now.millisecondsSinceEpoch;
    if (box.read(BoxName.passengerWalletTotal) == null) {
      box.write(BoxName.passengerWalletTotal, '0');
    }
    getPassengerWallet();
    final localAuth = LocalAuthentication();
    super.onInit();
  }
}

class EcashDriverPaymentScreen extends StatefulWidget {
  final String paymentUrl;

  const EcashDriverPaymentScreen({required this.paymentUrl, Key? key})
      : super(key: key);

  @override
  State<EcashDriverPaymentScreen> createState() =>
      _EcashDriverPaymentScreenState();
}

class _EcashDriverPaymentScreenState extends State<EcashDriverPaymentScreen> {
  late final WebViewController _controller;

  @override
  void initState() {
    super.initState();
    _controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(NavigationDelegate(
        onPageFinished: (url) async {
          Log.print('Ecash Driver WebView URL Finished: $url');
          await Get.find<PaymentController>().getPassengerWallet();
          // هنا نتحقق فقط من أن المستخدم عاد إلى صفحة النجاح
          // لا حاجة لاستدعاء أي API هنا، فالـ Webhook يقوم بكل العمل
          if (url.contains("success.php")) {
            showProcessingDialog();
          }
        },
      ))
      ..loadRequest(Uri.parse(widget.paymentUrl));
  }

  // دالة لعرض رسالة "العملية قيد المعالجة"
  void showProcessingDialog() {
    showDialog(
      barrierDismissible: false,
      context: Get.context!,
      builder: (BuildContext context) {
        return AlertDialog(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(12.0),
          ),
          title: Row(
            children: [
              Icon(Icons.check_circle, color: Colors.green),
              const SizedBox(width: 8),
              Text(
                "Payment Successful".tr,
                style: TextStyle(
                  color: Colors.green,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ],
          ),
          content: Text(
            "Your payment is being processed and your wallet will be updated shortly."
                .tr,
            style: const TextStyle(fontSize: 16),
          ),
          actions: [
            TextButton(
              onPressed: () {
                // أغلق مربع الحوار، ثم أغلق شاشة الدفع
                Navigator.pop(context); // Close the dialog
                Navigator.pop(context); // Close the payment screen
              },
              style: TextButton.styleFrom(
                backgroundColor: Colors.green,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(8.0),
                ),
              ),
              child: Text(
                "OK".tr,
                style: const TextStyle(color: Colors.white),
              ),
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Complete Payment'.tr)),
      body: WebViewWidget(controller: _controller),
    );
  }
}
