package com.seatel.mobilehall.ui.usage.fragement

import android.app.DatePickerDialog
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.NoConnectionError
import com.android.volley.TimeoutError
import com.android.volley.VolleyError
import com.seatel.mobilehall.R
import com.seatel.mobilehall.data.network.SeatelSuperRequest
import com.seatel.mobilehall.databinding.FragmentVoiceBinding
import com.seatel.mobilehall.ui.base.fragment.BaseFragment
import com.seatel.mobilehall.ui.login.activity.LoginActivity
import com.seatel.mobilehall.ui.usage.adapter.VoiceBillingAdapter
import com.seatel.mobilehall.ui.usage.interactor.BilingDetailListInteractor
import com.seatel.mobilehall.ui.usage.model.BilingDetailModel
import com.seatel.mobilehall.ui.usage.presenter.BilingDetailListPresenter
import com.seatel.mobilehall.util.AnalyticsHelper
import com.seatel.mobilehall.util.Constant
import com.seatel.mobilehall.util.SeatelUtils
import com.seatel.mobilehall.util.customview.CustomTextView
import com.seatel.mobilehall.util.customview.ErrorHandleView
import com.seatel.mobilehall.util.viewFragmentBinding
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale

class VoiceFragment : BaseFragment(), BilingDetailListInteractor.View, View.OnClickListener {


    private val binding by viewFragmentBinding(
        FragmentVoiceBinding::inflate
    )

    var mBilingDetailInteractor: BilingDetailListInteractor.View? = null
    var mBilingDetailPresenter: BilingDetailListPresenter? = null

    var mData: ArrayList<BilingDetailModel> = ArrayList()

    var startRequestRefresh = false
    var mOffset = 0
    val LIMIT_OFFSET = 10

    var linearLayoutManager: LinearLayoutManager? = null
    var mVoiceBilingAdapter: VoiceBillingAdapter? = null

    var calendarFilterFrom: Calendar? = null
    var calendarFilterTo: Calendar? = null
    var mStartData = ""
    var mEndData = ""
    var mPhoneNumber = ""
    var hour_on_call: CustomTextView? = null

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


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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // errorView = view.findViewById(R.id.error_view)

    }


    override fun onResume() {
        super.onResume()
        init()
    }


    fun setStartDate(mStartData: String) {
        this.mStartData = mStartData
    }

    fun setEndDate(mEndData: String) {
        this.mEndData = mEndData
    }

    fun getStartDate(): String {
        return mStartData
    }

    fun getEndDate(): String {
        return mEndData
    }

    fun setPhoneNuber(phone: String) {
        this.mPhoneNumber = phone
    }

    fun getDataBilling(): BilingDetailModel {
        return if (mData.size == 0) BilingDetailModel()
        else mData[0]
    }

    /* fun isPostPaidAccount(): Boolean {
         return SeatelSharePreferences.getInstance(requireContext())?.getIsPostPaid()!!
     }*/

    private fun init() {
        hour_on_call = view?.findViewById(R.id.hour_on_call)
        if (getMainPhoneLogin().isEmpty()) {
            binding.layoutBottomBilling.visibility = View.GONE

            binding.textLoginSignup.visibility = View.VISIBLE
            binding.textLoginSignup.setOnClickListener(this)
        } else {
            binding.layoutBottomBilling.visibility = View.VISIBLE
            binding.textLoginSignup.visibility = View.GONE
            calendarFilterFrom = Calendar.getInstance()
            calendarFilterTo = Calendar.getInstance()

            mBilingDetailInteractor = this

            linearLayoutManager = LinearLayoutManager(getmContext())

            binding.recyclerViewVoiceBilling.layoutManager = linearLayoutManager
            mVoiceBilingAdapter = VoiceBillingAdapter(getmContext(), isPostPaidAccount())
            mVoiceBilingAdapter?.setBilingType(Constant.VOICE)
            mVoiceBilingAdapter?.setViewInteractor(mBilingDetailInteractor)
            binding.recyclerViewVoiceBilling.adapter = mVoiceBilingAdapter
            binding.recyclerViewVoiceBilling.setHasFixedSize(true)

            /*  if (mStartData.isEmpty()) {
                  val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
                  mStartData = sdf.format(Date())
                  mEndData = sdf.format(Date())

              } else {
                  _binding!!.ctvFilterFrom.text =
                      SeatelUtils.getDateTime("yyyy-MM-dd", "MMM dd, yyyy", mStartData)
                  _binding!!.ctvFilterTo.text =
                      SeatelUtils.getDateTime("yyyy-MM-dd", "MMM dd, yyyy", mEndData)
              }*/
            setCurrentDateFilter()
            mBilingDetailPresenter = BilingDetailListPresenter(getmContext(), this)
            mBilingDetailPresenter?.setTypeBiling(Constant.VOICE)
            mBilingDetailPresenter?.setPhoneNumber(getPhoneLogin())
            mBilingDetailPresenter?.setEndDate(mEndData)
            mBilingDetailPresenter?.setStartDate(mStartData)
            getBilingList()
            binding.recyclerViewVoiceBilling.addOnScrollListener(object :
                RecyclerView.OnScrollListener() {
                override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                    super.onScrolled(recyclerView, dx, dy)
                    if (!startRequestRefresh) mVoiceBilingAdapter?.onScrollEvent(linearLayoutManager!!)
                    startRequestRefresh = false
                }
            })

            binding.viewDateFilterTo.setOnClickListener(this)
            binding.viewDateFilterFrom.setOnClickListener(this)

        }

    }

    private fun setCurrentDateFilter() {
        val currentDate = Calendar.getInstance()
        val year = currentDate.get(Calendar.YEAR)
        val month = currentDate.get(Calendar.MONTH)
        val dayFrom = currentDate.get(Calendar.DAY_OF_MONTH).minus(7)
        val dayTo = currentDate.get(Calendar.DAY_OF_MONTH)

        calendarFilterFrom?.set(Calendar.YEAR, year)
        calendarFilterFrom?.set(Calendar.MONTH, month)
        calendarFilterFrom?.set(Calendar.DAY_OF_MONTH, 1)

        calendarFilterTo?.set(Calendar.YEAR, year)
        calendarFilterTo?.set(Calendar.MONTH, month)
        calendarFilterTo?.set(Calendar.DAY_OF_MONTH, dayTo)

        val myFormat = "MMM dd, yyyy" // mention the format you need
        val formatType = SimpleDateFormat(myFormat, Locale.US)

        val myFormatForApi = "yyyy-MM-dd"
        val formatTypeApi = SimpleDateFormat(myFormatForApi, Locale.US)
        mStartData = formatTypeApi.format(calendarFilterFrom?.time)
        mEndData = formatTypeApi.format(calendarFilterTo?.time)

        binding.ctvFilterFrom.text = formatType.format(calendarFilterFrom?.time)
        binding.ctvFilterTo.text = formatType.format(calendarFilterTo?.time)
    }

    private fun showDatePicker(filterFrom: Boolean) {
        var calendarData = calendarFilterTo
        if (filterFrom) calendarData = calendarFilterFrom

        if (calendarData == null) return

        val year = calendarData.get(Calendar.YEAR)
        val month = calendarData.get(Calendar.MONTH)
        val day = calendarData.get(Calendar.DAY_OF_MONTH)
        // add "R.style.CustomDatePickerDialogTheme" after context for show old style
        val mTimePicker = DatePickerDialog(
            getmContext(), DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth ->

                calendarData.set(Calendar.YEAR, year)
                calendarData.set(Calendar.MONTH, month)
                calendarData.set(Calendar.DAY_OF_MONTH, dayOfMonth)

                val myFormat = "MMM dd, yyyy" // mention the format you need
                val formatType = SimpleDateFormat(myFormat, Locale.US)

                val myFormatApi = "yyyy-MM-dd" // format for service
                val formatTypeApi = SimpleDateFormat(myFormatApi, Locale.US)

                if (filterFrom) {
                    binding.ctvFilterFrom.text = formatType.format(calendarData.time)
                    mStartData = formatTypeApi.format(calendarData.time)
                    mBilingDetailPresenter?.setStartDate(mStartData)
                } else {
                    binding.ctvFilterTo.text = formatType.format(calendarData.time)
                    mEndData = formatTypeApi.format(calendarData.time)
                    mBilingDetailPresenter?.setEndDate(mEndData)
                }
                getBilingList()

            }, year, month, day
        )
//        mTimePicker.setTitle(SeatelUtils.translatForDialog(getmContext(),getString(R.string.please_select_date)))
        val minFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
        if (!filterFrom) {
            val strDate = "${calendarFilterFrom?.get(Calendar.DAY_OF_MONTH)}/${
                (calendarFilterFrom?.get(Calendar.MONTH))?.plus(1)
            }/${calendarFilterFrom?.get(Calendar.YEAR)}"
            val dateMin = minFormat.parse(strDate)
            mTimePicker.datePicker.minDate = dateMin.time
        } else {
            val strDateMax = "${calendarFilterTo?.get(Calendar.DAY_OF_MONTH)}/${
                (calendarFilterTo?.get(Calendar.MONTH))?.plus(1)
            }/${calendarFilterTo?.get(Calendar.YEAR)}"
            val dateMax = minFormat.parse(strDateMax)
            val strDateMin = "${Calendar.getInstance().get(Calendar.DAY_OF_MONTH)}/${
                (Calendar.getInstance().get(Calendar.MONTH)).minus(2)
            }/${Calendar.getInstance().get(Calendar.YEAR)}"
            val dateMin = minFormat.parse(strDateMin)
            mTimePicker.datePicker.maxDate = dateMax.time
            mTimePicker.datePicker.minDate = dateMin.time
        }
        mTimePicker.show()
    }

    private fun setDataAdapter(reportList: ArrayList<BilingDetailModel>) {
        mVoiceBilingAdapter?.addItems(reportList)
        try {
            binding.errorView.visibility = View.GONE
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun getBilingList() {
        startRequestRefresh = true
        mVoiceBilingAdapter?.clearData()
        mOffset = 0
        mData = ArrayList()
        binding.errorView.setViewMode(ErrorHandleView.Mode.LOADING)
        mBilingDetailPresenter?.onBilingDetailData(mOffset)
    }


    override fun responseBilingSucceed(notificationList: ArrayList<BilingDetailModel>) {
        mData.addAll(notificationList)
        setDataAdapter(notificationList)
        if (notificationList.size == 0 && mOffset == 0) {
            if (activity != null) {
                binding.errorView.errorMessage =
                    requireContext().getString(R.string.you_dont_have_any_billing_voice_yet)
            }

            binding.errorView.setViewMode(ErrorHandleView.Mode.NO_DATA)
            setupBillingBottom(BilingDetailModel())
        } else {
            if (notificationList.size > 0) setupBillingBottom(mData[0])
            binding.errorView.visibility = View.GONE
        }

        if (notificationList.size < LIMIT_OFFSET) mVoiceBilingAdapter?.setLoaded(false)

    }

    private fun setupBillingBottom(data: BilingDetailModel) {

        val dataInNet = SeatelUtils.convertSecondToDisplayFullTime(data.totalInNetDuration)
        if (dataInNet[0] > 0) {
            binding.ctvValueTotalOnCallHour.text = dataInNet[0].toString()
            hour_on_call?.visibility = View.VISIBLE
            binding.ctvValueTotalOnCallHour.visibility = View.VISIBLE
        } else {
            binding.ctvValueTotalOnCallHour.visibility = View.GONE
            hour_on_call?.visibility = View.GONE
        }

        binding.ctvValueTotalOnCall.text = dataInNet[1].toString()
        binding.ctvValueTotalOnCall.visibility = View.VISIBLE
        binding.ctvValueTotalOnCall.visibility = View.VISIBLE
        if (dataInNet[1] == 0) {
            binding.ctvValueTotalOnCall.visibility = View.GONE
            binding.minOnCall.visibility = View.GONE

        }

        binding.ctvValueTotalOnCallSec.text = dataInNet[2].toString()
        binding.ctvValueTotalOnCallSec.visibility = View.VISIBLE
        binding.secOnCall.visibility = View.VISIBLE
        if ((dataInNet[1] > 0 && dataInNet[2] == 0) || (dataInNet[0] > 0 && dataInNet[1] == 0 && dataInNet[2] == 0)) {
            binding.ctvValueTotalOnCallSec.visibility = View.GONE
            binding.secOnCall.visibility = View.GONE
        }

        binding.minOnCall.text = activity?.getString(R.string.min)
        binding.minOffCall.text = getString(R.string.min)

        binding.txtTitleTotalOnCall.text =
            SeatelUtils.translatForDialog(getmContext(), getString(R.string.total_on_call))

        binding.txtTitleTotalOffCall.text =
            SeatelUtils.translatForDialog(getmContext(), getString(R.string.total_off_call))

        binding.ctvValueTotalOffCall.text =
            data.totalOffNetDuration?.let { SeatelUtils.convertSecondToTime(it) }

        binding.ctvValueTotalOffCost.text =
            "${data.totalOffNetCost?.let { SeatelUtils.formatNumberK(it, 0) }}"

        binding.ctvValueTotalOnCost.text =
            "${data.totalInNetCost?.let { SeatelUtils.formatNumberK(it, 0) }}"

    }

    override fun responseBilingFail(error: VolleyError) {
        when (error) {
            is TimeoutError -> {
                binding.errorView.errorMessage =
                    getmContext().getString(R.string.connection_timeout)
                binding.errorView.setViewMode(ErrorHandleView.Mode.TIME_OUT)
            }

            is NoConnectionError -> {
                binding.errorView.errorMessage =
                    getmContext().getString(R.string.message_no_internet)
                binding.errorView.setViewMode(ErrorHandleView.Mode.NO_INTERNET)
            }

            else -> {
                binding.errorView.errorMessage = SeatelSuperRequest.getErrorMessageFrom(error)
                if (mOffset == 0) {
                    binding.errorView.errorMessage =
                        getmContext().getString(R.string.you_dont_have_any_billing_voice_yet)
                    binding.errorView.setViewMode(ErrorHandleView.Mode.NO_DATA)
                    // onDataChangedListener!!.onNoData(0)
                }
            }
        }
    }

    override fun onLoadMore() {
        mOffset += LIMIT_OFFSET
        binding.errorView.setViewMode(ErrorHandleView.Mode.LOADING)
        mBilingDetailPresenter?.onBilingDetailData(mOffset)
    }

    override fun onClick(view: View?) {
        when (view?.tag) {
            "FROM" -> {
                showDatePicker(true)
                AnalyticsHelper.logEvent(
                    AnalyticsHelper.Event.USAGE_TAP_DOWNLOAD_DOCUMENT_VOICE, null
                )
            }

            "TO" -> {
                showDatePicker(false)
                AnalyticsHelper.logEvent(
                    AnalyticsHelper.Event.USAGE_TAP_DOWNLOAD_DOCUMENT_VOICE, null
                )
            }

            "LOGIN_SIGNUP" -> LoginActivity.lunch(requireContext())
        }
    }
}