package es.verdnatura.presentation.view.feature.delivery.fragments

import android.graphics.drawable.Drawable
import android.view.KeyEvent
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.ImageView
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.gson.Gson
import es.verdnatura.R
import es.verdnatura.databinding.FragmentExpeditionSummaryBinding
import es.verdnatura.domain.toast
import es.verdnatura.presentation.base.BaseFragment
import es.verdnatura.presentation.common.AdapterCallback
import es.verdnatura.presentation.common.OnAddressRowClickListener
import es.verdnatura.presentation.common.OnItemImageLoadRowClickListener
import es.verdnatura.presentation.common.OnOptionsSelectedListener
import es.verdnatura.presentation.common.OnPasillerosItemClickListener
import es.verdnatura.presentation.common.ToolBarAdapterTooltip
import es.verdnatura.presentation.view.feature.delivery.adapters.ExpeditionSummaryAdapter
import es.verdnatura.presentation.view.feature.delivery.model.ExpeditionInfoLoadUnload
import es.verdnatura.presentation.view.feature.delivery.model.ExpeditionInfoSummary
import es.verdnatura.presentation.view.feature.delivery.model.ExpeditionSalix
import es.verdnatura.presentation.view.feature.delivery.viewmodels.DeliveryViewModel
import es.verdnatura.presentation.view.feature.pasillero.model.PasillerosItemVO

class SummaryFragment(
    var title: String = "",
    var state: String = "",
    var route: Int = 0,
) : BaseFragment<FragmentExpeditionSummaryBinding, DeliveryViewModel>(
    DeliveryViewModel::class
), AdapterCallback {

    private var adapter: ExpeditionSummaryAdapter? = null
    private var pasillerosItemClickListener: OnPasillerosItemClickListener? = null
    private var originalItem: Int = 0
    private lateinit var myList: MutableList<ExpeditionInfoLoadUnload>
    private lateinit var myListSummary: List<ExpeditionInfoSummary>
    private var counterCalls = 0
    private var counterResponse = 0
    private var positionOnScreen = 0
    private var addressFkSelected = 0
    private var routeSelected = 0
    private var isScanning = false
    private var positionSelected = -1

    override fun getPosition(): Int {
        return positionSelected
    }

    companion object {
        fun newInstance(title: String, state: String, route: Int) =
            SummaryFragment(title, state, route)
    }

    override fun getLayoutId(): Int = R.layout.fragment_expedition_summary

    override fun init() {
        super.init()
        setEvents()
        setToolBar()
        binding.scanInput.requestFocus()
        viewModel.routeGetExpeditionSummary(route)
        routeSelected = route
        setViews()

    }

    override fun onResume() {
        if (binding.mainToolbar.toolbarTitle.text != getString(R.string.titleDeliverySummary)) {
            binding.scanInput.isEnabled = true
            binding.scanInput.requestFocus()
        }

        super.onResume()

    }

    private fun setViews() {
        binding.expeditionSummaryRecyclerview.addOnScrollListener(object :
            RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                positionOnScreen =
                    (recyclerView.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
                super.onScrolled(recyclerView, dx, dy)
            }
        })
    }

    private fun setToolBar() {
        ma.hideBottomNavigation(View.GONE)
        binding.mainToolbar.toolbarSubtitle.setTextColor(requireContext().getColor((R.color.verdnatura_pumpkin_orange)))
        binding.mainToolbar.toolbarTitle.visibility = View.VISIBLE
        binding.mainToolbar.toolbarSubtitle.visibility = View.VISIBLE
        binding.mainToolbar.toolbarIcons.visibility = View.VISIBLE
        binding.mainToolbar.toolbarTitle.text = title

        val listIcons: ArrayList<ImageView> = ArrayList()
        val iconLoad = ImageView(context)
        val iconExit = ImageView(context)

        iconLoad.setImageResource(R.drawable.camion)
        iconExit.setImageResource(R.drawable.exit)

        iconLoad.tooltipText = getTooltip(R.drawable.camion)
        iconExit.tooltipText = getTooltip(R.drawable.exit)

        listIcons.add(iconLoad)
        listIcons.add(iconExit)

        binding.mainToolbar.toolbarIcons.adapter =
            ToolBarAdapterTooltip(listIcons, object : OnOptionsSelectedListener {

                override fun onOptionsItemSelected(item: Drawable) {

                    when (item) {
                        iconLoad.drawable -> {
                            openLoadUnLoad(0)
                        }

                        iconExit.drawable -> {
                            requireActivity().finish()

                        }
                    }
                }
            })

        binding.mainToolbar.toolbarIcons.layoutManager =
            LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
        binding.mainToolbar.toolbarIcons.visibility = View.VISIBLE
    }

    private fun openLoadUnLoad(adress: Int) {

        val entryPoint = Gson().toJson(
            mutableMapOf(
                "route" to routeSelected, "address" to adress
            )
        )

        ma.onPasillerosItemClickListener(
            PasillerosItemVO(title = R.string.titleLoadTruck), entryPoint
        )
    }

    private fun setExpeditionsState(
        list: MutableList<ExpeditionInfoLoadUnload>, state: String, address: Int
    ) {
        val listExpedition = list.filter { it.addressFk == address }.map { l ->
            ExpeditionSalix(
                expeditionFk = l.id, stateCode = if (l.code == state) {
                    state
                } else {
                    "FOUND"
                },
                isScanned = l.isScanned
            )
        }

        if (list.filter { it.addressFk == address }
                .filter { it.code == state }.size == list.filter { it.addressFk == address }.size) {
            counterCalls = 1
            viewModel.expeditionStateAddSalix(
                hashMapOf("expeditions" to listExpedition.filter { it.stateCode == state })
            )

            isScanning = false
        } else {

            val alertDialog = android.app.AlertDialog.Builder(requireContext()).create()
            alertDialog.setTitle(getString(R.string.info))
            alertDialog.setMessage(getString(R.string.expeditionTotal))
            alertDialog.setButton(
                android.app.AlertDialog.BUTTON_POSITIVE, getString(R.string.save)
            ) { _, _ ->

                counterCalls = 1
                viewModel.expeditionStateAddSalix(hashMapOf("expeditions" to listExpedition.filter { it.stateCode == state }))

            }
            alertDialog.setButton(
                android.app.AlertDialog.BUTTON_NEUTRAL, getString(R.string.find)
            ) { _, _ ->
                //createList(list.sortedByDescending { it.code })
            }
            alertDialog.show()
        }

    }

    private fun setEvents() {
        binding.mainToolbar.backButton.setOnClickListener {
            ma.onMyBackPressed()

        }

        binding.scanInput.setOnEditorActionListener { _, actionId, event ->
            if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || actionId == 0) {
                if (!binding.scanInput.text.isNullOrEmpty()) {
                    isScanning = true
                    val isScanned =
                        event != null && event.action == KeyEvent.ACTION_DOWN && event.keyCode == KeyEvent.KEYCODE_ENTER
                    try {
                        markExpedition(
                            binding.scanInput.text.toString().toInt(),
                            state,
                            if (isScanned) 1 else 0
                        )

                    } catch (ex: Exception) {
                        getString(R.string.errorExpedition).toast(context, Toast.LENGTH_SHORT)
                    }
                    binding.scanInput.setText("")
                }

                return@setOnEditorActionListener true
            }
            false
        }

    }

    private fun markExpedition(expedNumber: Int, state: String, isScanned: Int) {
        var found = false
        if (myList.filter { it.addressFk == addressFkSelected }.filter { it.id == expedNumber }
                .any { it.code == state }) {
            ma.messageWithSound(getString(R.string.expeditionMarked), null, true)
        } else {
            for (exped in myList.filter { it.addressFk == addressFkSelected }) {
                if (exped.id == expedNumber) {
                    found = true
                    exped.code = state
                    exped.isScanned = isScanned
                    break
                }
            }
            if (found) {
                ma.messageWithSound(
                    message = "",
                    isError = false,
                    isPlayed = true,
                    isToasted = false
                )
            } else {
                ma.messageWithSound(message = "", isError = true, isPlayed = true, isToasted = null)
            }
        }

        if (found) {
            updateCount(myList, state)
        }

    }

    override fun observeViewModel() {
        with(viewModel) {

            expeditionInfoLoadUnloadList.observe(viewLifecycleOwner) {
                createList(it.list as MutableList<ExpeditionInfoLoadUnload>)
            }

            expeditionInfoSummary.observe(viewLifecycleOwner) {
                createListSummary(it.list)
            }

            routeInfoList.observe(viewLifecycleOwner) {
                if (it.list.isNotEmpty()) {
                    binding.mainToolbar.toolbarIcons.visibility = View.VISIBLE
                    binding.mainToolbar.switchButton.visibility = View.VISIBLE
                } else {
                    binding.scanInput.setText("")
                    binding.mainToolbar.toolbarIcons.visibility = View.GONE
                    binding.mainToolbar.switchButton.visibility = View.GONE
                }
            }
            responseStateAdd.observe(viewLifecycleOwner) {
                if (it) {
                    counterResponse += 1
                    if (counterResponse == counterCalls) {
                        viewModel.routeGetExpeditionSummary(routeSelected)
                        counterResponse = 0
                        counterCalls = 0
                        checkNextAddress()
                    }
                }

            }

        }
    }

    private fun checkNextAddress() {

        if (myListSummary.size > positionSelected + 1) {

            val startIndex = positionSelected

            for ((indice, elemento) in myListSummary.withIndex()) {
                if (indice >= startIndex) {

                    if (myList.filter { it.addressFk == elemento.addressFk }
                            .filter { it.code == state }.size != myList.filter { it.addressFk == elemento.addressFk }.size) {
                        addressFkSelected = myListSummary[indice].addressFk
                        positionSelected = indice
                        break

                    }
                }
            }

        } else {
            addressFkSelected = myListSummary[positionSelected].addressFk

        }




        setTitleSummary()
    }

    private fun createListSummary(list: List<ExpeditionInfoSummary>) {

        myListSummary = list
        adapter = ExpeditionSummaryAdapter(list, object : OnAddressRowClickListener {
            override fun onAddressRowClickListener(item: ExpeditionInfoSummary) {

                positionSelected = myListSummary.indexOf(item)
                binding.scanInput.isEnabled = true
                binding.scanInput.requestFocus()

                if (addressFkSelected != item.addressFk && !isScanning) {

                    viewModel.getExpeditionFromRoute(routeSelected)

                }
                if (addressFkSelected != item.addressFk && isScanning) {
                    setExpeditionsState(myList, state, addressFkSelected)

                }
                addressFkSelected = item.addressFk
                isScanning = false
                viewModel.getExpeditionFromRoute(routeSelected)
                adapter!!.notifyDataSetChanged()
            }

        }, object : OnItemImageLoadRowClickListener {
            override fun onItemImageLoadRowClickListener(item: ExpeditionInfoSummary) {
                openLoadUnLoad(item.addressFk)
            }
        }, adapterCallBack = this@SummaryFragment)

        binding.expeditionSummaryRecyclerview.adapter = adapter
        binding.expeditionSummaryRecyclerview.layoutManager =
            LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
        adapter!!.notifyDataSetChanged()
    }

    private fun createList(list: MutableList<ExpeditionInfoLoadUnload>) {

        myList = list
        setTitleSummary()

    }

    private fun setListPosition(list: MutableList<ExpeditionInfoLoadUnload>) {
        for (i in list.indices) {
            if (list[i].code != state) {
                binding.expeditionSummaryRecyclerview.scrollToPosition(i)
                break
            }
        }
    }

    private fun updateCount(list: MutableList<ExpeditionInfoLoadUnload>, state: String) {
        val countMarked =
            list.filter { it.addressFk == addressFkSelected }.filter { it.code == state }.size

        setTitleSummary()

        if (countMarked == list.filter { it.addressFk == addressFkSelected }.size) {
            setExpeditionsState(list, state, addressFkSelected)
        }

    }

    private fun setTitleSummary() {

        if (::myList.isInitialized) {
            val countMarked =
                myList.filter { it.addressFk == addressFkSelected }.filter { it.code == state }.size
            binding.mainToolbar.toolbarTitle.text =
                getString(R.string.routeTxtDouble, routeSelected, addressFkSelected)
            binding.mainToolbar.toolbarSubtitle.text = getString(
                R.string.subTitleRouteDouble,
                countMarked,
                myList.filter { it.addressFk == addressFkSelected }.size
            )
        }
    }

}