package com.pan_american.android.ui.group_management.group_info

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
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.CustomAlertDialog
import com.pan_american.android.data.model.common.adapter.GroupInfoSimpleAdapter
import com.pan_american.android.data.model.common.network.DeleteRequest
import com.pan_american.android.data.model.group_management.group_info.entity.GroupInfoSimple
import com.pan_american.android.data.model.group_management.group_info.network.GroupInfoListRequest
import com.pan_american.android.data.model.group_management.group_info.network.GroupInfoListResponse
import com.pan_american.android.data.model.group_management.group_info.network.GroupStatusChangeRequest
import com.pan_american.android.data.model.group_management.group_info.network.GroupStatusChangeResponse
import com.pan_american.android.data.network.APIService
import com.pan_american.android.data.network.ServiceCreator
import com.pan_american.android.databinding.FragmentGroupInfoListBinding
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 GroupInfoListFragment : BaseFragment<FragmentGroupInfoListBinding>() {

    val apiService = ServiceCreator.create<APIService>()

    private var groupInfoList = ArrayList<GroupInfoSimple>()

    private var listInit = false

    private var groupInfoListRequest = GroupInfoListRequest()

    private var pageIndex = 1

    private var totalPage = 0

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

    override fun onStart() {
        super.onStart()

        requireArguments().apply {
            groupInfoListRequest.apply {
                teamDid = getInt("group_type")
                isSure = getInt("group_status")
                teamName = getString("group_name", "")
                clientName = getString("client_name", "")
                clientUnit = getString("customer_department", "")
                visitDataTime = getString("visit_date", "")
            }
        }

        groupInfoListRequest.pageIndex = pageIndex
        groupInfoListRequest.pageSize = 10

        initViews()
    }

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

        initGroupInfoList(1)
    }

    private fun initGroupInfoList(type: Int) {

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

        if (!listInit) {

            apiService.getGroupInfoList(groupInfoListRequest)
                .enqueue(object : Callback<GroupInfoListResponse> {

                    override fun onResponse(
                        call: Call<GroupInfoListResponse>, response: Response<GroupInfoListResponse>
                    ) {
                        val groupInfoListResponse = response.body()

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

                                for (item in groupInfoListResponse.data.data) {
                                    groupInfoList.add(item)
                                }

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

                                when (type) {
                                    1 -> {
                                        totalPage = getTotalPage(groupInfoListResponse.count)
                                        binding.groupInfoContainer.setEnableLoadMore(pageIndex < totalPage)
                                        initList()
                                        listInit = true
                                    }

                                    2 -> {
                                        binding.groupInfoContainer.finishRefresh()
                                        totalPage = getTotalPage(groupInfoListResponse.count)
                                        binding.groupInfoContainer.setEnableLoadMore(pageIndex < totalPage)
                                        initList()
                                        listInit = true
                                    }

                                    3 -> {
                                        binding.groupInfoContainer.finishLoadMore()
                                        binding.groupInfoContainer.setEnableLoadMore(pageIndex < totalPage)
                                        binding.groupInfoList.adapter!!.notifyItemInserted(
                                            groupInfoList.size
                                        )
                                        listInit = true
                                    }
                                }

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

                    override fun onFailure(call: Call<GroupInfoListResponse>, t: Throwable) {
                        showMessage(resources.getString(R.string.network_error))
                    }
                })
        } else {
            if (OASystem.needRefresh) {
                pageIndex = 1
                groupInfoListRequest.pageIndex = pageIndex
                groupInfoList.clear()
                listInit = false
                initGroupInfoList(2)
            }
        }
    }

    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.groupInfoList.layoutManager = layoutManager

        val adapter = GroupInfoSimpleAdapter(groupInfoList)

        binding.groupInfoList.adapter = adapter

        adapter.onRecyclerViewItemClick =
            object : GroupInfoSimpleAdapter.OnRecyclerViewItemClick<GroupInfoSimple> {
                override fun onItemClick(position: Int) {
                    val intent = Intent(OASystem.context, AddGroupInfoActivity::class.java).apply {
                        putExtra("id", groupInfoList[position].id)
                        putExtra("fromList", true)
                    }

                    startActivity(intent)
                }

                override fun onItemDelete(position: Int) {
                    CustomAlertDialog.Builder(OASystem.context).apply {
                        setTitle(
                            String.format(
                                resources.getString(R.string.delete_alert_text),
                                groupInfoList[position].teamName
                            )
                        )
                        setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
                            dialog.dismiss()
                        }
                        setPositiveButtonAndListener(resources.getString(R.string.confirm)) { _, _ ->
                            deleteGroup(position)
                        }
                        setCancelable(false)
                    }.show()
                }

                override fun changeGroupStatus(position: Int) {
                    if (groupInfoList[position].isSure == 0) {

                        CustomAlertDialog.Builder(OASystem.context).apply {
                            setTitle(resources.getString(R.string.alert))
                            setMessage(
                                String.format(
                                    resources.getString(R.string.group_status_change_title),
                                    groupInfoList[position].teamName
                                )
                            )
                            setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
                                dialog.dismiss()
                            }
                            setPositiveButtonAndListener(resources.getString(R.string.confirm)) { _, _ ->
                                if (OASystem.authorization(
                                        OASystem.GROUP_INFORMATION, OASystem.PROCESS
                                    )
                                ) {
                                    groupStatusChange(position)
                                } else {
                                    showMessage(resources.getString(R.string.permission_denied))
                                }
                            }
                            setCancelable(false)
                        }.show()
                    }
                }
            }

        binding.groupInfoContainer.setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
            override fun onRefresh(refreshLayout: RefreshLayout) {
                pageIndex = 1
                groupInfoListRequest.pageIndex = pageIndex
                groupInfoList.clear()
                listInit = false
                initGroupInfoList(2)
            }

            override fun onLoadMore(refreshLayout: RefreshLayout) {
                if (pageIndex < totalPage) {
                    pageIndex += 1
                    groupInfoListRequest.pageIndex = pageIndex
                    listInit = false
                    initGroupInfoList(3)
                }
            }
        })
    }

    private fun deleteGroup(position: Int) {
        apiService.deleteGroup(DeleteRequest(groupInfoList[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) {

                            groupInfoList.removeAt(position)

                            binding.groupInfoList.adapter!!.notifyItemRemoved(position)
                            binding.groupInfoList.adapter!!.notifyItemRangeChanged(
                                position, groupInfoList.size
                            )

                            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 groupStatusChange(position: Int) {
        apiService.groupStatusChange(GroupStatusChangeRequest(groupInfoList[position].id))
            .enqueue(object : Callback<GroupStatusChangeResponse> {
                override fun onResponse(
                    call: Call<GroupStatusChangeResponse>,
                    response: Response<GroupStatusChangeResponse>
                ) {

                    val statusChangeResponse = response.body()

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

                            groupInfoList[position].tourCode = statusChangeResponse.data
                            binding.groupInfoList.adapter!!.notifyItemChanged(position)

                        }

                        showMessage(statusChangeResponse.msg)

                    }
                }

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