package com.pan_american.android.ui.group_common.bill_management

import android.content.Intent
import android.net.Uri
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.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.common.entity.SimpleGroupInfo
import com.pan_american.android.data.model.common.network.DeleteRequest
import com.pan_american.android.data.model.common.network.QuerySetDataRequest
import com.pan_american.android.data.model.common.network.SelectorResponse
import com.pan_american.android.data.model.common.network.SimpleGroupInfoRequest
import com.pan_american.android.data.model.common.network.SimpleGroupInfoResponse
import com.pan_american.android.data.model.group_common_modle.bill_management.adapter.BillFileItemAdapter
import com.pan_american.android.data.model.group_common_modle.bill_management.entity.BillFileListItem
import com.pan_american.android.data.model.group_common_modle.bill_management.network.BillFileDownloadAllRequest
import com.pan_american.android.data.model.group_common_modle.bill_management.network.BillFileDownloadAllResponse
import com.pan_american.android.data.model.group_common_modle.bill_management.network.BillFileDownloadThisModelRequest
import com.pan_american.android.data.model.group_common_modle.bill_management.network.BillFileDownloadThisModelResponse
import com.pan_american.android.data.model.group_common_modle.bill_management.network.BillFileListRequest
import com.pan_american.android.data.model.group_common_modle.bill_management.network.BillFileListResponse
import com.pan_american.android.data.network.APIService
import com.pan_american.android.data.network.ServiceCreator
import com.pan_american.android.databinding.ActivityBillManagementBinding
import com.pan_american.android.databinding.LayoutTitleBinding
import com.scwang.smart.refresh.header.ClassicsHeader
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 BillManagementActivity : BaseActivity<ActivityBillManagementBinding>() {

    private lateinit var titleBinding: LayoutTitleBinding

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

    private val paymentPlateList = ArrayList<Selector>()

    private var selectedPaymentPlateId = 0

    private val simpleGroupInfoList = ArrayList<SimpleGroupInfo>()

    private val simpleGroupInfoRequest = SimpleGroupInfoRequest()

    private var selectedGroupNameId = 0

    private val billFileList = ArrayList<BillFileListItem>()

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

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

        initTitle()

        //获取基础数据源
        initGroupName()
    }

    override fun initTitle() {

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

            titleText.text = resources.getString(R.string.bill_management)

            backButton.setOnClickListener {
                back()
            }
        }

    }

    override fun initViews() {
        binding.billManagementListContainer.setRefreshHeader(ClassicsHeader(OASystem.context))
        binding.billManagementListContainer.setEnableRefresh(true)
        binding.billManagementListContainer.setEnableLoadMore(false)

        if (hasPermission()) {
            binding.downloadAllModelBill.visibility = View.VISIBLE
            binding.downloadThisModelBill.visibility = View.VISIBLE
        }

        getBillList()
    }

    override fun initEvents() {

        binding.groupName.setOnClickListener {
            simpleGroupInfoRequest.apply {
                pageIndex = 1
                pageSize = 10
                search = ""
            }

            simpleGroupInfoList.clear()

            getSimpleGroupInfoResource(1)
        }

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

                            text = data.name

                            if (binding.paymentPlate.text == data.name) {
                                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) {
                        paymentPlateList[position].apply {
                            binding.paymentPlate.text = name

                            selectedPaymentPlateId = id

                            getBillList()

                            popupWindow.dismiss()
                        }
                    }
                }
            }
        }

        binding.downloadAllModelBill.setOnClickListener {
            CustomAlertDialog.Builder().apply {
                setTitle(resources.getString(R.string.confirm))
                setMessage(String.format(resources.getString(R.string.bill_file_all_model_download_hint), binding.groupName.text))
                setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
                    dialog.dismiss()
                }
                setPositiveButtonAndListener(resources.getString(R.string.confirm)) { _, _ ->
                    downloadAllFile()
                }
            }.show()
        }

        binding.downloadThisModelBill.setOnClickListener {
            CustomAlertDialog.Builder().apply {
                setTitle(resources.getString(R.string.confirm))
                setMessage(String.format(resources.getString(R.string.bill_file_this_model_download_hint), binding.groupName.text, binding.paymentPlate.text))
                setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
                    dialog.dismiss()
                }
                setPositiveButtonAndListener(resources.getString(R.string.confirm)) { _, _ ->
                    downloadThisModelFile()
                }
            }.show()
        }
    }

    private fun initGroupName() {
        simpleGroupInfoRequest.apply {
            pageIndex = 1
            pageSize = 3
            search = ""
        }

        simpleGroupInfoList.clear()

        getSimpleGroupInfoResource(0)
    }

    private fun getSimpleGroupInfoResource(type: Int) {
        apiService.getGroupNameWithSearch(simpleGroupInfoRequest).enqueue(object : Callback<SimpleGroupInfoResponse> {
            override fun onResponse(p0: Call<SimpleGroupInfoResponse>, response: Response<SimpleGroupInfoResponse>) {
                val resourceResponse = response.body()

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

                        for (item in resourceResponse.data) {
                            simpleGroupInfoList.add(item)
                        }

                        when(type) {

                            0 -> {
                                binding.groupName.text = simpleGroupInfoList[0].name

                                selectedGroupNameId = simpleGroupInfoList[0].id

                                initGroupPlate()
                            }

                            1 -> {

                                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(true)
                                    selectorContainer.setEnableLoadMore(true)

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

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

                                                if (binding.groupName.text == data.name) {
                                                    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<SimpleGroupInfo> {
                                            override fun onItemClick(position: Int) {
                                                simpleGroupInfoList[position].apply {
                                                    binding.groupName.text = name

                                                    selectedGroupNameId = id

                                                    getBillList()

                                                    popupWindow.dismiss()
                                                }
                                            }
                                        }

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

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

                                            simpleGroupInfoList.clear()

                                            getSimpleGroupInfoResource(2)
                                        }

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

                                            getSimpleGroupInfoResource(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, simpleGroupInfoList.size)

                                            simpleGroupInfoList.clear()

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

                                            getSimpleGroupInfoResource(2)
                                        }
                                    })

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

                                selectorContainer.setEnableLoadMore(simpleGroupInfoRequest.pageIndex < getTotalPage(resourceResponse.count))
                                selector.adapter!!.notifyItemInserted(0)
                            }

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

                            3 -> {
                                selectorContainer.finishLoadMore()
                                selectorContainer.setEnableLoadMore(simpleGroupInfoRequest.pageIndex < getTotalPage(resourceResponse.count))
                                selector.adapter!!.notifyItemInserted(simpleGroupInfoList.size)
                            }
                        }

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

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

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

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

        return pageCount
    }

    private fun initGroupPlate() {
        apiService.querySetData(QuerySetDataRequest(16)).enqueue(object : Callback<SelectorResponse> {
            override fun onResponse(
                call: Call<SelectorResponse>,
                response: Response<SelectorResponse>
            ) {
                val selectorResponse = response.body()

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

                        for (item in selectorResponse.data) {
                            paymentPlateList.add(item)
                        }

                        binding.paymentPlate.text = paymentPlateList[0].name

                        selectedPaymentPlateId = paymentPlateList[0].id

                        initViews()

                        initEvents()

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

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

    private fun getBillList() {

        val billFileListRequest = BillFileListRequest().apply {
            ctable = selectedPaymentPlateId
            diid = selectedGroupNameId
            userId = if (hasPermission()) {
                -1
            } else {
                OASystem.userInfo.userId
            }
        }

        if (billFileList.size > 0) {
            binding.billManagementList.adapter!!.notifyItemRangeRemoved(0, billFileList.size)
            billFileList.clear()
        }

        apiService.getBillFileList(billFileListRequest).enqueue(object : Callback<BillFileListResponse> {
            override fun onResponse(
                call: Call<BillFileListResponse>,
                response: Response<BillFileListResponse>
            ) {
                val listResponse = response.body()

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

                        if (binding.billManagementListContainer.isRefreshing) {
                            binding.billManagementListContainer.finishRefresh()
                        }

                        for (item in listResponse.data) {
                            billFileList.add(item)
                        }

                        initList()

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

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

    private fun initList() {

        if (billFileList.size == 0) {
            showMessage(resources.getString(R.string.no_data))
            return
        }

        val layoutManager = LinearLayoutManager(OASystem.context)
        binding.billManagementList.layoutManager = layoutManager

        val adapter = BillFileItemAdapter(billFileList)

        binding.billManagementList.adapter = adapter

        adapter.onRecyclerViewItemClick = object : BillFileItemAdapter.OnRecyclerViewItemClick<BillFileListItem> {
            override fun downLoad(position: Int) {
                CustomAlertDialog.Builder().apply {
                    setTitle(resources.getString(R.string.confirm))
                    setMessage(String.format(resources.getString(R.string.bill_file_download_hint), billFileList[position].fileName))
                    setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
                        dialog.dismiss()
                    }
                    setPositiveButtonAndListener(resources.getString(R.string.confirm)) { _, _ ->
                        val uri = Uri.parse(billFileList[position].url)
                        startActivity(Intent(Intent.ACTION_VIEW, uri))
                    }
                }.show()
            }

            override fun delete(position: Int) {
                CustomAlertDialog.Builder().apply {
                    setTitle(resources.getString(R.string.alert))
                    setMessage(String.format(resources.getString(R.string.bill_file_delete_hint), billFileList[position].fileName))
                    setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
                        dialog.dismiss()
                    }
                    setPositiveButtonAndListener(resources.getString(R.string.confirm)) { _, _ ->
                        deleteBillFile(position)
                    }
                }.show()
            }
        }

        binding.billManagementListContainer.setOnRefreshListener {
            binding.billManagementList.adapter!!.notifyItemRangeRemoved(0, billFileList.size)
            billFileList.clear()
            getBillList()
        }

    }

    private fun deleteBillFile(position: Int) {
        apiService.deleteBillFile(DeleteRequest(billFileList[position].id)).enqueue(object : Callback<BaseResponse> {
            override fun onResponse(call: Call<BaseResponse>, response: Response<BaseResponse>) {
                val deleteResponse = response.body()

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

                        billFileList.removeAt(position)
                        binding.billManagementList.adapter!!.notifyItemRemoved(position)
                        binding.billManagementList.adapter!!.notifyItemRangeChanged(position, billFileList.size - position)

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

                    } else {
                        showMessage(deleteResponse.msg)
                    }

                }
            }

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

    private fun downloadAllFile() {
        apiService.downloadGroupAllBillFile(BillFileDownloadAllRequest(selectedGroupNameId)).enqueue(object : Callback<BillFileDownloadAllResponse> {
            override fun onResponse(
                call: Call<BillFileDownloadAllResponse>,
                response: Response<BillFileDownloadAllResponse>
            ) {
                val dataResponse = response.body()

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

                        val uri = Uri.parse(dataResponse.data.url)
                        startActivity(Intent(Intent.ACTION_VIEW, uri))

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

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

    private fun downloadThisModelFile() {

        val billFileDownloadThisModelRequest = BillFileDownloadThisModelRequest().apply {
            ctable = selectedPaymentPlateId
            diid = selectedGroupNameId
        }

        apiService.downloadGroupThisModelBillFile(billFileDownloadThisModelRequest).enqueue(object : Callback<BillFileDownloadThisModelResponse> {
            override fun onResponse(
                call: Call<BillFileDownloadThisModelResponse>,
                response: Response<BillFileDownloadThisModelResponse>
            ) {
                val dataResponse = response.body()

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

                        val uri = Uri.parse(dataResponse.data.url)
                        startActivity(Intent(Intent.ACTION_VIEW, uri))

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

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

    private fun hasPermission(): Boolean {
        return (OASystem.userInfo.userId == 21) or (OASystem.userInfo.userId == 22) or (OASystem.userInfo.userId == 187) or (OASystem.userInfo.userId == 258) or (OASystem.userInfo.userId == 233)
    }
}