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

import android.graphics.drawable.Drawable
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.widget.ImageView
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.gson.Gson
import es.verdnatura.R
import es.verdnatura.databinding.FragmentRouteBinding
import es.verdnatura.db.DeliveryDatabase
import es.verdnatura.domain.notNull
import es.verdnatura.domain.toDateString
import es.verdnatura.domain.toast
import es.verdnatura.presentation.base.BaseFragment
import es.verdnatura.presentation.base.database
import es.verdnatura.presentation.common.ItemDescorationCustomized
import es.verdnatura.presentation.common.OnItemImageRouteRowClickListener
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.RouteAdapter
import es.verdnatura.presentation.view.feature.delivery.model.ExpeditionInfoLoadUnload
import es.verdnatura.presentation.view.feature.delivery.model.ExpeditionSalix
import es.verdnatura.presentation.view.feature.delivery.model.RouteInfo
import es.verdnatura.presentation.view.feature.delivery.model.RouteLoaded
import es.verdnatura.presentation.view.feature.delivery.viewmodels.DeliveryViewModel
import es.verdnatura.presentation.view.feature.pasillero.model.PasillerosItemVO
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Date

class RoutesFragment(
    var title: String = ""
) : BaseFragment<FragmentRouteBinding, DeliveryViewModel>(
    DeliveryViewModel::class
) {

    private var adapter: RouteAdapter? = null
    private var pasillerosItemClickListener: OnPasillerosItemClickListener? = null
    private lateinit var myListRoute: MutableList<RouteInfo>
    private lateinit var db: DeliveryDatabase
    private lateinit var myListRouteLoaded: List<RouteLoaded>

    companion object {
        fun newInstance(title: String) = RoutesFragment(title)
    }

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

    override fun init() {
        super.init()
        setEvents()
        setToolBar()
        binding.scanInput.requestFocus()
        viewModel.getRoutes()

    }

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

    private fun pendingOperations() {

        db = database(requireContext().applicationContext)
        if (mobileApplication.hasNetwork) {
            lifecycleScope.launch {
                withContext(Dispatchers.IO) {
                    val pending = db.signedTicketDao().getAll()
                    for (p in pending) {
                        viewModel.saveSign(p.fileName, p.queryMapList)
                    }
                    val pendingExpedition = db.expedicionDao().getAllPendingExpeditions()

                    val pendingExpeditionSend = pendingExpedition.map { l ->
                        ExpeditionSalix(
                            expeditionFk = l.id, stateCode = l.code, l.isScanned
                        )
                    }

                    if (pendingExpeditionSend.any { it.stateCode == "DELIVERED" }) {
                        viewModel.expeditionStateAddSalix(
                            hashMapOf("expeditions" to pendingExpeditionSend.filter { it.stateCode == "DELIVERED" })
                        )
                    }
                    if (pendingExpeditionSend.any { it.stateCode == "ON DELIVERY" }) {
                        viewModel.expeditionStateAddSalix(
                            hashMapOf("expeditions" to pendingExpeditionSend.filter { it.stateCode == "ON DELIVERY" })
                        )
                    }
                    if (pendingExpeditionSend.any { it.stateCode == "LOST" }) {
                        viewModel.expeditionStateAddSalix(
                            hashMapOf("expeditions" to pendingExpeditionSend.filter { it.stateCode == "LOST" })
                        )
                    }
                    if (pendingExpeditionSend.any { it.stateCode == "FOUND" }) {
                        viewModel.expeditionStateAddSalix(
                            hashMapOf("expeditions" to pendingExpeditionSend.filter { it.stateCode == "FOUND" })
                        )
                    }

                }
                db.routesDao().deleteLoaded(toDateString(Date()))
                myListRouteLoaded = db.routesDao().getAllLoaded()

            }
        }

    }

    private fun deleteSignTickets(nameFileSigned: String) {
        lifecycleScope.launch {
            withContext(Dispatchers.IO) {
                db.signedTicketDao().deleteByNameFile(nameFileSigned)
            }

        }
    }

    private fun deleteExpeditionsPending(codeState: String) {
        lifecycleScope.launch {
            withContext(Dispatchers.IO) {
                db.expedicionDao().getDeleteByState(codeState)
            }

        }
    }

    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 iconInfo = ImageView(context)
        val iconRefresh = ImageView(context)
        val iconSearch = ImageView(context)

        iconInfo.setImageResource(R.drawable.ic_info_delivery)
        iconRefresh.setImageResource(R.drawable.ic_info_refresh)
        iconSearch.setImageResource(R.drawable.expedition_find)

        iconInfo.tooltipText = getTooltip(R.drawable.ic_info_delivery)
        iconRefresh.tooltipText = getTooltip(R.drawable.ic_info_refresh)
        iconSearch.tooltipText = getTooltip(R.drawable.expedition_find)
        listIcons.add(iconInfo)
        listIcons.add(iconRefresh)
        listIcons.add(iconSearch)

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

                override fun onOptionsItemSelected(item: Drawable) {

                    when (item) {
                        iconRefresh.drawable -> {
                            viewModel.getRoutes()
                        }

                        iconInfo.drawable -> {
                            ma.onPasillerosItemClickListener(
                                PasillerosItemVO(title = R.string.titleInfo),
                                getString(R.string.titleInfo)
                            )
                        }

                        iconSearch.drawable -> {
                            ma.onPasillerosItemClickListener(
                                PasillerosItemVO(title = R.string.titleLog),
                                getString(R.string.titleLog)
                            )
                        }
                    }
                }
            })

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

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

        }


        binding.scanInput.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                filteredList(s.toString().lowercase())
            }

            override fun afterTextChanged(s: Editable?) {

            }
        })

    }

    private fun filteredList(searchText: String) {
        if (::myListRoute.isInitialized) {
            val filteredList = myListRoute.filter { route ->
                route.toString().lowercase().contains(searchText)
            }.toMutableList()
            adapter!!.updateList(filteredList)
        }

    }

    override fun observeViewModel() {
        with(viewModel) {
            loadRouteList.observe(viewLifecycleOwner) { event ->
                event.getContentIfNotHandled().notNull {
                    createListRoutes(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
                }
            }


            responseSign.observe(viewLifecycleOwner) {

                if (it.isError) {
                    binding.mainToolbar.toolbarIcons.visibility = View.VISIBLE
                    it.message.toast(context)

                } else {
                    deleteSignTickets(it.fileToSign)
                }
            }

            responseLoadList.observe(viewLifecycleOwner) {

                ma.onApplicationEventAnimation(View.INVISIBLE)
                createListRoutes(mutableListOf(), getSaved = true)
            }

            responseStateAdd.observe(viewLifecycleOwner) {

                if (it) {
                    binding.mainToolbar.toolbarIcons.visibility = View.VISIBLE
                    deleteExpeditionsPending("")
                }
            }

        }

    }

    private fun createListRoutes(list: MutableList<RouteInfo>, getSaved: Boolean = false) {

        lifecycleScope.launch {
            withContext(Dispatchers.IO) {

                myListRoute = if (getSaved) {
                    db.routesDao().getAll() as MutableList<RouteInfo>
                } else {
                    db.routesDao().delete()
                    db.routesDao().insert(list)
                    list
                }

            }

            // myListRoute = list

            adapter = RouteAdapter(
                myListRoute, object : OnItemImageRouteRowClickListener {

                    override fun onItemImageRouteRowClickListener(item: RouteInfo, action: String) {
                        when (action) {
                            "loadVan" -> {
                                binding.scanInput.isEnabled = true
                                ma.onPasillerosItemClickListener(
                                    PasillerosItemVO(title = R.string.titleDeliverySummary),
                                    item.id.toString()
                                )
                            }

                            "showTickets" -> {
                                ma.onPasillerosItemClickListener(
                                    PasillerosItemVO(title = R.string.tickets),
                                    Gson().toJson(item)
                                )
                            }
                        }

                    }

                }, if (::myListRouteLoaded.isInitialized) {
                    myListRouteLoaded
                } else {
                    listOf()
                }
            )

            binding.routeRecyclerview.addItemDecoration(
                ItemDescorationCustomized(
                    resources.getDimensionPixelSize(
                        R.dimen.vertical_spacing
                    )
                )
            )
            binding.routeRecyclerview.adapter = adapter
            binding.routeRecyclerview.layoutManager =
                LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
            // adapter!!.notifyDataSetChanged()
            if (!binding.scanInput.text.isNullOrBlank()) {
                filteredList(binding.scanInput.text.toString())
            }

        }
    }

    private fun setListPosition(list: MutableList<ExpeditionInfoLoadUnload>) {
        for (i in list.indices) {
            binding.routeRecyclerview.scrollToPosition(i)
            break
        }
    }

}

