package com.pan_american.android.ui.financial_module.collection_bill

import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.Gravity
import android.view.View
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 androidx.recyclerview.widget.RecyclerView
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.common.entity.Selector
import com.pan_american.android.data.model.financial_module.collection_bill.entity.CollectionBillItem
import com.pan_american.android.data.model.financial_module.collection_bill.network.CollectionBillCurrencyListRequest
import com.pan_american.android.data.model.financial_module.collection_bill.network.CollectionBillCurrencyListResponse
import com.pan_american.android.data.model.financial_module.collection_bill.network.UpdateCollectionBillRequest
import com.pan_american.android.data.network.APIService
import com.pan_american.android.data.network.ServiceCreator
import com.pan_american.android.databinding.ActivityAddCollectionBillPaymentBinding
import com.pan_american.android.databinding.LayoutTitleBinding
import com.pan_american.android.util.MoneyInputFilter
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class AddCollectionBillPaymentActivity : BaseActivity<ActivityAddCollectionBillPaymentBinding>() {

    private var fromList = false

    private lateinit var titleBinding: LayoutTitleBinding

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

    private val currencyList = ArrayList<Selector>()

    private val collectionBillItem = CollectionBillItem()

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

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

        intent.apply {
            fromList = getBooleanExtra("fromList", false)
            collectionBillItem.diid = getIntExtra("groupId", 0)
        }

        if (fromList) {
            intent.apply {
                collectionBillItem.let {
                    it.id = getIntExtra("paymentId", 0)
                    it.priceName = getStringExtra("paymentName").toString()
                    it.addingWay = getIntExtra("paymentMode", 0)
                    it.price = getDoubleExtra("perPrice", 0.0)
                    it.currency = getIntExtra("currencyId", 0)
                    it.currencyStr = getStringExtra("currencyStr").toString()
                    it.count = getIntExtra("count", 0)
                    it.unit = getStringExtra("unit").toString()
                    it.rate = getDoubleExtra("exchangeRate", 0.0)
                    it.remark = getStringExtra("remark").toString()
                    it.itemSumPrice = getDoubleExtra("sumPrice", 0.0)
                }
            }
        }

        initTitle()

        initViews()

        getBaseDataResource()
    }

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

            backButton.setOnClickListener {
                back()
            }
        }
    }

    override fun initViews() {

        binding.perPrice.filters = arrayOf(MoneyInputFilter())
        binding.exchangeRate.filters = arrayOf(MoneyInputFilter(pointLength = 4))

        if (fromList) {

            collectionBillItem.apply {
                binding.paymentName.setText(priceName)

                for (item in OASystem.addMode) {
                    if (item.id == addingWay) {
                        binding.addMode.text = item.name
                    }
                }

                binding.perPrice.setText(price.toString())

                binding.paymentCurrency.text = currencyStr

                binding.count.setText(count.toString())

                binding.unit.setText(unit)

                binding.exchangeRate.setText(rate.toString())

                binding.notes.setText(remark)

                binding.totalPrice.text = itemSumPrice.toString()
            }

            binding.commit.setText(resources.getString(R.string.update))
        } else {
            binding.commit.setText(resources.getString(R.string.add))
        }
    }

    override fun initEvents() {

        binding.addMode.setOnClickListener {
            showSelector {
                val adapter = ListAdapter.Builder<Selector>().apply {
                    setData(OASystem.addMode)
                    setLayoutId(R.layout.item_selector)
                    addBindView { itemView, data ->
                        itemView.findViewById<TextView>(R.id.selector_item_name).apply {
                            if (collectionBillItem.addingWay == data.id) {
                                setTextColor(ResourcesCompat.getColor(resources, R.color.text_color_blue, null))
                            } else {
                                setTextColor(ResourcesCompat.getColor(resources, R.color.text_color, null))
                            }

                            text = data.name
                        }
                    }
                }.create()

                selector.adapter = adapter

                adapter.onRecyclerViewItemClick = object : ListAdapter.OnRecyclerViewItemClick<Selector> {
                    override fun onItemClick(position: Int) {
                        OASystem.addMode[position].apply {
                            binding.addMode.text = name
                            collectionBillItem.addingWay = id
                        }

                        popupWindow.dismiss()
                    }
                }
            }
        }

        binding.perPrice.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

            }

            override fun afterTextChanged(s: Editable?) {
                if (s.toString().isBlank()) {
                    showMessage(resources.getString(R.string.payment_price_hint))
                    return
                }

                if (s.toString().endsWith('.')) {
                    return
                }

                collectionBillItem.price = s.toString().toDouble()

                calculateSumPrice()
            }
        })

        binding.count.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

            }

            override fun afterTextChanged(s: Editable?) {
                if (s.toString().isBlank()) {
                    showMessage(resources.getString(R.string.count_input_hint))
                    return
                }

                if (s.toString().toInt() == 0) {
                    binding.count.setText("1")
                }

                collectionBillItem.count = s.toString().toInt()

                calculateSumPrice()
            }
        })

        binding.exchangeRate.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

            }

            override fun afterTextChanged(s: Editable?) {
                if (s.toString().isBlank()) {
                    showMessage(resources.getString(R.string.exchange_rate_input_hint))
                    return
                }

                if (s.toString().endsWith('.')) {
                    return
                }

                collectionBillItem.rate = s.toString().toDouble()

                calculateSumPrice()
            }
        })

        binding.paymentCurrency.setOnClickListener {
            val selectorList = ArrayList<Selector>()

            for (item in currencyList) {
                selectorList.add(item)
            }

            val popView = View.inflate(OASystem.context, R.layout.popup_smart_refresh_selector, null)
            popupWindow = PopupWindow(popView, RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.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(false)
                selectorContainer.setEnableLoadMore(false)

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

                val adapter = ListAdapter.Builder<Selector>().apply {
                    setData(selectorList)
                    setLayoutId(R.layout.item_selector)
                    addBindView { itemView, data ->
                        itemView.findViewById<TextView>(R.id.selector_item_name).apply {
                            text = String.format(resources.getString(R.string.currency_name_code_format), data.remark, data.name)

                            if (collectionBillItem.currency == 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<Selector> {
                        override fun onItemClick(position: Int) {
                            selectorList[position].apply {
                                binding.paymentCurrency.text = name

                                collectionBillItem.currency = id

                                popupWindow.dismiss()
                            }
                        }
                    }

                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, selectorList.size)

                        selectorList.clear()

                        if (editable.isNullOrBlank()) {

                            for (item in currencyList) {
                                selectorList.add(item)
                            }

                        } else {
                            for (i in 0 until currencyList.size) {
                                currencyList[i].apply {
                                    if (name.contains(editable) || remark.contains(editable)) {
                                        selectorList.add(this)
                                    }
                                }
                            }
                        }

                        if (selectorList.size == 0) {
                            showMessage(resources.getString(R.string.no_data))
                        } else {
                            for (i in 0 until selectorList.size) {
                                adapter.notifyItemInserted(i)
                            }
                        }
                    }
                })

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

        binding.commit.setOnClickListener {
            if (binding.paymentName.text.isNullOrBlank()) {
                showMessage(resources.getString(R.string.payment_name_input_hint))
                return@setOnClickListener
            } else {
                collectionBillItem.priceName = binding.paymentName.text.toString()
            }

            if (collectionBillItem.addingWay == -1) {
                showMessage(resources.getString(R.string.add_way_select_hint))
                return@setOnClickListener
            }

            if (collectionBillItem.price == 0.0) {
                showMessage(resources.getString(R.string.payment_price_hint))
                return@setOnClickListener
            }

            if (collectionBillItem.currency == -1) {
                showMessage(resources.getString(R.string.payment_currency_hint))
                return@setOnClickListener
            }

            if (collectionBillItem.count == 0) {
                showMessage(resources.getString(R.string.count_input_hint))
                return@setOnClickListener
            }

            if (binding.unit.text.toString().isBlank()) {
                showMessage(resources.getString(R.string.unit_input_hint))
                return@setOnClickListener
            } else {
                collectionBillItem.unit = binding.unit.text.toString()
            }

            if (collectionBillItem.rate == 0.0) {
                showMessage(resources.getString(R.string.exchange_rate_input_hint))
                return@setOnClickListener
            }

            if (binding.notes.getText().isNotBlank()) {
                collectionBillItem.remark = binding.notes.getText()
            }

            updateCollectionBill()
        }
    }

    private fun getBaseDataResource() {
        apiService.getCollectionBillCurrencyList(CollectionBillCurrencyListRequest()).enqueue(object : Callback<CollectionBillCurrencyListResponse> {
            override fun onResponse(
                call: Call<CollectionBillCurrencyListResponse>,
                response: Response<CollectionBillCurrencyListResponse>
            ) {
                val currencyResponse = response.body()

                if (currencyResponse != null) {
                    if (currencyResponse.code == 200) {
                        for (item in currencyResponse.data.currencyData) {
                            currencyList.add(item)
                        }

                        initEvents()
                    }
                }
            }

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

    private fun updateCollectionBill() {
        val updateCollectionBillRequest = UpdateCollectionBillRequest().also {
            collectionBillItem.apply {
                it.diId = diid
                it.id = id
                it.priceName = priceName
                it.price = price
                it.count = count
                it.unit = unit
                it.itemSumPrice = itemSumPrice
                it.rate = rate
                it.currency = currency
                it.addingWay = addingWay
                it.remark = remark
            }
        }

        apiService.updateCollectionBillPayment(updateCollectionBillRequest).enqueue(object : Callback<BaseResponse> {
            override fun onResponse(p0: 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)
            }
        })
    }

    private fun calculateSumPrice() {
        val sumPrice = collectionBillItem.price * collectionBillItem.rate * collectionBillItem.count

        collectionBillItem.itemSumPrice = sumPrice

        binding.totalPrice.text = collectionBillItem.itemSumPrice.toString()
    }
}