package com.pan_american.android.ui.group_management.entry_and_exit_fee_detail

import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.pan_american.android.OASystem
import com.pan_american.android.R
import com.pan_american.android.base.BaseActivity
import com.pan_american.android.base.BaseResponse
import com.pan_american.android.base.ListAdapter
import com.pan_american.android.data.model.group_management.entry_and_exit_fee_detail.entity.EntryAndExitPaymentPrinciple
import com.pan_american.android.data.model.group_management.entry_and_exit_fee_detail.network.EntryAndExitPaymentPrincipleRequest
import com.pan_american.android.data.model.group_management.entry_and_exit_fee_detail.network.EntryAndExitPaymentPrincipleResponse
import com.pan_american.android.data.model.group_management.entry_and_exit_fee_detail.network.UpdateEntryAndExitPaymentDetailRequest
import com.pan_american.android.data.network.APIService
import com.pan_american.android.data.network.ServiceCreator
import com.pan_american.android.databinding.ActivityEntryAndExitPaymentDetailBinding
import com.pan_american.android.databinding.LayoutTitleBinding
import com.pan_american.android.util.MoneyInputFilter
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class EntryAndExitPaymentDetailActivity : BaseActivity<ActivityEntryAndExitPaymentDetailBinding>() {

    private var fromList = false

    private lateinit var titleBinding: LayoutTitleBinding

    private val apiService = ServiceCreator.create<APIService>()

    private val entryAndExitPaymentPrincipleRequest = EntryAndExitPaymentPrincipleRequest()

    private val principleData = ArrayList<EntryAndExitPaymentPrinciple>()

    private var cityId = 0

    private var currencyId = 0

    private var rate = 0.0

    private val regex = Regex("^-?\\d+(\\.\\d{1,2})?\$")

    private val updateEntryAndExitPaymentDetailRequest = UpdateEntryAndExitPaymentDetailRequest()

    override fun getViewBinding() = ActivityEntryAndExitPaymentDetailBinding.inflate(layoutInflater)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        intent.apply {
            fromList = getBooleanExtra("fromList", false)
            updateEntryAndExitPaymentDetailRequest.also {
                it.diId = getIntExtra("diId", 0)
                it.feeType = getIntExtra("feeType", 0)
            }
        }

        if (fromList) {
            intent.apply {
                updateEntryAndExitPaymentDetailRequest.also {
                    it.subId = getIntExtra("id", 0)
                    it.days = getIntExtra("days", 0)
                    it.nationalTravelFeeId = getIntExtra("nationalTravelFeeId", 0)

                    cityId = it.nationalTravelFeeId
                    binding.city.text = getStringExtra("arae")

                    it.cost = getDoubleExtra("cost", 0.0)
                    it.currency = getIntExtra("currency", 0)

                    currencyId = it.currency

                    it.subTotal = getDoubleExtra("subTotal", 0.0)

                    for (item in OASystem.entryAndExitDetailResponse.currencys) {
                        if (item.currencyCode == getStringExtra("currencyName")) {
                            rate = item.rate
                            binding.currency.text = String.format(
                                resources.getString(R.string.currency_name_code_format),
                                item.currencyName,
                                item.currencyCode
                            )
                        }
                    }
                }
            }
        }

        initTitle()
        initViews()
        initEvents()
    }

    override fun initTitle() {
        titleBinding = LayoutTitleBinding.bind(binding.root).apply {
            titleText.text = if (fromList) {
                resources.getString(R.string.entry_and_exit_payment_detail)
            } else {
                resources.getString(R.string.add_entry_and_exit_payment_detail)
            }

            backButton.setOnClickListener {
                back()
            }
        }
    }

    override fun initViews() {
        if (fromList) {
            binding.commit.text = resources.getString(R.string.update)

            updateEntryAndExitPaymentDetailRequest.apply {
                binding.nights.setText(days.toString())
                binding.paymentPrinciple.setText(cost.toString())
                binding.totalPayment.text = subTotal.toString()
            }

        } else {
            binding.commit.text = resources.getString(R.string.add)
        }

        binding.paymentPrinciple.filters = arrayOf(MoneyInputFilter(2))
    }

    override fun initEvents() {
        binding.city.setOnClickListener {
            entryAndExitPaymentPrincipleRequest.apply {
                pageIndex = 1
            }

            getCityAndPaymentPrincipleData(1)
        }

        binding.paymentPrinciple.addTextChangedListener(object : TextWatcher {
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

            }

            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            override fun afterTextChanged(s: Editable?) {
                if (binding.paymentPrinciple.text.toString()
                        .matches(regex) && binding.paymentPrinciple.text.isNotBlank()
                ) {
                    binding.totalPayment.text = String.format(
                        resources.getString(R.string.decimal_format),
                        binding.paymentPrinciple.text.toString().toDouble() * rate
                    )
                }
            }
        })

        binding.commit.setOnClickListener {
            if (binding.nights.text.isNotBlank()) {
                updateEntryAndExitPaymentDetailRequest.days = binding.nights.text.toString().toInt()
            } else {
                showMessage(resources.getString(R.string.nights_input_hint))
                return@setOnClickListener
            }

            if (cityId != 0) {
                updateEntryAndExitPaymentDetailRequest.nationalTravelFeeId = cityId
            } else {
                showMessage(resources.getString(R.string.city_selected_hint))
                return@setOnClickListener
            }

            if (binding.paymentPrinciple.text.toString().matches(regex)) {
                updateEntryAndExitPaymentDetailRequest.cost = binding.paymentPrinciple.text.toString().toDouble()
            } else {
                showMessage(resources.getString(R.string.payment_price_hint))
                return@setOnClickListener
            }

            updateEntryAndExitPaymentDetailRequest.apply {
                currency = currencyId
                subTotal = binding.totalPayment.text.toString().toDouble()
            }

            updateEntryAndExitPaymentDetail()
        }
    }

    private fun getCityAndPaymentPrincipleData(type: Int) {
        apiService.getEntryAndExitCurrencyCityAndPrinciples(entryAndExitPaymentPrincipleRequest)
            .enqueue(object :
                Callback<EntryAndExitPaymentPrincipleResponse> {
                override fun onResponse(
                    call: Call<EntryAndExitPaymentPrincipleResponse>,
                    response: Response<EntryAndExitPaymentPrincipleResponse>
                ) {
                    val dataResponse = response.body()

                    if (dataResponse != null) {
                        if (dataResponse.code == 200) {

                            for (item in dataResponse.data) {
                                principleData.add(item)
                            }

                            when (type) {
                                1 -> {

                                    val popView = View.inflate(
                                        OASystem.context,
                                        R.layout.popup_smart_refresh_selector,
                                        null
                                    )
                                    popupWindow = PopupWindow(
                                        popView,
                                        ViewGroup.LayoutParams.MATCH_PARENT,
                                        ViewGroup.LayoutParams.WRAP_CONTENT
                                    )

                                    showPopupWindow {
                                        val searchView: LinearLayout =
                                            popView.findViewById(R.id.search_view)
                                        searchView.visibility = View.VISIBLE

                                        val searchText: EditText =
                                            popView.findViewById(R.id.search_text)

                                        selector = popView.findViewById(R.id.selector_list)

                                        selectorContainer =
                                            popView.findViewById(R.id.selector_refresh_container)
                                        selectorContainer.setEnableRefresh(true)
                                        selectorContainer.setEnableLoadMore(true)

                                        val layoutManager = LinearLayoutManager(OASystem.context)
                                        selector.layoutManager = layoutManager

                                        val adapter =
                                            ListAdapter.Builder<EntryAndExitPaymentPrinciple>()
                                                .apply {
                                                    setData(principleData)
                                                    setLayoutId(R.layout.item_selector)
                                                    addBindView { itemView, data ->
                                                        itemView.findViewById<TextView>(R.id.selector_item_name)
                                                            .apply {
                                                                text = data.area

                                                                if (cityId == data.id) {
                                                                    setTextColor(
                                                                        ResourcesCompat.getColor(
                                                                            resources,
                                                                            R.color.text_color_blue,
                                                                            null
                                                                        )
                                                                    )
                                                                } else {
                                                                    setTextColor(
                                                                        ResourcesCompat.getColor(
                                                                            resources,
                                                                            R.color.text_color,
                                                                            null
                                                                        )
                                                                    )
                                                                }
                                                            }
                                                    }
                                                }.create()

                                        selector.adapter = adapter

                                        adapter.onRecyclerViewItemClick =
                                            object :
                                                ListAdapter.OnRecyclerViewItemClick<EntryAndExitPaymentPrinciple> {
                                                override fun onItemClick(position: Int) {
                                                    principleData[position].apply {
                                                        binding.city.text = area

                                                        cityId = id

                                                        currencyId = currency

                                                        binding.currency.text = String.format(
                                                            resources.getString(R.string.currency_name_code_format),
                                                            currencyName,
                                                            currencyCode
                                                        )

                                                        var paymentPrinciple = 0.0

                                                        when (type) {
                                                            3 -> {
                                                                binding.paymentPrinciple.setText(
                                                                    roomCost.toString()
                                                                )

                                                                paymentPrinciple = roomCost
                                                            }

                                                            4 -> {
                                                                binding.paymentPrinciple.setText(
                                                                    foodCost.toString()
                                                                )

                                                                paymentPrinciple = foodCost
                                                            }

                                                            5 -> {
                                                                binding.paymentPrinciple.setText(
                                                                    publicCost.toString()
                                                                )

                                                                paymentPrinciple = publicCost
                                                            }
                                                        }

                                                        for (item in OASystem.entryAndExitDetailResponse.currencys) {
                                                            if (item.currencyCode == currencyCode) {
                                                                rate = item.rate
                                                                binding.totalPayment.text =
                                                                    String.format(
                                                                        resources.getString(R.string.decimal_format),
                                                                        paymentPrinciple * rate
                                                                    )
                                                            }
                                                        }
                                                    }

                                                    popupWindow.dismiss()
                                                }
                                            }

                                        selectorContainer.setOnRefreshLoadMoreListener(object :
                                            OnRefreshLoadMoreListener {
                                            override fun onRefresh(p0: RefreshLayout) {
                                                entryAndExitPaymentPrincipleRequest.pageIndex = 1

                                                selector.adapter!!.notifyItemRangeRemoved(
                                                    0,
                                                    principleData.size
                                                )

                                                principleData.clear()

                                                getCityAndPaymentPrincipleData(2)
                                            }

                                            override fun onLoadMore(p0: RefreshLayout) {
                                                entryAndExitPaymentPrincipleRequest.pageIndex += 1

                                                getCityAndPaymentPrincipleData(3)
                                            }
                                        })

                                        searchText.addTextChangedListener(object : TextWatcher {
                                            override fun beforeTextChanged(
                                                p0: CharSequence?,
                                                p1: Int,
                                                p2: Int,
                                                p3: Int
                                            ) {

                                            }

                                            override fun onTextChanged(
                                                p0: CharSequence?,
                                                p1: Int,
                                                p2: Int,
                                                p3: Int
                                            ) {

                                            }

                                            override fun afterTextChanged(editable: Editable?) {

                                                adapter.notifyItemRangeRemoved(
                                                    0,
                                                    principleData.size
                                                )

                                                principleData.clear()

                                                entryAndExitPaymentPrincipleRequest.apply {
                                                    pageIndex = 1
                                                    search = editable.toString()
                                                }

                                                getCityAndPaymentPrincipleData(2)
                                            }
                                        })

                                        popupWindow.showAtLocation(
                                            binding.root,
                                            Gravity.BOTTOM,
                                            0,
                                            0
                                        )
                                    }

                                    selectorContainer.setEnableLoadMore(
                                        entryAndExitPaymentPrincipleRequest.pageIndex < getTotalPage(
                                            dataResponse.count
                                        )
                                    )
                                    selector.adapter!!.notifyItemInserted(0)
                                }

                                2 -> {
                                    selectorContainer.finishRefresh()
                                    selectorContainer.setEnableLoadMore(
                                        entryAndExitPaymentPrincipleRequest.pageIndex < getTotalPage(
                                            dataResponse.count
                                        )
                                    )
                                    selector.adapter!!.notifyItemInserted(0)
                                }

                                3 -> {
                                    selectorContainer.finishLoadMore()
                                    selectorContainer.setEnableLoadMore(
                                        entryAndExitPaymentPrincipleRequest.pageIndex < getTotalPage(
                                            dataResponse.count
                                        )
                                    )
                                    selector.adapter!!.notifyItemInserted(principleData.size)
                                }
                            }

                        } else {
                            showMessage(dataResponse.msg)
                        }
                    }
                }

                override fun onFailure(
                    p0: Call<EntryAndExitPaymentPrincipleResponse>,
                    p1: Throwable
                ) {
                    showErrorInfo(R.string.base_resource_data_get_failed)
                }
            })
    }

    private fun getTotalPage(count: Int): Int {
        var pageCount = count / 10

        if (count % 10 > 0) {
            pageCount += 1
        }

        return pageCount
    }

    private fun updateEntryAndExitPaymentDetail() {
        apiService.updateEntryAndExitPaymentDetail(updateEntryAndExitPaymentDetailRequest).enqueue(object : Callback<BaseResponse> {
            override fun onResponse(call: Call<BaseResponse>, response: Response<BaseResponse>) {

                val updateResponse = response.body()

                if (updateResponse != null) {
                    if (updateResponse.code == 200) {

                        showMessage(resources.getString(R.string.update_success))

                        OASystem.needRefresh = true

                        finish()

                    } else {
                        showMessage(updateResponse.msg)
                    }
                }

            }

            override fun onFailure(p0: Call<BaseResponse>, p1: Throwable) {
                showErrorInfo(R.string.update_error)
            }
        })
    }
}