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

import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.os.Build
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.widget.ImageView
import androidx.annotation.RequiresApi
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.*
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.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

    @RequiresApi(Build.VERSION_CODES.O)
    override fun init() {
        super.init()
        setEvents()
        setToolBar()
        binding.scanInput.requestFocus()
        pendingOperations()
        callBack(viewModel.getRoutes(mobileApplication.userId!!))

    }


    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()

                    if (pendingExpedition.filter { it.code == "DELIVERED" }.isNotEmpty()) {
                        viewModel.expeditionState_add(
                            pendingExpedition.filter { it.code == "DELIVERED" },
                            "DELIVERED"
                        )
                    }

                    if (pendingExpedition.filter { it.code == "ON DELIVERY" }.isNotEmpty()) {
                        viewModel.expeditionState_add(
                            pendingExpedition.filter { it.code == "ON DELIVERY" },
                            "ON DELIVERY"
                        )
                    }
                    if (pendingExpedition.filter { it.code == "LOST" }.isNotEmpty()) {
                        viewModel.expeditionState_add(
                            pendingExpedition.filter { it.code == "LOST" },
                            "LOST"
                        )
                    }
                    if (pendingExpedition.filter { it.code == "FOUND" }.isNotEmpty()) {
                        viewModel.expeditionState_add(
                            pendingExpedition.filter { it.code == "FOUND" },
                            "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 callBack(callBackEndPoint: Unit) {
        binding.splashProgress.visibility = View.VISIBLE
        return callBackEndPoint
    }


    @RequiresApi(Build.VERSION_CODES.O)
    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)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            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 -> {
                            callBack(viewModel.getRoutes(mobileApplication.userId!!))
                        }

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

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

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

    private fun openAppDelivery(item: RouteInfo) {
        val i = Intent()
        val manager: PackageManager = requireContext().packageManager
        val info: PackageInfo = manager.getPackageInfo(requireContext().packageName, 0)
        val version = info.versionName
        try {
            if (version.contains("Beta")) {
                i.setClassName(
                    "verdnatura.es.repartoverdnatura.sfusion",
                    "verdnatura.es.repartoverdnatura.Tickets"
                )
            } else {
                i.setClassName(
                    "verdnatura.es.repartoverdnatura",
                    "verdnatura.es.repartoverdnatura.Tickets"
                )
            }
            i.putExtra("plate", item.numberPlate)
            i.putExtra("id", item.id.toString())
            i.putExtra("agency", item.name)
            i.putExtra("hour", item.hour)
            i.putExtra("date", item.created.toString())
            i.putExtra("m3", item.m3.toString())
            i.putExtra("driver", item.driver)
            i.putExtra("kmStart", item.kmStart.toString())
            i.putExtra("kmEnd", item.kmEnd.toString())
            i.putExtra("dEnd", item.finished)
            i.putExtra("dStart", item.started)
            i.putExtra("app", "picking")
            startActivity(i)
        } catch (e: Exception) {
            getString(R.string.deliveryApp).toast(context)
        }


    }


    private fun setEvents() {
        binding.mainToolbar.backButton.setOnClickListener {
            requireActivity().onBackPressed()

        }


        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) {
                val searchText = s.toString().lowercase()
                filteredList(s.toString().lowercase())

            }

            override fun afterTextChanged(s: Editable?) {

            }
        })

    }

    private fun filteredList(searchText: String) {

        val filteredList = myListRoute.filter { route ->
            route.toString().lowercase().contains(searchText)
        }.toMutableList()
        adapter!!.updateList(filteredList)
    }


    @RequiresApi(Build.VERSION_CODES.O)
    override fun observeViewModel() {
        with(viewModel) {
            loadRouteList.observe(viewLifecycleOwner) { event ->
                event.getContentIfNotHandled().notNull {
                    binding.splashProgress.visibility = View.GONE
                    createListRoutes(it.list)
                }
            }


            routeInfoList.observe(viewLifecycleOwner) {
                binding.splashProgress.visibility = View.GONE
                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
                    ma.messageWithSound(it.errorMessage, false, false, "", true)
                } else {
                    deleteSignTickets(it.response)
                }
            }

            responseLoadList.observe(viewLifecycleOwner) {
                binding.splashProgress.visibility = View.GONE
                ma.messageWithSound(getString(R.string.offline), false, false, "", true)
                createListRoutes(mutableListOf(), getSaved = true)
            }

            responseStateAdd.observe(viewLifecycleOwner) {

                if (!it.isError) {
                    binding.mainToolbar.toolbarIcons.visibility = View.VISIBLE

                    deleteExpeditionsPending(it.response)
                }
            }

        }

    }


    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 = getString(R.string.titleDeliverySummary)),
                                    item.id.toString()
                                )
                            }

                            "showTickets" -> {
                                //println("La ruta de los tickets es: " + item.id)
                                //openAppDelivery(item)
                                ma.onPasillerosItemClickListener(
                                    PasillerosItemVO(title = getString(R.string.tickets)),
                                    Gson().toJson(item)
                                )
                            }
                        }

                    }

                }, myListRouteLoaded
            )

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

}

