package com.seatel.mobilehall.ui.profile.activity

import android.Manifest
import android.app.Activity
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Typeface
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.text.SpannableStringBuilder
import android.text.TextUtils
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.lifecycle.lifecycleScope
import com.android.volley.VolleyError
import com.bumptech.glide.Glide
import com.seatel.mobilehall.BuildConfig
import com.seatel.mobilehall.R
import com.seatel.mobilehall.data.network.SeatelSuperRequest
import com.seatel.mobilehall.ui.base.activity.BaseActivity
import com.seatel.mobilehall.ui.home.interactor.ProfileInteractor
import com.seatel.mobilehall.ui.home.presenter.ProfilePresenter
import com.seatel.mobilehall.ui.login.activity.LoginActivity
import com.seatel.mobilehall.ui.login.activity.UpdatedSimProfileActivity
import com.seatel.mobilehall.ui.login.model.ProfileModel
import com.seatel.mobilehall.ui.login.model.UploadImageResponse
import com.seatel.mobilehall.ui.profile.fragment.BottomSheetFragment
import com.seatel.mobilehall.ui.profile.interactor.BottomSheetInteractor
import com.seatel.mobilehall.ui.profile.interactor.UploadImageInteractor
import com.seatel.mobilehall.ui.profile.presenter.UploadImagePresenter
import com.seatel.mobilehall.util.*
import com.seatel.mobilehall.util.Constant.REQUEST_CROP_PHOTO
import com.seatel.mobilehall.util.Constant.REQUEST_LOAD_PHOTO
import com.seatel.mobilehall.util.Constant.REQUEST_TAKE_PHOTO
import com.theartofdev.edmodo.cropper.CropImage
import com.theartofdev.edmodo.cropper.CropImageView
import id.zelory.compressor.Compressor
import id.zelory.compressor.constraint.format
import id.zelory.compressor.constraint.quality
import id.zelory.compressor.constraint.resolution
import kotlinx.android.synthetic.main.activity_profile.*
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*

class ProfileActivity : BaseActivity(), View.OnClickListener, ProfileInteractor.View,
    BottomSheetInteractor.View, UploadImageInteractor.View {

    private var mCameraRequest: PermissionUtil.PermissionRequestObject? = null
    private var mImageCaptureUri: Uri? = null
    private lateinit var mOutputFile: File
    private lateinit var mBottomSheet: BottomSheetFragment
    private lateinit var mUploadImagePresenter: UploadImagePresenter
    private var compressedImage: File? = null

    private var isEdit = false
    private lateinit var mMenu: MenuItem
    private var mDataProfile: ProfileModel? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_profile)
        super.activityEnterRightAnimation()
        init()
        if (isNoneSeatel()) {
            view_updated_profile.visibility = View.GONE
            line_bottom.visibility = View.GONE
        }
    }

    override fun onBackPressed() {
        super.onBackPressed()
        super.activityExitLeftAnimation()
        finish()
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {

        val inflater = menuInflater
        inflater.inflate(R.menu.menu_profile, menu)
        this.mMenu = menu.findItem(R.id.edit_menu)

        val customFont = FontCache.getFont(this, Typeface.NORMAL)
        val plain = FontCache.get(this, customFont)

//        val face = Typeface.createFromAsset(assets, "fonts/HelveticaNeue-Regular.ttf")
        val title =
            SpannableStringBuilder(SeatelUtils.translatForDialog(this, getString(R.string.edit)))
        title.setSpan(plain, 0, title.length, 0)
        mMenu.title = title

        if (!isMainAccountLogin())
            mMenu.isVisible = false

        return super.onCreateOptionsMenu(menu)
    }


    override fun onGalleryClicked() {
        mBottomSheet.dismiss()
        loadFile()
    }

    override fun onCameraClicked() {
        mBottomSheet.dismiss()
        showCamera()
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {

        if (item.itemId == R.id.edit_menu) updateMenu()
        return super.onOptionsItemSelected(item)
    }

    override fun onLoadDataSucceed(profileModel: ProfileModel) {
        mDataProfile = profileModel
        hideProgress()
        fillDataProfile(profileModel)
    }

    private fun fillDataProfile(profileModel: ProfileModel) {
        if (profileModel.certType.isNotEmpty())
            text_view_id.text = SeatelUtils.translatForDialog(
                this,
                profileModel.certType
            ) + ": " + profileModel.certNumber
        else {
            view_id.visibility = View.GONE
            line_id.visibility = View.GONE
        }
        if (profileModel.custName.isEmpty()) {
            view_name.visibility = View.GONE
            line_name.visibility = View.GONE
        } else text_view_cart_name.text = profileModel.custName
        text_view_cart_phone_number.text = SeatelUtils.phoneNumberFormat(profileModel.msisdn)
        text_view_email.text = profileModel.email

        if (TextUtils.isEmpty(text_view_email.text.trim()))
            layout_email.visibility = View.GONE

        if (!TextUtils.isEmpty(profileModel.imageUrl))
            Glide.with(this)
                .load(profileModel.imageUrl)
                .placeholder(R.drawable.ic_yes_profile)
                .dontAnimate()
                .into(image_view_profile)

        text_view_password.visibility = View.VISIBLE
    }

    override fun onLoadDataFailed(error: VolleyError) {
        Log.d("onLoadDataFailed::>>>", "onLoadDataFailed: ${error.message}")
        hideProgress()
        SeatelAlertDialog.with(this, SeatelSuperRequest.getErrorMessageFrom(error)).show()
    }

    private fun init() {
        val profilePresenter = ProfilePresenter(this)
//        mDataProfile = Gson().fromJson<ProfileModel>(SeatelSharePreferences.getConstant(this).userInfo, ProfileModel::class.java)
        if (mDataProfile == null) {
            showProgress()
            profilePresenter.loadData(getPhoneLogin())
        } else fillDataProfile(mDataProfile!!)

        image_view_camera.setOnClickListener {
            mBottomSheet.show(supportFragmentManager, "BottomSheetFragment")
        }
        mBottomSheet = BottomSheetFragment()
        mBottomSheet.setBottomSheetView(this)
        view_updated_profile.setOnClickListener {
            LoginActivity.launchWithAddNewPhone(this, false, true)
            //  UpdatedSimProfileActivity.launch(this, getMainPhoneLogin())
        }
    }

    private fun updateMenu() {

        if (isEdit) {
            image_view_edit_pass.visibility = View.GONE
            image_view_camera.visibility = View.GONE
            mMenu.title = SeatelUtils.translatForDialog(this, getString(R.string.edit))
            isEdit = false
        } else {
            image_view_edit_pass.visibility = View.VISIBLE
            image_view_camera.visibility = View.VISIBLE
            mMenu.title = SeatelUtils.translatForDialog(this, getString(R.string.cancel))
            isEdit = true
            image_view_edit_pass.setOnClickListener(this)
        }
    }

    override fun onClick(v: View?) {
        ChangePasswordActivity.lunch(this)
    }

    companion object {
        fun lunch(context: Context) {
            val intent = Intent(context, ProfileActivity::class.java)
            context.startActivity(intent)
        }
    }


    private fun showCamera() {

        mCameraRequest = PermissionUtil.with(this).request(
            Manifest.permission.CAMERA,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
        ).onAllGranted(object : PermissionUtil.Func() {

            override fun call() {
                dispatchTakePictureIntent(REQUEST_TAKE_PHOTO)
            }

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

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        mCameraRequest!!.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (resultCode != RESULT_OK) return

        when (requestCode) {

            REQUEST_LOAD_PHOTO ->
                if (data != null && data.data != null) {
                    val actualImage = FileUtils.from(this, data.data)
                    lifecycleScope.launch {
                        val compressedImageFile = Compressor.compress(this@ProfileActivity, actualImage)
                        mImageCaptureUri = Uri.fromFile(compressedImageFile)
                        setImageCrop()
                    }

                    /* GlobalScope.launch {
                         val file =
                             Compressor.compress(this@ProfileActivity, actualImage) {
                                 resolution(640, 480)
                                 quality(90)
                                 format(Bitmap.CompressFormat.WEBP)

                             }

                     }*/
                    //doCrop(REQUEST_CROP_PHOTO)
                }
            REQUEST_TAKE_PHOTO ->
                //doCrop(REQUEST_CROP_PHOTO)
                setImageCrop()

            CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE -> {
                val result = CropImage.getActivityResult(data)
                if (resultCode == Activity.RESULT_OK) {
                    result.uri?.let {
                        val actualImage = FileUtils.from(this, it)
                        lifecycleScope.launch {
                            val mCompressFile =
                                Compressor.compress(this@ProfileActivity, actualImage) {
                                    resolution(640, 480)
                                    quality(90)
                                    format(Bitmap.CompressFormat.WEBP)

                                }
                            mOutputFile = mCompressFile
                            setImage()
                        }
                    }
                }

            }
            REQUEST_CROP_PHOTO -> setImage()
        }
    }


    override fun onUploadFailed(error: VolleyError) {
        Log.d("onUploadFailed::>>", "onUploadFailed: ${error.message}")
        hideProgress()
        SeatelAlertDialog.with(this, SeatelSuperRequest.getErrorMessageFrom(error)).show()
    }

    override fun onUploadSucceed(data: UploadImageResponse) {
        mUploadImagePresenter.onUpdate(getPhoneLogin(), data.data[0].filename)
    }

    override fun onUpdateSucceed() {
        hideProgress()
        isEdit = true
        updateMenu()
        Glide.with(this).load(mOutputFile).dontAnimate().into(image_view_profile)
    }

    private fun setImage() {
        showProgress()
        mUploadImagePresenter = UploadImagePresenter(this)
        mUploadImagePresenter.onUpload(mOutputFile)
    }

    private fun setImageCrop() {
        CropImage.activity(mImageCaptureUri)
            .setGuidelines(CropImageView.Guidelines.ON)
            .start(this)
    }

    private fun doCrop(requestCode: Int) {

        mOutputFile = File.createTempFile(
            "crop_" + Calendar.getInstance().timeInMillis + "_",
            ".jpg",
            getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        )
        val mImageCropUri =
            FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", 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)
        intent.putExtra("aspectX", 1)
        intent.putExtra("aspectY", 1)

        val resInfoList = packageManager.queryIntentActivities(intent, 0)
        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)
                }
                grantUriPermission(
                    packageName,
                    mImageCropUri,
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
                )
            }
        }
        startActivityForResult(intent, requestCode)
    }

    private fun dispatchTakePictureIntent(requestCode: Int) {

        val intentTakePhoto = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
        val imageFileName = "IMG_$timeStamp.jpg"
        try {
            val f = File.createTempFile(
                "IMG_$timeStamp",
                ".jpg",
                getExternalFilesDir(Environment.DIRECTORY_PICTURES)
            )
            mImageCaptureUri =
                FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", f)
            intentTakePhoto.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri)
            intentTakePhoto.putExtra("listPhotoName", imageFileName)
            startActivityForResult(intentTakePhoto, requestCode)
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    private fun loadFile() {

        var intent: Intent? = null

        mCameraRequest = PermissionUtil.with(this).request(
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
        ).onAllGranted(object : PermissionUtil.Func() {

            override fun call() {
                if (intent != null) return
                intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
                startActivityForResult(intent, REQUEST_LOAD_PHOTO)
            }

        }).onAnyDenied(object : PermissionUtil.Func() {
            override fun call() {
                Toast.makeText(
                    this@ProfileActivity,
                    "Storage permission is needed to access file.",
                    Toast.LENGTH_LONG
                ).show()
            }
        }).askPermission(99)
    }

    private fun getCompressFile(actualImage: File): File {

        /* return Compressor(this).setMaxWidth(640).setMaxHeight(480)
                 .setQuality(90)
                 .setCompressFormat(Bitmap.CompressFormat.WEBP)
                 .setDestinationDirectoryPath(getExternalFilesDir(Environment.DIRECTORY_PICTURES)?.absolutePath)
                 .compressToFile(actualImage)*/
        actualImage.let { imageFile ->
            lifecycleScope.launch {
                compressedImage = Compressor.compress(this@ProfileActivity, imageFile) {
                    resolution(640, 480)
                    quality(90)
                    format(Bitmap.CompressFormat.WEBP)
                }
            }
        }

        return compressedImage!!
    }
}
