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.LayoutInflater
import android.view.View
import android.view.ViewGroup
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.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.databinding.FragmentOrderPaymentBinding
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 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?) {
        orderPaymentBinding.errorView.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, getPhoneLogin()
                    )
                }

                "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))
            orderPaymentBinding.errorView.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


    private var _orderPaymentBinding: FragmentOrderPaymentBinding? = null
    private val orderPaymentBinding get() = _orderPaymentBinding!!


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

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _orderPaymentBinding = FragmentOrderPaymentBinding.inflate(inflater, container, false)
        return orderPaymentBinding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        checkCallBack = false
        paymentsAdapter = OrderPaymentsAdapter(context)
        orderPaymentBinding.recyclerViewOrderPayment.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, getPhoneLogin()
                        )
                    }

                    "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() {
        orderPaymentBinding.errorView.setViewMode(ErrorHandleView.Mode.LOADING)
        object : SeatelJSONArrayRequest(context) {

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

        }.setOnErrorListener { error ->
            when {
                error is NoConnectionError -> orderPaymentBinding.errorView.setViewMode(
                    ErrorHandleView.Mode.NO_INTERNET
                )

                error is TimeoutError -> orderPaymentBinding.errorView.setViewMode(ErrorHandleView.Mode.TIME_OUT)
                paymentsAdapter?.itemCount == 0 -> {
                    orderPaymentBinding.errorView.errorMessage =
                        "Payment cannot process right now. Please try again."
                    orderPaymentBinding.errorView.setViewMode(ErrorHandleView.Mode.NO_DATA)
                }
            }
        }.execute {
            it as JSONArray
            if (getMethodPaymentModel(it).size == 0 && paymentsAdapter?.itemCount == 0) {
                orderPaymentBinding.errorView.errorMessage =
                    "Payment cannot process right now. Please try again."
                orderPaymentBinding.errorView.setViewMode(ErrorHandleView.Mode.NO_DATA)
            } else {
                orderPaymentBinding.errorView.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
    }

}