package com.pan_american.android.ui.group_invite_official.official_visits

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.CardAdapter
import com.pan_american.android.base.CustomAlertDialog
import com.pan_american.android.base.ListAdapter
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.SimpleGroupInfoRequest
import com.pan_american.android.data.model.common.network.SimpleGroupInfoResponse
import com.pan_american.android.data.model.group_invite_official.official_visits.entity.OfficialVisitListItem
import com.pan_american.android.data.model.group_invite_official.official_visits.network.OfficialVisitListRequest
import com.pan_american.android.data.model.group_invite_official.official_visits.network.OfficialVisitListResponse
import com.pan_american.android.data.model.group_invite_official.official_visits.network.ProvinceAndCityDownloadFileRequest
import com.pan_american.android.data.model.group_invite_official.official_visits.network.ProvinceAndCityDownloadFileResponse
import com.pan_american.android.data.network.APIService
import com.pan_american.android.data.network.ServiceCreator
import com.pan_american.android.databinding.ActivityInviteVisitsBinding
import com.pan_american.android.databinding.LayoutTitleBinding
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 InviteVisitsActivity : BaseActivity<ActivityInviteVisitsBinding>() {

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

    private val simpleGroupInfoRequest = SimpleGroupInfoRequest()

    private val officialVisitListRequest = OfficialVisitListRequest()

    private val simpleGroupInfoList = ArrayList<SimpleGroupInfo>()

    private val officialVisitList = ArrayList<OfficialVisitListItem>()

    private var groupId = 0

    private lateinit var titleBinding: LayoutTitleBinding

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

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

        initTitle()
        initViews()
    }

    override fun initTitle() {
        titleBinding = LayoutTitleBinding.bind(binding.root).apply {
            titleText.text = resources.getString(R.string.official_visits)

            if (OASystem.authorization(OASystem.OFFICIAL_VISITS, OASystem.ADD)) {
                addButton.visibility = View.VISIBLE
            }

            addButton.setOnClickListener {
                val intent = Intent(OASystem.context, AddOfficialVisitsActivity::class.java).apply {
                    putExtra("fromList", false)
                    run {
                        for (item in simpleGroupInfoList) {
                            if (groupId == item.id) {
                                putExtra("groupName", item.name)
                                putExtra("visitCountry", item.visitCountry)
                                putExtra("clientName", item.clientName)
                                putExtra("groupCode", item.tourCode)
                                putExtra("groupId", groupId)
                                return@run
                            }
                        }
                    }
                }
                startActivity(intent)
            }

            backButton.setOnClickListener {
                back()
            }
        }
    }

    override fun initViews() {

        binding.officialVisitsContainer.setRefreshHeader(ClassicsHeader(OASystem.context))
        binding.officialVisitsContainer.setRefreshFooter(ClassicsFooter(OASystem.context))

        simpleGroupInfoRequest.apply {
            pageIndex = 1
            pageSize = 3
        }

        officialVisitListRequest.apply {
            pageIndex = 1
            pageSize = 10
        }

        getSimpleGroupInfoResource(0)
    }

    override fun initEvents() {

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

            simpleGroupInfoList.clear()

            getSimpleGroupInfoResource(1)
        }

        binding.baseInfoSwitch.setOnClickListener {

            if (binding.groupBaseInfo.visibility == View.GONE) {
                binding.groupBaseInfo.visibility = View.VISIBLE
                binding.baseInfoSwitch.text = resources.getString(R.string.hide)
            } else {
                binding.groupBaseInfo.visibility = View.GONE
                binding.baseInfoSwitch.text = resources.getString(R.string.show)
            }
        }

        binding.provinceRequestData.setOnClickListener {
            downloadRequestData(1)
        }

        binding.cityRequestData.setOnClickListener {
            downloadRequestData(2)
        }
    }

    override fun onStart() {
        super.onStart()

        if (OASystem.needRefresh) {
            binding.officialVisitsList.adapter!!.notifyItemRangeRemoved(0, officialVisitList.size)
            officialVisitListRequest.pageIndex = 1
            officialVisitList.clear()
            OASystem.needRefresh = false
            getGroupOfficialVisitsList(2)
        }
    }

    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 -> {

                                simpleGroupInfoList[0].apply {
                                    binding.groupNameSelector.text = name
                                    binding.groupCustomer.text = clientName
                                    binding.visitCountry.text = visitCountry
                                    binding.visitDays.text = visitDays.toString()
                                    binding.visitMembers.text = visitPNumber.toString()
                                    binding.duringTime.text = String.format(resources.getString(R.string.during_format), this.visitStartDate.substring(0, 10), this.visitEndDate.substring(0, 10))

                                    groupId = id
                                }

                                initEvents()

                                getGroupOfficialVisitsList(1)
                            }

                            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.groupNameSelector.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.groupNameSelector.text = name
                                                    binding.groupCustomer.text = clientName
                                                    binding.visitCountry.text = visitCountry
                                                    binding.visitDays.text = visitDays.toString()
                                                    binding.visitMembers.text = visitPNumber.toString()
                                                    binding.duringTime.text = String.format(resources.getString(R.string.during_format), this.visitStartDate.substring(0, 10), this.visitEndDate.substring(0, 10))

                                                    groupId = id

                                                    getGroupOfficialVisitsList(1)

                                                    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 getGroupOfficialVisitsList(type: Int) {

        officialVisitListRequest.diid = groupId

        apiService.getGroupOfficialVisitList(officialVisitListRequest).enqueue(object : Callback<OfficialVisitListResponse> {
            override fun onResponse(
                p0: Call<OfficialVisitListResponse>,
                response: Response<OfficialVisitListResponse>
            ) {
                val listResponse = response.body()

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

                        for (item in listResponse.data.dataList) {
                            officialVisitList.add(item)
                        }

                        when(type) {
                            1 -> {
                                binding.officialVisitsContainer.setEnableLoadMore(officialVisitListRequest.pageIndex < getTotalPage(listResponse.data.dataCount))
                                initList()
                            }

                            2 -> {
                                binding.officialVisitsContainer.finishRefresh()
                                binding.officialVisitsContainer.setEnableLoadMore(officialVisitListRequest.pageIndex < getTotalPage(listResponse.data.dataCount))
                                initList()
                            }

                            3 -> {
                                binding.officialVisitsContainer.finishLoadMore()
                                binding.officialVisitsContainer.setEnableLoadMore(officialVisitListRequest.pageIndex < getTotalPage(listResponse.data.dataCount))
                                binding.officialVisitsList.adapter!!.notifyItemInserted(officialVisitList.size)
                            }
                        }

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

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

    private fun initList() {
        if (officialVisitList.size == 0) {
            showMessage(resources.getString(R.string.no_data))
            return
        }

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

        val adapter = CardAdapter.Builder<OfficialVisitListItem>().apply {
            setData(officialVisitList)
            setLayoutId(R.layout.item_official_visits_list)
            setCanDelete(OASystem.authorization(OASystem.OFFICIAL_VISITS, OASystem.DELETE))
            addBindView { itemView, data ->
                itemView.findViewById<TextView>(R.id.official_department).text = data.client
                itemView.findViewById<TextView>(R.id.official_time).text = String.format(resources.getString(R.string.with_space_format), data.date.substring(0, 10), data.time)
                itemView.findViewById<TextView>(R.id.official_attribute).text = data.nature.ifBlank {
                        resources.getString(R.string.no_info)
                    }
                itemView.findViewById<TextView>(R.id.contacts_name).text = data.contact
                itemView.findViewById<TextView>(R.id.creator).text = data.createUserName
                itemView.findViewById<TextView>(R.id.create_time).text = data.createTime
            }
        }.create()

        binding.officialVisitsList.adapter = adapter

        adapter.onRecyclerViewItemClick = object : CardAdapter.OnRecyclerViewItemClick<OfficialVisitListItem> {
            override fun onItemClick(position: Int) {
                val intent = Intent(OASystem.context, AddOfficialVisitsActivity::class.java).apply {
                    run {
                        for (item in simpleGroupInfoList) {
                            if (groupId == item.id) {
                                putExtra("groupName", item.name)
                                putExtra("visitCountry", item.visitCountry)
                                putExtra("clientName", item.clientName)
                                putExtra("groupCode", item.tourCode)
                                putExtra("id", officialVisitList[position].id)
                                putExtra("groupId", groupId)
                                putExtra("fromList", true)
                                return@run
                            }
                        }
                    }
                }

                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), officialVisitList[position].client))
                    setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
                        dialog.dismiss()
                    }
                    setPositiveButtonAndListener(resources.getString(R.string.confirm)) { dialog, _ ->
                        dialog.dismiss()
                        deleteOfficialItem(position)
                    }
                }.show()
            }
        }

        binding.officialVisitsContainer.setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
            override fun onRefresh(p0: RefreshLayout) {
                binding.officialVisitsList.adapter!!.notifyItemRangeRemoved(0, officialVisitList.size)
                officialVisitListRequest.pageIndex = 1
                officialVisitList.clear()
                getGroupOfficialVisitsList(2)
            }

            override fun onLoadMore(p0: RefreshLayout) {
                officialVisitListRequest.pageIndex += 1
                getGroupOfficialVisitsList(3)
            }
        })
    }

    private fun deleteOfficialItem(position: Int) {
        apiService.deleteGroupOfficialVisit(DeleteRequest(officialVisitList[position].id)).enqueue(object : Callback<BaseResponse> {
            override fun onResponse(p0: Call<BaseResponse>, response: Response<BaseResponse>) {

                val deleteResponse = response.body()

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

                        officialVisitList.removeAt(position)
                        binding.officialVisitsList.adapter!!.notifyItemRemoved(position)
                        binding.officialVisitsList.adapter!!.notifyItemRangeChanged(position, officialVisitList.size - position)

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

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

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

    private fun downloadRequestData(type: Int) {
        apiService.downloadProvinceAndCityRequestFile(ProvinceAndCityDownloadFileRequest(type, groupId)).enqueue(object : Callback<ProvinceAndCityDownloadFileResponse> {
            override fun onResponse(call: Call<ProvinceAndCityDownloadFileResponse>, response: Response<ProvinceAndCityDownloadFileResponse>) {

                val urlResponse = response.body()

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

                        CustomAlertDialog.Builder().apply {
                            setTitle(resources.getString(R.string.confirm))

                            when(type) {
                                1 -> {
                                    setMessage(String.format(resources.getString(R.string.request_data_download_hint), binding.groupNameSelector.text, resources.getString(R.string.province_request_data)))
                                }

                                2 -> {
                                    setMessage(String.format(resources.getString(R.string.request_data_download_hint), binding.groupNameSelector.text, resources.getString(R.string.city_request_data)))
                                }
                            }

                            setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
                                dialog.dismiss()
                            }

                            setPositiveButtonAndListener(resources.getString(R.string.confirm)) { _, _ ->
                                val uri = Uri.parse(urlResponse.data)
                                startActivity(Intent(Intent.ACTION_VIEW, uri))
                            }
                        }.show()

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

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