package com.seatel.mobilehall.ui.home.fragment

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.View
import com.android.volley.NoConnectionError
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.TimeoutError
import com.google.gson.Gson
import com.seatel.mobilehall.BuildConfig
import com.seatel.mobilehall.R
import com.seatel.mobilehall.data.network.SeatelJSONArrayRequest
import com.seatel.mobilehall.data.network.SeatelJSONObjectRequest
import com.seatel.mobilehall.data.network.SeatelSuperRequest
import com.seatel.mobilehall.data.prefs.ProfileSharedPreference
import com.seatel.mobilehall.data.prefs.SeatelSharePreferences
import com.seatel.mobilehall.ui.base.fragment.BaseFragment
import com.seatel.mobilehall.ui.home.activity.AliPayMpayPaymentActivity
import com.seatel.mobilehall.ui.home.activity.OrderPaymentSuccessActivity
import com.seatel.mobilehall.ui.home.activity.WingPaymentActivity
import com.seatel.mobilehall.ui.home.adapter.OrderPaymentsAdapter
import com.seatel.mobilehall.ui.home.model.AbaFormModel
import com.seatel.mobilehall.ui.home.model.PaymentMethodModel
import com.seatel.mobilehall.ui.login.model.UploadImageResponse
import com.seatel.mobilehall.util.Constant
import com.seatel.mobilehall.util.MultipartEntityRequest
import com.seatel.mobilehall.util.SeatelAlertDialog
import com.seatel.mobilehall.util.customview.ErrorHandleView
import com.seatel.mobilehall.util.manager.OrderProfileSingleton
import com.seatel.mobilehall.util.manager.OrderingManager
import kotlinx.android.synthetic.main.fragment_order_payment.error_view
import kotlinx.android.synthetic.main.fragment_order_payment.recycler_view_order_payment
import org.json.JSONArray
import org.json.JSONObject
import java.io.File
import java.util.Locale

class OrderPaymentFragment : BaseFragment(), OrderPaymentsAdapter.OrderPaymentItemClick,
    Response.Listener<JSONObject> {

    override fun onResponse(response: JSONObject?) {
        error_view.visibility = View.GONE
        if (response?.optString("remark")?.isNotEmpty()!!
            && response.optInt("orderId") > 0 && !OrderingManager.getInstance().buyTopUpCard
        ) {
            uploadImage(response.optInt("orderId"))
        }

        amount = String.format(
            Locale.US,
            "%.2f",
            OrderingManager.getInstance().totalSelectedPriceWithInsurance
        ).toDouble()
        remark = response?.optString("remark")

        OrderingManager.getInstance().orderId = remark?.split("\\|")!![0]

        if (response.has("promotions")) {
            val promotions = response.optJSONArray("promotions")
            for (i in 0 until promotions.length()) {
                if (promotions.optJSONObject(i)
                        .optString("code") == Constant.PROMOTION_CODE_VALENTINE_DAY
                ) {
                    isShowValentineDayPromotion = true
                    break
                } else {
                    isShowValentineDayPromotion = false
                }
            }
        }
        if (OrderingManager.getInstance().buyTopUpCard) {
            when (OrderingManager.getInstance().paymentMethod.toLowerCase()) {
                "wing" -> {
                    checkCallBack = false
                    WingPaymentActivity.lunch(
                        getmContext(),
                        "${Constant.URL_WING_PAYMENT}amount=$amount&remark=$remark",
                        amount,
                        false,
                        isShowValentineDayPromotion
                    )
                }
                "mpay", "alipay" -> {
                    checkCallBack = false
                    AliPayMpayPaymentActivity.lunch(
                        getmContext(),
                        "${BuildConfig.BASE_URL}${OrderingManager.getInstance().paymentMethod.toLowerCase()}/form?amount=$amount&remark=$remark",
                        amount,
                        OrderingManager.getInstance().paymentMethod,
                        isShowValentineDayPromotion
                    )
                }
                "aba" -> {
                    abaPayway(amount, remark)
                }
            }
        }
    }

    private fun uploadImage(orderId: Int) {
        val orderProfile =
            OrderProfileSingleton.getInstance(requireContext())

        if (orderProfile?.getFrontIdImageUrl() != null) {
            upload(Response.Listener {
                imageFrontFileName = getUploadResponseModel(it).data[0].filename
                postOrders(orderId)
            }, orderProfile.getFrontIdImageUrl())
        }

        if (orderProfile?.getBackIdImageUrl() != null) {
            upload(Response.Listener {
                imageBackFileName = getUploadResponseModel(it).data[0].filename
            }, orderProfile.getBackIdImageUrl())
        }

        if (orderProfile?.getPhoto() != null) {
            upload(Response.Listener {
                imageUserFileName = getUploadResponseModel(it).data[0].filename
            }, orderProfile.getPhoto())
        }
    }


    private fun getUploadResponseModel(data: String): UploadImageResponse {

        return Gson().fromJson(data, UploadImageResponse::class.java)
    }

    private fun upload(response: Response.Listener<String>, file: File) {
        val multi = MultipartEntityRequest.with(context).setType(Constant.ANY).setFile(file)
        multi.setOnErrorListener {
            if (it.networkResponse.statusCode == 413) {
                SeatelAlertDialog.with(requireContext(), "Request Entity Too Large")
                    .show()
            }
            /*SeatelAlertDialog.with(this, "Please check your internet connection and try again!")
                .show()*/
        }

        multi.upLoadImage(response)
    }


    override fun onClick(data: PaymentMethodModel) {
        if (checkOrderPriceOver1K(data.paymentName))
            error_view.setViewMode(ErrorHandleView.Mode.LOADING)
        OrderingManager.getInstance().executeOrderPayment(context, data.paymentName, this)
    }

    private fun checkOrderPriceOver1K(paymentName: String): Boolean {
        when (paymentName.toLowerCase()) {
            "mpay", "alipay" -> {
                if (OrderingManager.getInstance().totalSelectedPriceWithInsurance > 1000.00) {
                    SeatelAlertDialog.with(
                        requireContext(),
                        "Sorry, this payment method amount limit is at 1000$."
                    ).show()
                    return false
                }
            }
        }
        return true
    }

    private var paymentsAdapter: OrderPaymentsAdapter? = null
    private var imageFrontFileName = ""
    private var imageBackFileName = ""
    private var imageUserFileName = ""
    var isShowValentineDayPromotion = false
    var amount = 0.0
    var remark = ""
    private var return_params: String = ""
    private var tran_id: String = ""
    private var checkCallBack = false

    override fun onAttach(context: Context) {
        super.onAttach(context)
        setmContext(context)
        setFragmentLayout(R.layout.fragment_order_payment)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        checkCallBack = false
        paymentsAdapter = OrderPaymentsAdapter(context)
        recycler_view_order_payment.adapter = paymentsAdapter
        // recycler_view_order_payment.layoutManager = GridLayoutManager(context, 2)
        paymentsAdapter?.setOrderPaymentItemClick(this)

        getPaymentMethod()
    }

    private fun postOrders(orderId: Int) {
        object : SeatelJSONObjectRequest(context) {
            override fun getFunctionName(): String {
                return Constant.ORDER
            }

            override fun getMethod(): Int {
                return Request.Method.PUT
            }

            override fun onGetBodyRequest(): String {
                val jsonObject = JSONObject()
                jsonObject.put("orderIds", orderId)

                val profile = JSONObject()
                profile.put("certName",ProfileSharedPreference.getInstance(context)?.getDocumentType())
                profile.put(
                    "idCardNumber",ProfileSharedPreference.getInstance(context)?.getId()
                )
                profile.put("name",ProfileSharedPreference.getInstance(context)?.getName())
                profile.put("gender", ProfileSharedPreference.getInstance(context)?.getGender())
                profile.put("dateOfBirth", ProfileSharedPreference.getInstance(context)?.getDob())

                profile.put("frontIDPhotoUrl", imageFrontFileName)
                profile.put("backIDPhotoUrl", imageBackFileName)
                profile.put("photoUrl", imageUserFileName)

                jsonObject.put("profile", profile)
                return jsonObject.toString()
            }

        }.setOnErrorListener {
            SeatelAlertDialog.with(requireContext(), SeatelSuperRequest.getErrorMessageFrom(it))
                .show()
        }.execute {
            val response = it as JSONObject
            val message = response.optString("message")

            if (message == "OK") {
                when (OrderingManager.getInstance().paymentMethod.toLowerCase()) {
                    "wing" -> {
                        checkCallBack = false
                        WingPaymentActivity.lunch(
                            getmContext(),
                            "${Constant.URL_WING_PAYMENT}amount=$amount&remark=$remark",
                            amount,
                            false,
                            isShowValentineDayPromotion
                        )
                    }
                    "mpay", "alipay" -> {
                        checkCallBack = false
                        AliPayMpayPaymentActivity.lunch(
                            getmContext(),
                            "${BuildConfig.BASE_URL}${OrderingManager.getInstance().paymentMethod.toLowerCase()}/form?amount=$amount&remark=$remark",
                            amount,
                            OrderingManager.getInstance().paymentMethod,
                            isShowValentineDayPromotion
                        )
                    }
                    "aba" -> {
                        abaPayway(amount, remark)
                    }

                    /*AliPayMpayPaymentActivity.lunch(



                            getmContext(),
                            "${Constant.URL_ABA_PAYMENT}amount=$amount&remark=$remark${OrderingManager.getInstance().urlAddForABA}",
                            amount,
                            "ABA payway", isShowValentineDayPromotion, true
                        )*/
                }
            }


        }
    }


    override fun onResume() {
        super.onResume()
        val action: String? = activity?.intent?.action
        val data: Uri? = activity?.intent?.data
        Log.d("TAG::>>>", "incomingLink: $action $data ")
        if (checkCallBack)
            getAbaCallBack()
    }

    private fun getAbaCallBack() {
        object : SeatelJSONObjectRequest(context) {
            override fun getFunctionName(): String {
                return "aba/callback"
            }

            override fun onGetBodyRequest(): String {

                val obj = JSONObject()
                obj.put("tran_id", tran_id)
                obj.put("status", "0")
                obj.put("return_params", return_params)

                return obj.toString()
            }

            override fun getMethod(): Int {
                return Request.Method.POST
            }

        }.setOnErrorListener {
            SeatelAlertDialog.with(requireContext(), SeatelSuperRequest.getErrorMessageFrom(it))
                .show()
        }.execute {
            val message = (it as JSONObject).optString("message")
            val status = it.optString("status")
            if (status.equals("pending")) {
                SeatelAlertDialog.with(requireContext(), message).show()
            }
            if (status.equals("ok")) {
                OrderPaymentSuccessActivity.launch(
                    requireContext(), OrderingManager.getInstance().getOrderId().split("|")[0],
                    SeatelSharePreferences.getInstance(requireContext())?.getNoneSeatelNumber()!!
                )
                activity?.finish()
            }
        }
    }

    private fun abaPayway(amount: Double, remark: String) {
        object : SeatelJSONObjectRequest(context) {
            override fun getFunctionName(): String {
                return "aba/form?amount=$amount&remark=$remark|top-up&option=abapay_deeplink"
            }

            override fun getMethod(): Int {
                return Request.Method.GET
            }


        }.setOnErrorListener {
            SeatelAlertDialog.with(requireContext(), SeatelSuperRequest.getErrorMessageFrom(it))
                .show()
        }.execute {
            val response = it as JSONObject
            val gson = Gson().fromJson(response.toString(), AbaFormModel::class.java)
            tran_id = gson.status.tran_id
            return_params = remark
            openDeepLink(gson.abapay_deeplink)
        }

    }


    private fun openDeepLink(qrString: String) {
        val ABA_SCHEME = "abamobilebank"
        val ABA_DOMAIN = "ababank.com"
        checkCallBack = true
        try {
            val url = qrString
            /*val url =
                "${ABA_SCHEME}://${ABA_DOMAIN}?type=payway&qrcode=${qrString}" // value from "abapay_deeplink"*/
            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
            startActivity(intent)
        } catch (ex: Exception) {
            gotoPlayStore()
            /* val intent: Intent = Intent(Intent.ACTION_VIEW).apply {
                 //  intent.data = Uri.parse("market://details?id=com.paygo24.ibank")
                 data = Uri.parse("https://play.google.com/store/apps/details?id=com.paygo24.ibank")
             }
             startActivity(intent)*/
        }
    }

    private fun gotoPlayStore() {
        try {
            startActivity(
                Intent(
                    Intent.ACTION_VIEW,
                    Uri.parse("market://details?id=com.paygo24.ibank")
                )
            )
        } catch (obj: android.content.ActivityNotFoundException) {
            startActivity(
                Intent(
                    Intent.ACTION_VIEW,
                    Uri.parse("https://play.google.com/store/apps/details?id=com.paygo24.ibank")
                )
            )
        }

    }

    private fun getPaymentMethod() {
        error_view.setViewMode(ErrorHandleView.Mode.LOADING)
        object : SeatelJSONArrayRequest(context) {

            override fun getFunctionName(): String {
                return Constant.PAYMENT_METHODS
            }

        }.setOnErrorListener { error ->
            when {
                error is NoConnectionError -> error_view.setViewMode(ErrorHandleView.Mode.NO_INTERNET)
                error is TimeoutError -> error_view.setViewMode(ErrorHandleView.Mode.TIME_OUT)
                paymentsAdapter?.itemCount == 0 -> {
                    error_view.errorMessage = "Payment cannot process right now. Please try again."
                    error_view.setViewMode(ErrorHandleView.Mode.NO_DATA)
                }
            }
        }.execute {
            it as JSONArray
            if (getMethodPaymentModel(it).size == 0 && paymentsAdapter?.itemCount == 0) {
                error_view.errorMessage = "Payment cannot process right now. Please try again."
                error_view.setViewMode(ErrorHandleView.Mode.NO_DATA)
            } else {
                error_view.visibility = View.GONE
            }
            paymentsAdapter?.setDataMethod(getMethodPaymentModel(it))
        }
    }

    private fun getMethodPaymentModel(response: JSONArray): ArrayList<PaymentMethodModel> {
        val methodDataModels: ArrayList<PaymentMethodModel> = ArrayList()

        for (i in 0 until response.length()) {
            val payment = PaymentMethodModel()
            payment.paymentName = response.optJSONObject(i).optString("name")
            payment.paymentIcon = response.optJSONObject(i).optString("icon")
            payment.description = response.optJSONObject(i).optString("description")
            payment.title = response.optJSONObject(i).optString("title")
            methodDataModels.add(payment)
            /*   if (!(TextUtils.isEmpty(paymentName))) {

                   when (paymentName.toLowerCase()) {
                       Constant.PaymentMethodList.WING -> {
                           methodDataModels.add(PaymentMethodModel(paymentName, response.optJSONObject(i).optString("_id"), R.drawable.ic_wing))
                       }
                       Constant.PaymentMethodList.M_PAY -> {
                           methodDataModels.add(PaymentMethodModel(paymentName, response.optJSONObject(i).optString("_id"), R.drawable.ic_mpay_blue))
                       }
                       Constant.PaymentMethodList.ALI_PAY -> {
                           methodDataModels.add(PaymentMethodModel(paymentName, response.optJSONObject(i).optString("_id"), R.drawable.ic_alipay))
                       }
                       Constant.PaymentMethodList.ABA -> {
                           methodDataModels.add(PaymentMethodModel(paymentName, response.optJSONObject(i).optString("_id"), R.drawable.ic_aba_pay))
                       }
                   }
               }*/
        }
        return methodDataModels
    }

}