package com.pan_american.android.ui.group_invite_official.invite_data

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import com.pan_american.android.OASystem
import com.pan_american.android.R
import com.pan_american.android.base.BaseFragment
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.data.model.common.network.DeleteRequest
import com.pan_american.android.data.model.group_invite_official.invite_data.entity.InviteDataListItem
import com.pan_american.android.data.model.group_invite_official.invite_data.network.InviteDataListRequest
import com.pan_american.android.data.model.group_invite_official.invite_data.network.InviteDataListResponse
import com.pan_american.android.data.network.APIService
import com.pan_american.android.data.network.ServiceCreator
import com.pan_american.android.databinding.FragmentInviteDataListBinding
import com.scwang.smart.refresh.footer.ClassicsFooter
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 InviteDataListFragment : BaseFragment<FragmentInviteDataListBinding>() {

    private var inviteDataListRequest = InviteDataListRequest()

    private var pageIndex = 1

    private var totalPage = 0

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

    private val inviteDataList = ArrayList<InviteDataListItem>()

    override fun getViewBinding(
        inflater: LayoutInflater,
        container: ViewGroup?,
        bundle: Bundle?
    ) = FragmentInviteDataListBinding.inflate(layoutInflater, container, false)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        requireArguments().apply {
            inviteDataListRequest.country = getString("country", "")
            inviteDataListRequest.unitName = getString("unitName", "")
            inviteDataListRequest.contact = getString("contact", "")
            inviteDataListRequest.delegation = getString("delegation", "")
            inviteDataListRequest.field = getString("field", "")
            inviteDataListRequest.createUserId = getInt("createUserId", 0)
            inviteDataListRequest.startCreateTime = getString("startCreateTime", "")
            inviteDataListRequest.endCreateTime = getString("endCreateTime", "")
        }

        inviteDataListRequest.pageIndex = pageIndex
        inviteDataListRequest.pageSize = 10

        initViews()
    }

    override fun initViews() {
        binding.inviteDataContainer.setRefreshHeader(ClassicsHeader(OASystem.context))
        binding.inviteDataContainer.setRefreshFooter(ClassicsFooter(OASystem.context))

        initInviteDataList(1)
    }

    override fun onStart() {
        super.onStart()

        if (OASystem.needRefresh) {
            pageIndex = 1
            inviteDataListRequest.pageIndex = pageIndex
            inviteDataList.clear()
            OASystem.needRefresh = false
            initInviteDataList(2)
        }
    }

    private fun initInviteDataList(type: Int) {

        //避免Fragment not attached to a context.
        if (!isAdded) {
            return
        }

        apiService.getInviteDataList(inviteDataListRequest).enqueue(object :
            Callback<InviteDataListResponse> {
            override fun onResponse(
                call: Call<InviteDataListResponse>,
                response: Response<InviteDataListResponse>
            ) {
                val listResponse = response.body()

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

                        if (listResponse.data.size == 0) {
                            showMessage(resources.getString(R.string.no_data))
                        }

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

                        when (type) {
                            1 -> {
                                totalPage = getTotalPage(listResponse.count)
                                binding.inviteDataContainer.setEnableLoadMore(pageIndex < totalPage)
                                initList()
                            }

                            2 -> {
                                binding.inviteDataContainer.finishRefresh()
                                totalPage = getTotalPage(listResponse.count)
                                binding.inviteDataContainer.setEnableLoadMore(pageIndex < totalPage)
                                initList()
                            }

                            3 -> {
                                binding.inviteDataContainer.finishLoadMore()
                                binding.inviteDataContainer.setEnableLoadMore(pageIndex < totalPage)
                                binding.inviteDataList.adapter!!.notifyItemInserted(inviteDataList.size)
                            }
                        }

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

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

    private fun getTotalPage(dataCount: Int): Int {
        var totalPage = dataCount / 10
        if (dataCount % 10 != 0) {
            totalPage++
        }

        return totalPage
    }

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

        val adapter = CardAdapter.Builder<InviteDataListItem>().apply {
            setData(inviteDataList)
            setLayoutId(R.layout.item_invite_data)
            setCanDelete(OASystem.authorization(OASystem.INVITE_DATA, OASystem.DELETE))
            addBindView { itemView, data ->
                itemView.findViewById<TextView>(R.id.unit_name).text = data.unitName
                itemView.findViewById<TextView>(R.id.country).text = data.country.ifBlank {
                    resources.getString(R.string.no_info)
                }
                itemView.findViewById<TextView>(R.id.city).text = data.city.ifBlank {
                    resources.getString(R.string.no_info)
                }
                itemView.findViewById<TextView>(R.id.industry).text = data.field.ifBlank {
                    resources.getString(R.string.no_info)
                }
                itemView.findViewById<TextView>(R.id.contacts_name).text = data.contact.ifBlank {
                    resources.getString(R.string.no_info)
                }
                itemView.findViewById<TextView>(R.id.job).text = data.job.ifBlank {
                    resources.getString(R.string.no_info)
                }
                itemView.findViewById<TextView>(R.id.phone).text = data.tel.ifBlank {
                    resources.getString(R.string.no_info)
                }
                itemView.findViewById<TextView>(R.id.creator).text = data.createUserName
                itemView.findViewById<TextView>(R.id.create_time).text = data.createTime
            }
        }.create()

        binding.inviteDataList.adapter = adapter

        adapter.onRecyclerViewItemClick = object : CardAdapter.OnRecyclerViewItemClick<InviteDataListItem> {
            override fun onItemClick(position: Int) {
                val intent = Intent(OASystem.context, AddInviteDataActivity::class.java).apply {
                    putExtra("data_id", inviteDataList[position].id)
                    putExtra("from_list", true)
                }

                startActivity(intent)
            }

            override fun onItemDelete(position: Int) {
                CustomAlertDialog.Builder().apply {
                    setTitle(resources.getString(R.string.alert))
                    setMessage(
                        String.format(
                            resources.getString(R.string.delete_alert_text),
                            inviteDataList[position].unitName
                        )
                    )
                    setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
                        dialog.dismiss()
                    }
                    setPositiveButtonAndListener(resources.getString(R.string.confirm)) { _, _ ->
                        deleteInviteData(position)
                    }
                }.show()
            }
        }

        binding.inviteDataContainer.setOnRefreshLoadMoreListener(object :
            OnRefreshLoadMoreListener {
            override fun onRefresh(refreshLayout: RefreshLayout) {
                pageIndex = 1
                inviteDataListRequest.pageIndex = pageIndex
                binding.inviteDataList.adapter!!.notifyItemRangeRemoved(0, inviteDataList.size)
                inviteDataList.clear()
                initInviteDataList(2)
            }

            override fun onLoadMore(refreshLayout: RefreshLayout) {
                if (pageIndex < totalPage) {
                    pageIndex += 1
                    inviteDataListRequest.pageIndex = pageIndex
                    initInviteDataList(3)
                }
            }
        })
    }

    private fun deleteInviteData(position: Int) {
        apiService.deleteInviteData(DeleteRequest(inviteDataList[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) {
                        showMessage(resources.getString(R.string.delete_success))

                        inviteDataList.removeAt(position)

                        binding.inviteDataList.adapter!!.notifyItemRemoved(position)

                        binding.inviteDataList.adapter!!.notifyItemRangeChanged(position, inviteDataList.size - position)

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

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