package com.pan_american.android.ui.efficiency_tools.daily_payment

import android.os.Bundle
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
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.BaseRequest
import com.pan_american.android.base.BaseResponse
import com.pan_american.android.base.CardAdapter
import com.pan_american.android.base.CustomAlertDialog
import com.pan_american.android.base.ListAdapter
import com.pan_american.android.data.model.common.entity.Selector
import com.pan_american.android.data.model.daily_payment.entity.DailyPaymentDetail
import com.pan_american.android.data.model.daily_payment.entity.DailyPaymentListItem
import com.pan_american.android.data.model.daily_payment.network.AddDailyPaymentRequest
import com.pan_american.android.data.model.daily_payment.network.DailyPaymentDetailRequest
import com.pan_american.android.data.model.daily_payment.network.DailyPaymentDetailResponse
import com.pan_american.android.data.model.daily_payment.network.DailyPaymentSelectorItemResponse
import com.pan_american.android.data.model.daily_payment.network.UpdateDailyPaymentRequest
import com.pan_american.android.data.network.APIService
import com.pan_american.android.data.network.ServiceCreator
import com.pan_american.android.databinding.ActivityAddDailyPaymentBinding
import com.pan_american.android.databinding.LayoutTitleBinding
import com.pan_american.android.util.MoneyInputFilter
import com.pan_american.android.util.ScrollEditText
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import kotlin.math.roundToInt

class AddDailyPaymentActivity : BaseActivity<ActivityAddDailyPaymentBinding>() {

    private lateinit var titleBinding: LayoutTitleBinding

    val apiService = ServiceCreator.create<APIService>()

    private lateinit var paymentIdentifications: ArrayList<Selector>

    private lateinit var transferIdentification: ArrayList<Selector>

    private var companyList = ArrayList<Selector>()

    private var selectorList = ArrayList<Selector>()

    private var dailyPaymentList = ArrayList<DailyPaymentListItem>()

    //类型标识
    private var paymentIdentifyId = -1

    //转账标识
    private var transferIdentifyId = -1

    //公司ID标识
    private var companyId = -1

    //费用类型标识
    private var feeTypeId = -1

    //费用名称标识
    private var feeSubTypeId = -1

    //添加费用明细 PopupWindow 弹窗组件
    private lateinit var paymentItemName: EditText

    private lateinit var paymentItemCount: EditText

    private lateinit var paymentItemPrice: EditText

    private lateinit var paymentItemRemark: ScrollEditText

    private lateinit var commit: TextView

    private var itemCount = 0

    private var totalPayment: Double = 0.00

    private var fromList = false

    private var dailyPaymentId = 0

    private lateinit var dailyPaymentDetail: DailyPaymentDetail

    private var financeStatus = -1

    private var managerStatus = -1

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

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

        fromList = intent.getBooleanExtra("from_list", false)

        if (fromList) {
            //来自列表，获取日付item ID
            dailyPaymentId = intent.getIntExtra("daily_payment_id", 0)
            financeStatus = intent.getIntExtra("finance_status", -1)
            managerStatus = intent.getIntExtra("manager_status", -1)
        }

        initTitle()
        initViews()
        //获取类型标识、转账标识和公司列表再初始化界面
        getSelectorItem()
    }

    override fun initTitle() {

        titleBinding = LayoutTitleBinding.bind(binding.root).apply {

            if (fromList) {
                titleText.text = resources.getString(R.string.daily_payment_detail)
            } else {
                titleBinding = LayoutTitleBinding.bind(binding.root).apply {
                    titleText.text = resources.getString(R.string.add_daily_payment)
                }
            }

            backButton.setOnClickListener {
                back()
            }
        }
    }

    override fun initViews() {

        if (fromList) {
            if (canBeEdit()) {
                binding.commit.setText(resources.getString(R.string.update))
            } else {
                binding.paymentIdentification.isEnabled = false
                binding.transferIdentification.isEnabled = false
                binding.applicationCompany.isEnabled = false
                binding.paymentType.isEnabled = false
                binding.paymentName.isEnabled = false
                binding.paymentNotes.isEnabled(false)
                binding.addPaymentItem.visibility = View.GONE

                binding.commit.setText(resources.getString(R.string.back))
            }

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

            setTotalPayment()
        }
    }

    override fun initEvents() {

        binding.paymentIdentification.setOnClickListener {
            showSelector {
                val adapter = ListAdapter.Builder<Selector>().apply {
                    setData(paymentIdentifications)
                    setLayoutId(R.layout.item_selector)
                    addBindView { itemView, data ->
                        itemView.findViewById<TextView>(R.id.selector_item_name).apply {
                            text = data.name

                            if (paymentIdentifyId == 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) {

                            binding.paymentIdentification.text =
                                paymentIdentifications[position].name
                            paymentIdentifyId = paymentIdentifications[position].id

                            popupWindow.dismiss()
                        }
                    }
            }
        }

        binding.transferIdentification.setOnClickListener {

            selectorList.clear()

            if (paymentIdentifyId == 0) {
                showMessage(resources.getString(R.string.payment_identification_select_hint))
                return@setOnClickListener
            }

            for (item in transferIdentification) {
                if (item.sTid == paymentIdentifyId) {
                    selectorList.add(item)
                }
            }

            if (selectorList.size == 0) {
                showMessage(resources.getString(R.string.no_sub_type))
                return@setOnClickListener
            }

            showSelector {
                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 = data.name

                            if (transferIdentifyId == 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) {
                            binding.transferIdentification.text = selectorList[position].name
                            transferIdentifyId = selectorList[position].id

                            popupWindow.dismiss()
                        }
                    }
            }
        }

        binding.applicationCompany.setOnClickListener {
            showSelector {
                val adapter = ListAdapter.Builder<Selector>().apply {
                    setData(companyList)
                    setLayoutId(R.layout.item_selector)
                    addBindView { itemView, data ->
                        itemView.findViewById<TextView>(R.id.selector_item_name).apply {
                            text = data.name

                            if (companyId == 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) {
                            binding.applicationCompany.text = companyList[position].name
                            companyId = companyList[position].id

                            popupWindow.dismiss()
                        }
                    }
            }
        }

        binding.paymentType.setOnClickListener {
            showSelector {
                val adapter = ListAdapter.Builder<Selector>().apply {
                    setData(OASystem.paymentType)
                    setLayoutId(R.layout.item_selector)
                    addBindView { itemView, data ->
                        itemView.findViewById<TextView>(R.id.selector_item_name).apply {
                            text = data.name

                            if (feeTypeId == 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) {
                            binding.paymentType.text = OASystem.paymentType[position].name
                            feeTypeId = OASystem.paymentType[position].id

                            popupWindow.dismiss()
                        }
                    }
            }
        }

        binding.paymentName.setOnClickListener {

            selectorList.clear()

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

            for (item in OASystem.paymentSubType) {
                if (item.sTid == feeTypeId) {
                    selectorList.add(item)
                }
            }

            if (selectorList.size == 0) {
                showMessage(resources.getString(R.string.no_sub_type))
                return@setOnClickListener
            }

            showSelector {
                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 = data.name

                            if (feeSubTypeId == 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) {
                            binding.paymentName.text = selectorList[position].name
                            feeSubTypeId = selectorList[position].id

                            popupWindow.dismiss()
                        }
                    }
            }
        }

        binding.addPaymentItem.setOnClickListener {
            initPopupWindow {

                paymentItemPrice.filters = arrayOf(MoneyInputFilter())

                commit.setOnClickListener {
                    if (paymentItemName.text.trim().isEmpty() || paymentItemCount.text.trim()
                            .isEmpty() || paymentItemPrice.text.trim().isEmpty()
                    ) {
                        showMessage(resources.getString(R.string.payment_item_hint))
                    } else {
                        val regex = Regex("^-?\\d+(\\.\\d{1,2})?\$")
                        if (!paymentItemPrice.text.toString().matches(regex)) {
                            showMessage(resources.getString(R.string.payment_price_hint))
                        } else {
                            dailyPaymentList.add(
                                DailyPaymentListItem(
                                    paymentItemName.text.toString(),
                                    paymentItemCount.text.toString().toDouble(),
                                    paymentItemPrice.text.toString().toDouble(),
                                    paymentItemCount.text.toString()
                                        .toDouble() * paymentItemPrice.text.toString().toDouble(),
                                    paymentItemRemark.getText().trim()
                                )
                            )
                            initList()
                            totalPayment += dailyPaymentList[itemCount].itemTotal
                            itemCount += 1
                            setTotalPayment()
                            popupWindow.dismiss()
                        }
                    }
                }
            }
        }

        binding.commit.setOnClickListener {

            if (fromList) {
                if (!canBeEdit()) {
                    back()
                    return@setOnClickListener
                }
            }

            if (OASystem.userInfo.userId != dailyPaymentDetail.createUserId) {
                showMessage(resources.getString(R.string.daily_payment_userId_error))
                return@setOnClickListener
            }

            when {
                paymentIdentifyId == -1 -> {
                    showMessage(resources.getString(R.string.payment_identification_select_hint))
                }

                transferIdentifyId == -1 -> {
                    showMessage(resources.getString(R.string.transfer_identification_select_hint))
                }

                companyId == -1 -> {
                    showMessage(resources.getString(R.string.company_select_hint))
                }

                feeTypeId == -1 -> {
                    showMessage(resources.getString(R.string.payment_type_select_hint))
                }

                feeSubTypeId == -1 -> {
                    showMessage(resources.getString(R.string.payment_name_select_hint))
                }

                binding.paymentNotes.getText().trim().isEmpty() -> {
                    showMessage(resources.getString(R.string.payment_notes_hint))
                }

                dailyPaymentList.size == 0 -> {
                    showMessage(resources.getString(R.string.payment_item_add_hint))
                }

                else -> {

                    binding.commit.setButtonStatus(1)

                    if (fromList) {
                        updateDailyPayment()
                    } else {
                        addDailyPayment()
                    }
                }
            }
        }
    }

    private fun getSelectorItem() {
        apiService.getDailyPaymentSelectorItems(BaseRequest())
            .enqueue(object : Callback<DailyPaymentSelectorItemResponse> {
                override fun onResponse(
                    call: Call<DailyPaymentSelectorItemResponse>,
                    response: Response<DailyPaymentSelectorItemResponse>
                ) {
                    val dailyPaymentSelectorItemResponse = response.body()
                    if (dailyPaymentSelectorItemResponse != null) {
                        if (dailyPaymentSelectorItemResponse.code == 200) {

                            dailyPaymentSelectorItemResponse.data.companyNameData.forEach {
                                val selector = Selector()
                                selector.name = it.companyName
                                selector.id = it.id
                                companyList.add(selector)
                            }

                            paymentIdentifications =
                                dailyPaymentSelectorItemResponse.data.feeTypeData
                            transferIdentification =
                                dailyPaymentSelectorItemResponse.data.feeTypeSubData

                            if (fromList) {
                                //根据ID获取日付item详情
                                getDailyPaymentFromId(dailyPaymentId)
                            }

                            initEvents()

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

                override fun onFailure(call: Call<DailyPaymentSelectorItemResponse>, t: Throwable) {
                    showErrorInfo(R.string.base_resource_data_get_failed)
                }
            })
    }

    private fun setTotalPayment() {

        totalPayment = (totalPayment * 100).roundToInt() / 100.00

        binding.paymentTotal.text =
            String.format(resources.getString(R.string.rmb_price), totalPayment)
    }

    private fun initPopupWindow(block: () -> Unit) {
        val popView = View.inflate(this, R.layout.popup_add_daily_payment, null)
        popupWindow = PopupWindow(
            popView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT
        )

        showPopupWindow {

            paymentItemName = popView.findViewById(R.id.left_text)
            paymentItemCount = popView.findViewById(R.id.payment_item_counts)
            paymentItemPrice = popView.findViewById(R.id.right_text)
            paymentItemRemark = popView.findViewById(R.id.payment_remark)
            commit = popView.findViewById(R.id.commit)

            block()

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

    private fun initList() {
        val layoutManager = LinearLayoutManager(OASystem.context)
        binding.paymentItemList.layoutManager = layoutManager

        val adapter = CardAdapter.Builder<DailyPaymentListItem>().apply {
            setLayoutId(R.layout.item_delete_button_selector)
            setData(dailyPaymentList)
            setCanDelete(canBeEdit())
            addBindView { itemView, data ->
                itemView.findViewById<TextView>(R.id.left_text).text = data.priceName
                itemView.findViewById<TextView>(R.id.right_text).text =
                    String.format(resources.getString(R.string.rmb_price), data.itemTotal)
            }
        }.create()

        binding.paymentItemList.adapter = adapter

        adapter.onRecyclerViewItemClick =
            object : CardAdapter.OnRecyclerViewItemClick<DailyPaymentListItem> {
                override fun onItemClick(position: Int) {

                    val item = dailyPaymentList[position]

                    initPopupWindow {
                        paymentItemName.setText(item.priceName)
                        paymentItemName.isEnabled = false

                        paymentItemCount.setText(item.quantity.toString())
                        paymentItemCount.isEnabled = false

                        paymentItemPrice.setText(
                            String.format(
                                resources.getString(R.string.rmb_price), item.price
                            )
                        )
                        paymentItemPrice.isEnabled = false

                        if (item.remark.isBlank()) {
                            paymentItemRemark.setText(resources.getString(R.string.none))
                        } else {
                            paymentItemRemark.setText(item.remark)
                        }

                        paymentItemRemark.isEnabled(false)

                        commit.setOnClickListener {
                            popupWindow.dismiss()
                        }
                    }

                }

                override fun onItemDelete(position: Int) {

                    CustomAlertDialog.Builder(OASystem.context).apply {
                        setTitle(resources.getString(R.string.alert))
                        setMessage(resources.getString(R.string.payment_item_delete_alert))
                        setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
                            dialog.dismiss()
                        }
                        setPositiveButtonAndListener(resources.getString(R.string.confirm)) { _, _ ->
                            deletePaymentItem(position)
                        }
                        setCancelable(false)
                    }.show()
                }

            }
    }

    private fun deletePaymentItem(position: Int) {
        totalPayment -= dailyPaymentList[position].itemTotal

        dailyPaymentList.removeAt(position)
        binding.paymentItemList.adapter!!.notifyItemRemoved(position)
        binding.paymentItemList.adapter!!.notifyItemRangeChanged(position, dailyPaymentList.size)

        itemCount -= 1

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

        setTotalPayment()
    }

    private fun addDailyPayment() {

        apiService.addDailyPayment(
            AddDailyPaymentRequest(
                binding.paymentNotes.getText().trim(),
                totalPayment,
                transferIdentifyId,
                feeSubTypeId,
                companyId,
                dailyPaymentList
            )
        ).enqueue(object : Callback<BaseResponse> {
            override fun onResponse(call: Call<BaseResponse>, response: Response<BaseResponse>) {
                val baseResponse = response.body()
                if (baseResponse != null) {
                    if (baseResponse.code == 200) {
                        showMessage(resources.getString(R.string.insert_success))

                        OASystem.needRefresh = true

                        back()
                    } else {

                        binding.commit.setButtonStatus(0)

                        showMessage(baseResponse.msg)
                    }
                }
            }

            override fun onFailure(call: Call<BaseResponse>, t: Throwable) {

                binding.commit.setButtonStatus(0)

                showMessage(resources.getString(R.string.network_error))
            }
        })
    }

    private fun getDailyPaymentFromId(id: Int) {
        apiService.getDailyPaymentDetail(DailyPaymentDetailRequest(id))
            .enqueue(object : Callback<DailyPaymentDetailResponse> {
                override fun onResponse(
                    call: Call<DailyPaymentDetailResponse>,
                    response: Response<DailyPaymentDetailResponse>
                ) {
                    val dailyPaymentDetailResponse = response.body()
                    if (dailyPaymentDetailResponse != null) {
                        if (dailyPaymentDetailResponse.code == 200) {
                            dailyPaymentDetail = dailyPaymentDetailResponse.data

                            //申请名称
                            binding.paymentNotes.setText(dailyPaymentDetail.instructions)

                            //类型标识、转账标识
                            for (transferItem in transferIdentification) {
                                if (transferItem.id == dailyPaymentDetail.transferTypeId) {

                                    for (paymentItem in paymentIdentifications) {
                                        if (transferItem.sTid == paymentItem.id) {
                                            paymentIdentifyId = paymentItem.id
                                            binding.paymentIdentification.text = paymentItem.name
                                        }
                                    }

                                    transferIdentifyId = transferItem.id
                                    binding.transferIdentification.text = transferItem.name
                                }
                            }

                            //公司名称
                            run {
                                for (companyItem in companyList) {
                                    if (companyItem.id == dailyPaymentDetail.companyId) {
                                        companyId = companyItem.id
                                        binding.applicationCompany.text = companyItem.name
                                        return@run
                                    }
                                }
                            }

                            //费用类型、费用名称
                            for (feeSubType in OASystem.paymentSubType) {
                                if (feeSubType.id == dailyPaymentDetail.priceTypeId) {

                                    for (feeTypeItem in OASystem.paymentType) {
                                        if (feeSubType.sTid == feeTypeItem.id) {
                                            feeTypeId = feeTypeItem.id
                                            binding.paymentType.text = feeTypeItem.name
                                        }
                                    }

                                    feeSubTypeId = feeSubType.id
                                    binding.paymentName.text = feeSubType.name
                                }
                            }

                            //费用项目数量
                            itemCount = dailyPaymentDetail.feeContents.size

                            //总金额
                            totalPayment = dailyPaymentDetail.sumPrice
                            setTotalPayment()

                            //费用项目
                            dailyPaymentList = dailyPaymentDetail.feeContents
                            initList()

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

                override fun onFailure(call: Call<DailyPaymentDetailResponse>, t: Throwable) {
                    showErrorInfo(R.string.daily_payment_detail_get_failed)
                }
            })
    }

    private fun updateDailyPayment() {

        apiService.updateDailyPaymentDetail(
            UpdateDailyPaymentRequest(
                dailyPaymentId,
                binding.paymentNotes.getText().trim(),
                totalPayment,
                transferIdentifyId,
                feeSubTypeId,
                companyId,
                dailyPaymentList
            )
        ).enqueue(object : Callback<BaseResponse> {
            override fun onResponse(call: Call<BaseResponse>, response: Response<BaseResponse>) {

                val baseResponse = response.body()

                if (baseResponse != null) {
                    if (baseResponse.code == 200) {
                        showMessage(resources.getString(R.string.update_success))

                        OASystem.needRefresh = true

                        back()
                    } else {

                        binding.commit.setButtonStatus(0)

                        showMessage(baseResponse.msg)
                    }
                }
            }

            override fun onFailure(call: Call<BaseResponse>, t: Throwable) {

                binding.commit.setButtonStatus(0)

                showMessage(resources.getString(R.string.network_error))
            }
        })
    }

    private fun canBeEdit(): Boolean {
        return if (fromList) {
            OASystem.authorization(OASystem.DAILY_PAYMENT, OASystem.EDIT) and (financeStatus != 1) and (managerStatus != 1)
        } else {
            true
        }
    }
}