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.widget.TextView
import androidx.core.content.res.ResourcesCompat
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.group_management.entry_and_exit_fee_detail.network.OtherPaymentDataSourceRequest
import com.pan_american.android.data.model.group_management.entry_and_exit_fee_detail.network.OtherPaymentDataSourceResponse
import com.pan_american.android.data.model.group_management.entry_and_exit_fee_detail.network.UpdateOtherPaymentRequest
import com.pan_american.android.data.network.APIService
import com.pan_american.android.data.network.ServiceCreator
import com.pan_american.android.databinding.ActivityOtherPaymentDetailBinding
import com.pan_american.android.databinding.LayoutTitleBinding
import com.pan_american.android.util.MoneyInputFilter
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class OtherPaymentDetailActivity : BaseActivity<ActivityOtherPaymentDetailBinding>() {

    private var fromList = false

    private var groupId = 0

    private lateinit var titleBinding: LayoutTitleBinding

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

    private val rateList = ArrayList<Selector>()

    private val paymentTypeList = ArrayList<Selector>()

    private var currencyRate = 0.0

    private val updateOtherPaymentRequest = UpdateOtherPaymentRequest()

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

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

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

        intent.apply {
            fromList = getBooleanExtra("fromList", false)
            updateOtherPaymentRequest.diid = getIntExtra("diId", 0)
            updateOtherPaymentRequest.index = getIntExtra("index", 0)

            groupId = updateOtherPaymentRequest.diid

            binding.index.text = updateOtherPaymentRequest.index.toString()
        }

        if (fromList) {
            intent.apply {
                updateOtherPaymentRequest.subId = getIntExtra("subId", 0)
                updateOtherPaymentRequest.setDataId = getIntExtra("setDataId", 0)

                binding.paymentType.text = getStringExtra("setDataName")

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

                binding.currency.text = getStringExtra("currencyName")

                updateOtherPaymentRequest.subTotal = getDoubleExtra("subTotal", 0.0)
                updateOtherPaymentRequest.remark = getStringExtra("remark").toString()
            }
        }

        initTitle()

        getOtherPaymentBaseData()

        initViews()
    }

    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)
        } else {
            binding.commit.text = resources.getString(R.string.add)
        }

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

        updateOtherPaymentRequest.apply {
            binding.paymentPrinciple.setText(cost.toString())
            binding.totalPayment.text = subTotal.toString()
            binding.remark.setText(remark)
        }

    }

    override fun initEvents() {
        binding.paymentType.setOnClickListener {

            showSelector {
                val adapter = ListAdapter.Builder<Selector>().apply {
                    setData(paymentTypeList)
                    setLayoutId(R.layout.item_selector)
                    addBindView { itemView, data ->
                        itemView.findViewById<TextView>(R.id.selector_item_name).apply {
                            if (updateOtherPaymentRequest.setDataId == 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) {
                        paymentTypeList[position].apply {
                            binding.paymentType.text = name
                            updateOtherPaymentRequest.setDataId = id

                            popupWindow.dismiss()
                        }
                    }
                }
            }
        }

        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() * currencyRate
                    )
                }
            }
        })

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

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

                selector.adapter = adapter

                adapter.onRecyclerViewItemClick = object : ListAdapter.OnRecyclerViewItemClick<Selector> {
                    override fun onItemClick(position: Int) {
                        rateList[position].apply {
                            binding.currency.text = currencyCode
                            updateOtherPaymentRequest.currency = currencyId
                            currencyRate = rate

                            binding.totalPayment.text = String.format(
                                resources.getString(R.string.decimal_format),
                                binding.paymentPrinciple.text.toString().toDouble() * currencyRate
                            )

                            popupWindow.dismiss()
                        }
                    }
                }
            }
        }

        binding.commit.setOnClickListener {

            if (updateOtherPaymentRequest.setDataId == 0) {
                showMessage(resources.getString(R.string.payment_type_select_hint))
                return@setOnClickListener
            }

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

            if (updateOtherPaymentRequest.currency == 0) {
                showMessage(resources.getString(R.string.payment_currency_hint))
                return@setOnClickListener
            }

            updateOtherPaymentRequest.subTotal = binding.totalPayment.text.toString().toDouble()

            if (binding.remark.getText().isNotBlank()) {
                updateOtherPaymentRequest.remark = binding.remark.getText()
            }

            updateOtherPayment()
        }
    }

    private fun getOtherPaymentBaseData() {
        apiService.getEntryAndExitOtherPaymentBaseData(OtherPaymentDataSourceRequest(diId = groupId))
            .enqueue(object : Callback<OtherPaymentDataSourceResponse> {
                override fun onResponse(
                    call: Call<OtherPaymentDataSourceResponse>,
                    response: Response<OtherPaymentDataSourceResponse>
                ) {
                    val dataResponse = response.body()

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

                            dataResponse.data.apply {
                                for (item in groupOtherRateData) {
                                    when(item.currencyCode) {
                                        "USD" -> {
                                            for (currency in OASystem.entryAndExitDetailResponse.currencys) {
                                                if (item.currencyCode == currency.currencyCode) {
                                                    item.rate = currency.rate
                                                }
                                            }
                                        }

                                        "EUR" -> {
                                            for (currency in OASystem.entryAndExitDetailResponse.currencys) {
                                                if (item.currencyCode == currency.currencyCode) {
                                                    item.rate = currency.rate
                                                }
                                            }
                                        }

                                        "GBP" -> {
                                            for (currency in OASystem.entryAndExitDetailResponse.currencys) {
                                                if (item.currencyCode == currency.currencyCode) {
                                                    item.rate = currency.rate
                                                }
                                            }
                                        }

                                        "JPY" -> {
                                            for (currency in OASystem.entryAndExitDetailResponse.currencys) {
                                                if (item.currencyCode == currency.currencyCode) {
                                                    item.rate = currency.rate
                                                }
                                            }
                                        }

                                        "HKD" -> {
                                            for (currency in OASystem.entryAndExitDetailResponse.currencys) {
                                                if (item.currencyCode == currency.currencyCode) {
                                                    item.rate = currency.rate
                                                }
                                            }
                                        }

                                        else -> {
                                            rateList.add(item)
                                        }
                                    }
                                }

                                for (item in otherFeeTypeData) {
                                    paymentTypeList.add(item)
                                }

                                for (item in rateList) {
                                    if (item.currencyId == updateOtherPaymentRequest.currency) {
                                        currencyRate = item.rate
                                        binding.currency.text = String.format(
                                            resources.getString(R.string.currency_name_code_format),
                                            item.currencyName,
                                            item.currencyCode
                                        )
                                    }
                                }

                                initEvents()
                            }

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

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

    private fun updateOtherPayment() {
        apiService.updateEntryAndExitOtherPayment(updateOtherPaymentRequest).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)
            }
        })
    }
}