import 'dart:convert';

import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart';
import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

enum _PAYMENT_TYPE{PACKAGES, PHARMACY, PATIENT}
var _InAppBrowserOptions = InAppBrowserClassOptions(
    inAppWebViewGroupOptions: InAppWebViewGroupOptions(crossPlatform: InAppWebViewOptions(useShouldOverrideUrlLoading: true)),
    crossPlatform: InAppBrowserOptions(hideUrlBar: true),
    ios: IOSInAppBrowserOptions(toolbarBottom: false,)
);

class MyInAppBrowser extends InAppBrowser {
  _PAYMENT_TYPE paymentType;
  static String SERVICE_URL =
      'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; // Payfort Payment Gateway URL UAT

  // static String SERVICE_URL =
  //     'https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx'; //Payfort Payment Gateway URL LIVE

  static String PREAUTH_SERVICE_URL =
      'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; // Payfort PreAuth Payment Gateway URL UAT

  // static String PREAUTH_SERVICE_URL =
  //     'https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx'; //Payfort PreAuth Payment Gateway URL Live Store

  // static String PRESCRIPTION_PAYMENT_WITH_ORDERID =
  //     'https://uat.hmgwebservices.com/epharmacy/checkout/OpcCompleteRedirectionPaymentClientbyOrder?orderID=';

  static String PRESCRIPTION_PAYMENT_WITH_ORDERID =
      'https://mdlaboratories.com/exacartapi/checkout/OpcCompleteRedirectionPaymentClientbyOrder?orderID='; //Live

  // Packages
  static String PACKAGES_REQUEST_PAYMENT_URL = '$EXA_CART_API_BASE_URL/checkout/OpcCompleteRedirectionPayment1';
  static String PACKAGES_PAYMENT_SUCCESS_URL = '$EXA_CART_API_BASE_URL/Checkout/MobilePaymentSuccess';
  static String PACKAGES_PAYMENT_FAIL_URL = '$EXA_CART_API_BASE_URL/Checkout/MobilePaymentFailed';

  static List<String> successURLS = [
    'success',
    'PayFortResponse',
    'PayFortSucess',
    'mobilepaymentcomplete'
  ];

  static List<String> errorURLS = ['PayfortCancel', 'errorpage', 'Failed'];

  final Function onExitCallback;
  final Function onLoadStartCallback;
  final BuildContext context;

  AppSharedPreferences sharedPref = AppSharedPreferences();
  AuthProvider authProvider = new AuthProvider();
  InAppBrowser browser = new InAppBrowser();

  AuthenticatedUser authUser;
  AppoitmentAllHistoryResultList appo;

  String deviceToken;

  double lat = 0.0;
  double long = 0.0;

  static bool isPaymentDone = false;

  MyInAppBrowser({this.onExitCallback, this.appo, this.onLoadStartCallback, this.context});

  Future onBrowserCreated() async {
    print("\n\nBrowser Created!\n\n");
  }

  @override
  Future onLoadStart(String url) async {
    if(onLoadStartCallback != null)
      onLoadStartCallback(url);
  }

  @override
  Future onLoadStop(String url) async {
    print("\n\nStopped $url\n\n");
  }

  @override
  void onLoadError(String url, int code, String message) {
    print("Can't load $url.. Error: $message");
  }

  @override
  void onProgressChanged(int progress) {
    print("Progress: $progress");
  }

  @override
  void onExit() {
    print("\n\nBrowser closed!\n\n");
    if(onExitCallback != null)
      onExitCallback(appo, isPaymentDone);
  }

  @override
  Future<ShouldOverrideUrlLoadingAction> shouldOverrideUrlLoading(ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async {
    var url = shouldOverrideUrlLoadingRequest.url;
    debugPrint("redirecting/overriding to: $url");

    if(paymentType == _PAYMENT_TYPE.PACKAGES && [PACKAGES_PAYMENT_SUCCESS_URL,PACKAGES_PAYMENT_FAIL_URL].contains(url)){
      isPaymentDone = (url == PACKAGES_PAYMENT_SUCCESS_URL);
      close();
    }

    return ShouldOverrideUrlLoadingAction.ALLOW;
  }

  getLanguageID() async {
    return await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
  }

  getDeviceToken() async {
    String deviceToken = await sharedPref.getString(PUSH_TOKEN);
    this.deviceToken = deviceToken;
  }

  getPatientData() async {
    if (await this.sharedPref.getObject(USER_PROFILE) != null) {
      var data = AuthenticatedUser.fromJson(
          await this.sharedPref.getObject(USER_PROFILE));
      authUser = data;
    }
    if (await this.sharedPref.getDouble(USER_LAT) != null &&
        await this.sharedPref.getDouble(USER_LONG) != null) {
      lat = await this.sharedPref.getDouble(USER_LAT);
      long = await this.sharedPref.getDouble(USER_LONG);
    }
  }

  openPackagesPaymentBrowser({@required int customer_id, @required int order_id}){
    paymentType = _PAYMENT_TYPE.PACKAGES;
    var full_url = '$PACKAGES_REQUEST_PAYMENT_URL?customer_id=$customer_id&order_id=$order_id';
    this.openUrl(url: full_url, options: _InAppBrowserOptions);
  }

  openPaymentBrowser(
      double amount,
      String orderDesc,
      String transactionID,
      String projId,
      String emailId,
      String paymentMethod,
      dynamic patientType,
      String patientName,
      dynamic patientID,
      AuthenticatedUser authenticatedUser,
      InAppBrowser browser,
      bool isLiveCareAppo,
      [var appoDate,
      var appoNo,
      var clinicID,
      var doctorID]) {
    this.browser = browser;
    getPatientData();
    generateURL(
            amount,
            orderDesc,
            transactionID,
            projId,
            emailId,
            paymentMethod,
            patientType,
            patientName,
            patientID,
            authenticatedUser,
            isLiveCareAppo,
            appoDate,
            appoNo,
            clinicID,
            doctorID)
        .then((value) {

      paymentType = _PAYMENT_TYPE.PATIENT;
      this.browser.openUrl(url: value, options: _InAppBrowserOptions);
    });
  }

  openPharmacyPaymentBrowser(
      OrderDetailModel order,
      double amount,
      String orderDesc,
      String transactionID,
      String emailId,
      String paymentMethod,
      String patientName,
      dynamic patientID,
      AuthenticatedUser authenticatedUser,
      InAppBrowser browser) {
    this.browser = browser;
    getPatientData();
    generatePharmacyURL(order, amount, orderDesc, transactionID, emailId,
            paymentMethod, patientName, patientID, authenticatedUser)
        .then((value) {
      this.browser.openUrl(url: value);
    });
  }

  openBrowser(String url) {
    this.browser = browser;
    this.browser.openUrl(url: url, options: _InAppBrowserOptions);
  }

  Future<String> generateURL(
      double amount,
      String orderDesc,
      String transactionID,
      String projId,
      String emailId,
      String paymentMethod,
      dynamic patientType,
      String patientName,
      dynamic patientID,
      AuthenticatedUser authUser,
      bool isLiveCareAppo,
      [var appoDate,
      var appoNo,
      var clinicID,
      var doctorID,
      var patientData,
      var servID,
      var LiveServID]) async {
    getDeviceToken();
    String currentLanguageID = getLanguageID() == 'ar' ? 'AR' : 'EN';
    String form = isLiveCareAppo ? getLiveCareForm() : getForm();

    form = form.replaceFirst("EMAIL_VALUE", emailId);

    form = form.replaceFirst('AMOUNT_VALUE', amount.toString());
    form = form.replaceFirst('ORDER_DESCRIPTION_VALUE', orderDesc);
    form = form.replaceFirst('ORDER_ID_VALUE', transactionID);
    form = form.replaceFirst('REQUEST_ID_VALUE', transactionID);
    form = form.replaceFirst('PROJECT_ID_VALUE', projId);
    form = form.replaceFirst('PAYMENT_OPTION_VALUE', paymentMethod);
    form = form.replaceFirst('LANG_VALUE', currentLanguageID);
    form = form.replaceFirst('PATIENT_OUT_SA',
        authUser.outSA == 0 ? false.toString() : true.toString());
    form = form.replaceFirst(
        'PATIENT_TYPE_ID', patientData == null ? patientType.toString() : "1");

    form = form.replaceFirst(
        'DEVICE_TOKEN', await sharedPref.getString(PUSH_TOKEN));
    form = form.replaceFirst('LATITUDE_VALUE', this.lat.toString());
    form = form.replaceFirst('LONGITUDE_VALUE', this.long.toString());

    if (servID == "4")
      form = form.replaceFirst(
          'SERVICE_URL_VALUE', MyInAppBrowser.PREAUTH_SERVICE_URL);
    else
      form = form.replaceFirst('SERVICE_URL_VALUE', MyInAppBrowser.SERVICE_URL);

    if (servID != null) {
      form = form.replaceFirst('SERV_ID', servID);
      form = form.replaceFirst('LIVE_SERVICE_ID', LiveServID);
    } else {
      form = form.replaceFirst('SERV_ID', "2");
      form = form.replaceFirst('LIVE_SERVICE_ID', "2");
    }

    form = form.replaceFirst('CUSTNAME_VALUE', patientName);
    form = form.replaceFirst('CUSTID_VALUE', patientID.toString());

    if (isLiveCareAppo) {
      form = form.replaceFirst('IS_SCHEDULE_VALUE', "true");
      form = form.replaceFirst('APPOINTMENT_DATE_VALUE', appoDate);
      form = form.replaceFirst('APPOINTMENT_NO_VALUE', appoNo.toString());
      form = form.replaceFirst('DOCTOR_ID_VALUE', doctorID.toString());
      form = form.replaceFirst('CLINIC_ID_VALUE', clinicID.toString());
    }

    var bytes = utf8.encode(form);
    var base64Str = base64.encode(bytes);
    print(form);
    print('data:text/html;base64,' + base64Str);
    return 'data:text/html;base64,' + base64Str;
  }

  Future<String> generatePharmacyURL(
      OrderDetailModel order,
      double amount,
      String orderDesc,
      String transactionID,
      String emailId,
      String paymentMethod,
      String patientName,
      dynamic patientID,
      AuthenticatedUser authUser) async {
    String pharmacyURL = PRESCRIPTION_PAYMENT_WITH_ORDERID +
        order.orderGuid +
        '&&CustomerId=' +
        "${order.customerId}";
    print(pharmacyURL);
    return pharmacyURL;
  }

  String getForm() {
    return '<html> ' +
        '<head></head>' +
        '<body>' +
        '<form id="paymentForm" action="SERVICE_URL_VALUE" method="post">' +
        '<input type="hidden" name="Amount" value="AMOUNT_VALUE">' +
        '<input type="hidden" name="ProjID" value="PROJECT_ID_VALUE">' +
        '<input type="hidden" name="Order_Desc" value="ORDER_DESCRIPTION_VALUE">' +
        '<input type="hidden" name="OrderID" value="ORDER_ID_VALUE">' +
        // '<input type="hidden" name="reqID" value="REQUEST_ID_VALUE">' +
        '<input type="hidden" name="PaymentOption" value="PAYMENT_OPTION_VALUE">' +
        '<input type="hidden" name="Email" value="EMAIL_VALUE">' +
        '<input type="hidden" name="ServID" value="SERV_ID"  >' +
        '<input type="hidden" name="ChannelID" value="2"  >' +
        '<input type="hidden" name="Lang" value="LANG_VALUE"  >' +
        '<input type="hidden" name="ReturnURL" value=""  >' +
        '<input type="hidden" name="CustName" value="CUSTNAME_VALUE" >' +
        '<input type="hidden" name="PatientOutSA" value="PATIENT_OUT_SA" >' +
        '<input type="hidden" name="PatientTypeID" value="PATIENT_TYPE_ID" >' +
        '<input type="hidden" name="DeviceToken" value="DEVICE_TOKEN" >' +
        '<input type="hidden" name="Longitude" value="LONGITUDE_VALUE" >' +
        '<input type="hidden" name="Latitude" value="LATITUDE_VALUE" >' +
        '<input type="hidden" name="Live_ServiceID" value="LIVE_SERVICE_ID" >' +
        '<input type="hidden" name="CustID" value="CUSTID_VALUE"  >' +
        '<input type="hidden" name="ResponseContinueURL" value="http://hmg.com/Documents/success.html" >' +
        '<input type="hidden" name="BackClickUrl" value="http://hmg.com/Documents/success.html" >' +
        '</form>' +
        '<script type="text/javascript"> document.getElementById("paymentForm").submit(); </script>' +
        '</body>' +
        '</html>';
  }

  String getLiveCareForm() {
    return '<html> ' +
        '<head></head>' +
        '<body>' +
        '<form id="paymentForm" action="SERVICE_URL_VALUE" method="post">' +
        '<input type="hidden" name="Amount" value="AMOUNT_VALUE">' +
        '<input type="hidden" name="ProjID" value="PROJECT_ID_VALUE">' +
        '<input type="hidden" name="IsSchedule" value="IS_SCHEDULE_VALUE">' +
        '<input type="hidden" name="AppointmentDate" value="APPOINTMENT_DATE_VALUE">' +
        '<input type="hidden" name="AppointmentNo" value="APPOINTMENT_NO_VALUE">' +
        '<input type="hidden" name="DoctorID" value="DOCTOR_ID_VALUE">' +
        '<input type="hidden" name="ClinicID" value="CLINIC_ID_VALUE">' +
        '<input type="hidden" name="Order_Desc" value="ORDER_DESCRIPTION_VALUE">' +
        '<input type="hidden" name="OrderID" value="ORDER_ID_VALUE">' +
        '<input type="hidden" name="PaymentOption" value="PAYMENT_OPTION_VALUE">' +
        '<input type="hidden" name="Email" value="EMAIL_VALUE">' +
        '<input type="hidden" name="ServID" value="SERV_ID"  >' +
        '<input type="hidden" name="ChannelID" value="2"  >' +
        '<input type="hidden" name="Lang" value="LANG_VALUE"  >' +
        '<input type="hidden" name="ReturnURL" value=""  >' +
        '<input type="hidden" name="CustName" value="CUSTNAME_VALUE" >' +
        '<input type="hidden" name="PatientOutSA" value="PATIENT_OUT_SA" >' +
        '<input type="hidden" name="PatientTypeID" value="PATIENT_TYPE_ID" >' +
        '<input type="hidden" name="DeviceToken" value="DEVICE_TOKEN" >' +
        '<input type="hidden" name="Longitude" value="LONGITUDE_VALUE" >' +
        '<input type="hidden" name="Latitude" value="LATITUDE_VALUE" >' +
        '<input type="hidden" name="Live_ServiceID" value="LIVE_SERVICE_ID" >' +
        '<input type="hidden" name="CustID" value="CUSTID_VALUE"  >' +
        '<input type="hidden" name="ResponseContinueURL" value="http://hmg.com/Documents/success.html" >' +
        '<input type="hidden" name="BackClickUrl" value="http://hmg.com/Documents/success.html" >' +
        '</form>' +
        '<script type="text/javascript"> document.getElementById("paymentForm").submit(); </script>' +
        '</body>' +
        '</html>';
  }
}

class MyChromeSafariBrowser extends ChromeSafariBrowser {
  MyChromeSafariBrowser(browserFallback) : super(bFallback: browserFallback);

  @override
  void onOpened() {
    print("ChromeSafari browser opened");
  }

  @override
  void onCompletedInitialLoad() {
    print("ChromeSafari browser initial load completed");
  }

  @override
  void onClosed() {
    print("ChromeSafari browser closed");
  }
}