package com.seatel.mobilehall.util.view

import android.Manifest
import android.app.Activity
import android.app.DatePickerDialog
import android.app.Dialog
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.text.TextUtils
import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.Window
import android.view.WindowManager
import android.widget.Button
import android.widget.DatePicker
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import com.bumptech.glide.Glide
import com.seatel.mobilehall.BuildConfig
import com.seatel.mobilehall.R
import com.seatel.mobilehall.data.network.SeatelJSONArrayRequest
import com.seatel.mobilehall.databinding.ViewActivateBuySimBinding
import com.seatel.mobilehall.ui.base.activity.BaseActivity
import com.seatel.mobilehall.ui.login.model.ProfileModel
import com.seatel.mobilehall.util.Constant
import com.seatel.mobilehall.util.PermissionUtil
import com.seatel.mobilehall.util.SeatelAlertDialog
import com.seatel.mobilehall.util.SeatelUtils
import com.seatel.mobilehall.util.customview.BottomChooserDialog
import com.seatel.mobilehall.util.manager.OrderingManager
import org.json.JSONArray
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale

@RequiresApi(Build.VERSION_CODES.HONEYCOMB)
@Suppress("RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
class ActivateBuySimView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    isSimProfle: Boolean = false
) : LinearLayout(context, attrs, defStyleAttr), View.OnClickListener,
    DatePickerDialog.OnDateSetListener {

    private lateinit var binding: ViewActivateBuySimBinding
    private var certificateModel = ArrayList<BottomChooserDialog.BottomChooserModel>()
    private val calendar = Calendar.getInstance()
    private var imageType = ""
    var mOutputFileBack: File? = null
    var mOutputFileFront: File? = null
    var mOutputFileUser: File? = null
    var mImageCaptureUri: Uri? = null
    private var profile: ProfileModel? = null
    var dateOfBirth = "" //this use for post data to server
    private var idCertificationType = 0
    private var mGenderKeyPost = ""
    private var mCertificationNamePost: String? = ""
    private var mPhotoRequest: PermissionUtil.PermissionRequestObject? = null
    private var isUpdateSimProfile: Boolean = false

    fun getIdCertType(): Int {
        return idCertificationType
    }

    fun getGenderKeyPost(): String {
        return mGenderKeyPost.lowercase(Locale.getDefault())
    }

    fun getCertificationNamePost(): String? {
        return mCertificationNamePost
    }


    override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
        calendar.set(Calendar.YEAR, year)
        calendar.set(Calendar.MONTH, month)
        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
        val sdf = SimpleDateFormat("dd MMM yyyy", Locale.US)

        dateOfBirth = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US).format(calendar.time)

        try {
            binding.tvDate.text = sdf.format(calendar.time).split(" ")[0]
            binding.tvMonth.text = sdf.format(calendar.time).split(" ")[1]
            binding.tvYear.text = sdf.format(calendar.time).split(" ")[2]
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun onScanIdCardResult(data: Intent) {

        val fullName =
            data.getStringExtra(Constant.MRZ_FIRST_NAME) + " " + data.getStringExtra(Constant.MRZ_LAST_NAME)
        binding.editTextName.setText(fullName)

//        //Date Of birth profile
        val dateOfBirthMRZ = data.getStringExtra(Constant.MRZ_DOB)?.split(" ")
        if (dateOfBirthMRZ?.size!! > 5) {
            val newDate = SimpleDateFormat(
                "dd MMM yyyy",
                Locale.US
            ).parse("${dateOfBirthMRZ[2]} ${dateOfBirthMRZ[1]} ${dateOfBirthMRZ[5]}")
            calendar.time = newDate
            dateOfBirth =
                SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US).format(calendar.time)

            try {
                binding.tvDate.text = "${dateOfBirthMRZ[2]}"
                binding.tvMonth.text = "${dateOfBirthMRZ[1]}"
                binding.tvYear.text = "${dateOfBirthMRZ[5]}"
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        if (data.getStringExtra(Constant.MRZ_GENDER) == "M") {
            binding.tvSex.text = "Male"
            mGenderKeyPost = "male"
        } else {
            binding.tvSex.text = "Female"
            mGenderKeyPost = "female"
        }

        getIdType(data.getStringExtra(Constant.MRZ_DOCUMENT_TYPE).toString())
        binding.editTextCardNumber.setText(data.getStringExtra(Constant.MRZ_ID))
    }

    private fun updatedDocTypeSelected(data: BottomChooserDialog.BottomChooserModel) {
        binding.tvIdType.text = data.name
        mCertificationNamePost = data.name
        idCertificationType = data.id
        binding.editTextCardNumber.isEnabled = true
    }

    override fun onClick(p0: View?) {
        when (p0?.id) {
            R.id.tv_month, R.id.tv_date, R.id.tv_year ->
                showCalendar()

            R.id.tv_id_type ->
                getIdType()

            R.id.tv_sex ->
                showChooserDialog(getSex(), binding.tvSex)

            R.id.layout_upload_front -> {
                imageType = "front"
                chooseImage()
            }

            R.id.layout_upload_back -> {
                imageType = "back"
                chooseImage()
            }

            R.id.layout_upload_user -> {
                imageType = "user"
                chooseImage()
            }

            R.id.btn_scan -> {
                showPermissionCamera()
            }
        }
    }

    private fun showPermissionCamera() {
        val mActivity = context as AppCompatActivity
        mPhotoRequest = PermissionUtil.with(mActivity).request(Manifest.permission.CAMERA)
            .onAllGranted(object : PermissionUtil.Func() {
                override fun call() {
                    //  ScanMRZActivity.launchForResult(context)
                }

            }).onAnyDenied(object : PermissionUtil.Func() {
                override fun call() {
                    Toast.makeText(
                        context,
                        "Camera permission is needed to open camera.",
                        Toast.LENGTH_LONG
                    ).show()
                }
            }).askPermission(999)
    }

    private fun chooseImage() {
        val dialog = Dialog(context)
        val view = LayoutInflater.from(context).inflate(R.layout.dialog_choose_image, null)
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog.setContentView(view)
        if (dialog.window != null) {
            dialog.window!!.setDimAmount(0.5f)
            dialog.window!!.setLayout(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.WRAP_CONTENT
            )
            dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            dialog.window!!.setGravity(Gravity.BOTTOM)
            dialog.window!!.attributes.windowAnimations = R.style.DialogAnimationSlideUpDown
        }
        view.findViewById<Button>(R.id.button_cancel).setOnClickListener {
            dialog.dismiss()
        }
        view.findViewById<LinearLayout>(R.id.parent_camera).setOnClickListener {
            openCamera()
            dialog.dismiss()
        }
        view.findViewById<LinearLayout>(R.id.parent_gallery).setOnClickListener {
            openGallery()
            dialog.dismiss()
        }
        dialog.show()
    }

    private fun openCamera() {
        if (ContextCompat.checkSelfPermission(
                context,
                Manifest.permission.CAMERA
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(
                context as Activity,
                arrayOf(Manifest.permission.CAMERA),
                Constant.REQUEST_CAMERA
            )
        } else {
            val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
            val timeStamp = SimpleDateFormat("yyyyMMDD_HHmmss", Locale.getDefault()).format(Date())
            val imageFileName = "IMG_$timeStamp.jpg"
            try {
                val mFile = File.createTempFile(
                    "IMG_$timeStamp",
                    ".jpg",
                    context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
                )
                mImageCaptureUri = FileProvider.getUriForFile(
                    context,
                    BuildConfig.APPLICATION_ID + ".provider",
                    mFile
                )
                intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri)
                intent.putExtra("listPhotoName", imageFileName)
                (context as Activity).startActivityForResult(intent, Constant.REQUEST_TAKE_PHOTO)
            } catch (e: IOException) {
                e.printStackTrace()
            }

        }
    }

    private fun openGallery() {
        if (ContextCompat.checkSelfPermission(
                context,
                Manifest.permission.READ_EXTERNAL_STORAGE
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(
                context as Activity,
                arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                Constant.REQUEST_GELLARY
            )
        } else {
            val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
            (context as Activity).startActivityForResult(intent, Constant.REQUEST_LOAD_PHOTO)
        }
    }

    fun doCrop(requestCode: Int) {
        try {
            val mOutputFile = File.createTempFile(
                "crop_" + Calendar.getInstance().timeInMillis + "_",
                ".jpg",
                context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
            )
            val mImageCropUri = FileProvider.getUriForFile(
                context,
                BuildConfig.APPLICATION_ID + ".provider",
                mOutputFile
            )
            when (imageType) {
                "front" -> mOutputFileFront = mOutputFile
                "back" -> mOutputFileBack = mOutputFile
                else -> mOutputFileUser = mOutputFile
            }

            val intent = Intent("com.android.camera.action.CROP")
            intent.setDataAndType(mImageCaptureUri, "image/*")
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
            intent.putExtra("scale", true)
            intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCropUri)
//            if (imageType == "user") {
//                intent.putExtra("aspectX", 2)
//                intent.putExtra("aspectY", 1)
//            }
            val resInfoList = context.packageManager.queryIntentActivities(intent, 0)
            if (resInfoList.size == 0) {
                SeatelAlertDialog.with(context, "PHOTO CROPPING IS INDEED NOT SUPPORTED.").show()
            }
            for (i in resInfoList.indices) {
                if (resInfoList[i] != null) {
                    val packageName = resInfoList[i].activityInfo.packageName
                    if ("com.google.android.apps.photos" == packageName) {
                        intent.component =
                            ComponentName(packageName, resInfoList[i].activityInfo.name)
                    }
                    context.grantUriPermission(
                        packageName,
                        mImageCropUri,
                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
                    )
                }
            }
            (context as Activity).startActivityForResult(intent, requestCode)
        } catch (e: IOException) {
            e.printStackTrace()
        }

    }

    private fun getSex(): ArrayList<BottomChooserDialog.BottomChooserModel> {
        val sex = ArrayList<BottomChooserDialog.BottomChooserModel>()
        sex.add(BottomChooserDialog.BottomChooserModel(0, "Male"))
        sex.add(BottomChooserDialog.BottomChooserModel(0, "Female"))
        return sex
    }

    private fun showCalendar() {
        DatePickerDialog(
            context, this, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
            calendar.get(Calendar.DAY_OF_MONTH)
        ).show()
    }

    fun displayForUpdateSimNoneSeatelUser() {
        binding.tvIdType.text = ""
        binding.editTextCardNumber.setText("")
        binding.editTextCardNumber.isEnabled = false

        binding.radioGroupSelect.visibility = View.GONE
        binding.radioButtonCurrentInfo.isChecked = false
    }

    fun displayForUpdateSimProfile() {
        binding.mainView.setBackgroundColor(Color.parseColor("#ffffff"))
        binding.viewSubMain.setBackgroundColor(Color.parseColor("#ffffff"))
        binding.tvIdType.text = ""
        binding.editTextCardNumber.setText("")
        binding.editTextCardNumber.isEnabled = false


        binding.editTextName.visibility = View.VISIBLE
        binding.titleNote.visibility = View.GONE
        binding.radioGroupSelect.visibility = View.GONE
        binding.viewDob.visibility = View.GONE
        binding.titleYourPhoto.visibility = View.VISIBLE
        binding.viewBlockProfile.visibility = View.VISIBLE
//        Glide.with(context).load("")
//                .dontAnimate()
//                .into(binding.imageViewUser)
        binding.imageViewUser.visibility = View.INVISIBLE
    }

    init {

        binding = ViewActivateBuySimBinding.inflate(LayoutInflater.from(context), this, true)


        // LayoutInflater.from(getContext()).inflate(R.layout.view_activate_buy_sim, this)

        binding.radioButtonNewId.text =
            SeatelUtils.translatForDialog(getContext(), "Register new ID")
        binding.radioButtonCurrentInfo.text =
            SeatelUtils.translatForDialog(getContext(), "Use my current info")
        binding.tvIdType.hint = SeatelUtils.translatForDialog(getContext(), "Document Type")
        binding.tvSex.hint = SeatelUtils.translatForDialog(getContext(), "Gender")
        binding.editTextCardNumber.hint = SeatelUtils.translatForDialog(getContext(), "ID#")
        binding.editTextName.hint = SeatelUtils.translatForDialog(getContext(), "Name")
        binding.tvDate.hint = SeatelUtils.translatForDialog(getContext(), "Day")
        binding.tvMonth.hint = SeatelUtils.translatForDialog(getContext(), "Month")
        binding.tvYear.hint = SeatelUtils.translatForDialog(getContext(), "Year")

        binding.tvDate.setOnClickListener(this)
        binding.tvMonth.setOnClickListener(this)
        binding.tvYear.setOnClickListener(this)
        binding.tvSex.setOnClickListener(this)
        binding.tvSex.setOnClickListener(this)
        binding.tvIdType.setOnClickListener(this)
        binding.btnScan.setOnClickListener(this)
        binding.layoutUploadFront.setOnClickListener(this)
        binding.layoutUploadBack.setOnClickListener(this)
        binding.layoutUploadUser.setOnClickListener(this)

        binding.frameCurrentInfo.setOnClickListener {
            if (OrderingManager.getInstance().getPhoneNumber(context).startsWith("018") ||
                OrderingManager.getInstance().getPhoneNumber(context).startsWith("18") ||
                OrderingManager.getInstance().getPhoneNumber(context).startsWith("85518")
            ) {
                binding.radioButtonCurrentInfo.isChecked = true
                binding.radioButtonNewId.isChecked = false
                changeInfo()
            } else {
                SeatelAlertDialog.with(
                    context,
                    context.getString(R.string.message_register_sim_none_seatel)
                ).show()
            }
        }

        binding.frameNewInfo.setOnClickListener {
            binding.radioButtonNewId.isChecked = true
            binding.radioButtonCurrentInfo.isChecked = false
            changeInfo()
        }
//        binding.radioButtonCurrentInfo.setOnCheckedChangeListener { buttonView, isChecked ->
//            //check non seatel user can't use current info
//
//        }
//        binding.radioButtonNewId.setOnCheckedChangeListener { buttonView, isChecked ->
//            buttonView.setTextColor(if (isChecked) ContextCompat.getColor(context, R.color.colorPrimary) else ContextCompat.getColor(context, R.color.colorGray))
//            changeInfo()
//        }

        profile = (getContext() as BaseActivity<*>).getProfile()
        if (profile != null) {
            binding.tvIdType.text = profile?.certType
            if (profile?.certType != null)
                mCertificationNamePost = profile?.certType!!
            binding.editTextCardNumber.setText(profile?.certNumber)
            if (binding.editTextCardNumber.text.isNotEmpty())
                binding.editTextCardNumber.isEnabled = true
            if (!TextUtils.isEmpty(profile?.imageUrl) && !isSimProfle) {
                binding.imageViewUser.visibility = View.VISIBLE
                Glide.with(context).load(profile?.imageUrl)
                    .dontAnimate()
                    .into(binding.imageViewUser)
            }
        }
    }

    private fun changeInfo() {
        if (binding.radioButtonCurrentInfo.isChecked) {
            binding.radioButtonCurrentInfo.setTextColor(
                ContextCompat.getColor(
                    context,
                    R.color.colorPrimary
                )
            )
            binding.radioButtonNewId.setTextColor(
                ContextCompat.getColor(
                    context,
                    R.color.colorGray
                )
            )
            binding.tvIdType.text = profile?.certType
            binding.editTextName.setText(profile?.custName)
            binding.editTextCardNumber.setText(profile?.certNumber)
            if (!TextUtils.isEmpty(profile?.imageUrl)) {
                binding.imageViewUser.visibility = View.VISIBLE
                Glide.with(context).load(profile?.imageUrl).dontAnimate()
                    .into(binding.imageViewUser)
            }

            binding.tvIdType.setOnClickListener(null)
            binding.editTextCardNumber.isEnabled = !binding.editTextCardNumber.text.isEmpty()

            binding.frameNewInfo.setBackgroundResource(R.drawable.bg_info_unselected)
            binding.frameCurrentInfo.setBackgroundResource(0)
        } else {
            binding.radioButtonNewId.setTextColor(
                ContextCompat.getColor(
                    context,
                    R.color.colorPrimary
                )
            )
            binding.radioButtonCurrentInfo.setTextColor(
                ContextCompat.getColor(
                    context,
                    R.color.colorGray
                )
            )
            binding.tvIdType.text = ""
            binding.editTextCardNumber.setText("")
            binding.imageViewUser.visibility = View.GONE

            binding.tvIdType.setOnClickListener(this)
            binding.editTextCardNumber.isEnabled = false
            binding.editTextName.setText("")
            binding.tvDate.text = ""
            binding.tvMonth.text = ""
            binding.tvYear.text = ""
            binding.tvSex.text = ""

            binding.frameCurrentInfo.setBackgroundResource(R.drawable.bg_info_unselected)
            binding.frameNewInfo.setBackgroundResource(0)
        }
    }

    private fun getIdType(typeIDScan: String = "") {
        if (certificateModel.size == 0)
            object : SeatelJSONArrayRequest(context) {

                override fun getFunctionName(): String {
                    return "certifications"
                }

            }.execute { itf ->
                certificateModel = ArrayList()
                val certificateObject = itf as JSONArray
                for (i in 0 until certificateObject.length()) {
                    certificateModel.add(
                        BottomChooserDialog.BottomChooserModel(
                            certificateObject.optJSONObject(i).optInt("certId"),
                            certificateObject.optJSONObject(i).optString("certName")
                        )
                    )
                }
                if (typeIDScan.isNotEmpty()) {
                    if (typeIDScan == "ID")
                        certificateModel
                            .filter { it.name == "ID Card" }
                            .forEach { updatedDocTypeSelected(it) }

                    if (typeIDScan == "PN" || typeIDScan == "P" || typeIDScan == "PO")
                        certificateModel
                            .filter { it.name == "Passport" }
                            .forEach { updatedDocTypeSelected(it) }
                } else {
                    showChooserDialog(certificateModel, object : BottomChooserDialog.OnItemChooser {
                        override fun onChose(
                            position: Int,
                            data: BottomChooserDialog.BottomChooserModel
                        ) {
                            binding.tvIdType.text = data.name
                            mCertificationNamePost = data.name
                            idCertificationType = data.id
                            binding.editTextCardNumber.isEnabled = true
                        }
                    })
                }
            }
        else
            if (typeIDScan.isNotEmpty()) {
                if (typeIDScan == "ID")
                    certificateModel
                        .filter { it.name == "ID Card" }
                        .forEach { updatedDocTypeSelected(it) }

                if (typeIDScan == "PN")
                    certificateModel
                        .filter { it.name == "Passport" }
                        .forEach { updatedDocTypeSelected(it) }
            } else {
                showChooserDialog(certificateModel, object : BottomChooserDialog.OnItemChooser {
                    override fun onChose(
                        position: Int,
                        data: BottomChooserDialog.BottomChooserModel
                    ) {
                        binding.tvIdType.text = data.name
                        mCertificationNamePost = data.name
                        idCertificationType = data.id
                        binding.editTextCardNumber.isEnabled = true
                    }
                })
            }
    }

    private fun showChooserDialog(
        bottomChooserModel: ArrayList<BottomChooserDialog.BottomChooserModel>,
        onItemChooser: BottomChooserDialog.OnItemChooser
    ) {
        BottomChooserDialog(context).addItems(bottomChooserModel, onItemChooser).show()
    }

    private fun showChooserDialog(
        bottomChooserModel: ArrayList<BottomChooserDialog.BottomChooserModel>,
        textView: TextView
    ) {
        BottomChooserDialog(context).addItems(
            bottomChooserModel,
            object : BottomChooserDialog.OnItemChooser {
                override fun onChose(position: Int, data: BottomChooserDialog.BottomChooserModel) {
                    textView.text = data.name
                    mGenderKeyPost = data.name
                }
            }).show()
    }

    fun setImageCrop(bitmap: Bitmap?) {
        when (imageType) {
            "front" -> {
                binding.imageViewFront.visibility = View.VISIBLE
                binding.imageViewFront.setImageBitmap(bitmap)
            }

            "back" -> {
                binding.imageViewBack.visibility = View.VISIBLE
                binding.imageViewBack.setImageBitmap(bitmap)
            }

            else -> {
                binding.imageViewUser.visibility = View.VISIBLE
                binding.imageViewUser.setImageBitmap(bitmap)
            }
        }
    }
}
