Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
8.3 kB
2
Indexable
Never
package com.agree.ecosystem.core.utils.presentation.dialog.sectorsdialog

import android.app.ActionBar
import android.app.Dialog
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import com.agree.ecosystem.core.utils.R
import com.agree.ecosystem.core.utils.base.AgrBottomSheet
import com.agree.ecosystem.core.utils.databinding.FragmentSectorsDialogBinding
import com.agree.ecosystem.core.utils.databinding.LayoutErrorSubsectorBinding
import com.agree.ecosystem.core.utils.domain.reqres.model.subsector.SubSector
import com.agree.ecosystem.core.utils.utility.AppConfig
import com.agree.ecosystem.core.utils.utility.extension.addObservers
import com.agree.ui.snackbar.errorSnackBar
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.oratakashi.viewbinding.core.binding.fragment.viewBinding
import com.oratakashi.viewbinding.core.tools.gone
import com.oratakashi.viewbinding.core.tools.visible
import com.telkom.legion.component.viewstate.ViewState
import com.telkom.legion.component.viewstate.showDefaultLayout
import com.telkom.legion.component.viewstate.showErrorLayout
import com.telkom.legion.component.viewstate.showLoadingLayout
import org.koin.androidx.viewmodel.ext.android.viewModel

class SectorsDialogFragment(
    private val defaultValue: String,
    private val isSmartFarming: Boolean,
    private val callback: (Pair<List<SubSector>, Boolean>) -> Unit
) : AgrBottomSheet(), SectorsDataContract {

    private val binding: FragmentSectorsDialogBinding by viewBinding()

    private val subSectors: MutableList<SubSector> by lazy {
        ArrayList()
    }

    private var bottomSheetBehavior: BottomSheetBehavior<View>? = null

    override fun initAction() {
        with(binding) {

            val bottomSheetBehavior = BottomSheetBehavior.from(container.parent as View)
            bottomSheetBehavior.setBottomSheetCallback(object :
                BottomSheetBehavior.BottomSheetCallback() {
                override fun onStateChanged(bottomSheet: View, newState: Int) {
                    if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                        dismiss()
                    }
                }

                override fun onSlide(bottomSheet: View, slideOffset: Float) {
                    if (slideOffset < -0.8) {
                        binding.btnApplyContainer.gone()
                    } else {
                        binding.btnApplyContainer.visible()
                    }
                }
            })

            ivClose.setOnClickListener { dismiss() }

            if (!isSmartFarming) {
                cbSmartfarming.gone()
                divSmartfarming.gone()
            }

            cbSelectAll.setOnClickListener {
                spSector.isCheckedAll = cbSelectAll.isChecked
            }

            btnApply.setOnClickListener {
                /**
                 * If CheckedAll and error detected will return callback empty list
                 * because nothing explicit sector selected, and fragment doesn't know
                 * how much real size sector list
                 */
                if (spSector.isCheckedAll) {
                    callback.invoke(subSectors to cbSmartfarming.isChecked)
                    dismiss()
                } else {
                    runCatching {
                        callback.invoke(
                            subSectors.filter {
                                spSector.text.contains(it.getFullSectorName())
                            } to cbSmartfarming.isChecked
                        )
                        dismiss()
                    }.onFailure {
                        it.printStackTrace()
                        callback.invoke(emptyList<SubSector>() to cbSmartfarming.isChecked)
                        dismiss()
                    }
                }
            }

            getSubSectors()
        }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val bottomSheetDialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
        bottomSheetDialog.setOnShowListener {
            val dialog = it as BottomSheetDialog

            dialog.findViewById<FrameLayout>(com.google.android.material.R.id.design_bottom_sheet) as FrameLayout
            val containerLayout: FrameLayout =
                dialog.findViewById<FrameLayout>(com.google.android.material.R.id.container) as FrameLayout
            val button = binding.btnApply
            val params = FrameLayout.LayoutParams(
                ActionBar.LayoutParams.MATCH_PARENT,
                ActionBar.LayoutParams.WRAP_CONTENT
            )
            params.gravity = Gravity.BOTTOM
            val parent = button.parent as ViewGroup
            parent.removeView(button)
            containerLayout.addView(button, params)
        }
        return bottomSheetDialog
    }

    override fun initObserver() {
        addObservers(SectorsObserver(this, viewModel))
    }

    override fun getSubSectors() {
        viewModel.getSubSectors()
    }

    override fun onGetSubSectorsLoading() {
        binding.msvSubSectors.showLoadingLayout()
    }

    override fun onGetSubSectorsSuccess(data: List<SubSector>) {
        with(binding) {
            binding.msvSubSectors.showDefaultLayout()
            subSectors.clear()
            subSectors.addAll(data)
            spSector.addAll(data)

            if (defaultValue == getString(R.string.label_all_subsector)) {
                spSector.text = data.joinToString(", ") { it.getFullSectorName() }
            } else {
                spSector.text = defaultValue
            }

            spSector.setOnCheckedChangeListener {
                cbSelectAll.isChecked = it
            }
        }
    }

    override fun onGetSubSectorsFailed(e: Throwable?) {
        with(binding) {
            msvSubSectors.showErrorLayout()

            val errorView = msvSubSectors.getView(ViewState.ERROR)

            with(LayoutErrorSubsectorBinding.bind(errorView)) {
                btnTryAgain.setOnClickListener {
                    getSubSectors()
                }
            }
        }

        if (AppConfig.isDebug) {
            errorSnackBar(e?.message.toString())
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return binding.root
    }

    private val viewModel: SectorsViewModel by viewModel()

    companion object {
        fun setup(block: Builder.() -> Unit): SectorsDialogFragment {
            return Builder().apply(block).build()
        }
    }

    open class Builder {
        /**
         * Selected sector
         */
        var selectedSectors: String = ""

        /**
         * Show Smartfarming Filter
         */
        var isSmartFarming: Boolean = false

        /**
         * Callback will return list of selected subsector and isSmartFarming
         */
        private var callback: (Pair<List<SubSector>, Boolean>) -> Unit = {}

        /**
         * Callback will return list of selected subsector and isSmartFarming
         */
        @JvmName("setCallbackListenerBoth")
        fun setCallbackListener(callback: (List<SubSector>, Boolean) -> Unit) {
            this.callback = {
                callback.invoke(it.first, it.second)
            }
        }

        /**
         * Callback will return list of selected subsector only
         */
        @JvmName("setCallbackListenerSubSector")
        fun setCallbackListener(callback: (List<SubSector>) -> Unit) {
            this.callback = {
                callback.invoke(it.first)
            }
        }

        fun build(): SectorsDialogFragment {
            return SectorsDialogFragment(selectedSectors, isSmartFarming, callback)
        }
    }
}