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

import android.Manifest
import android.app.Activity
import android.app.TimePickerDialog
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.gson.Gson
import es.verdnatura.R
import es.verdnatura.databinding.FragmentTicketsBinding
import es.verdnatura.db.DeliveryDatabase
import es.verdnatura.domain.ConstAndValues.TOKEN
import es.verdnatura.domain.isoToString
import es.verdnatura.domain.notNull
import es.verdnatura.domain.toast
import es.verdnatura.presentation.base.BaseFragment
import es.verdnatura.presentation.base.database
import es.verdnatura.presentation.common.GeneralAdapter
import es.verdnatura.presentation.common.GeneralItem
import es.verdnatura.presentation.common.ItemDescorationCustomized
import es.verdnatura.presentation.common.OnGeneralItemRowClickListener
import es.verdnatura.presentation.common.OnItemButtonCMRRowClickListener
import es.verdnatura.presentation.common.OnItemButtonTicketRowClickListener
import es.verdnatura.presentation.common.OnOptionsSelectedListener
import es.verdnatura.presentation.common.OnPasillerosItemClickListener
import es.verdnatura.presentation.common.ToolBarAdapterTooltip
import es.verdnatura.presentation.common.addDateToTime
import es.verdnatura.presentation.common.getHourDay
import es.verdnatura.presentation.view.component.CustomDialogInputNotes
import es.verdnatura.presentation.view.component.CustomDialogList
import es.verdnatura.presentation.view.feature.delivery.adapters.TicketAdapter
import es.verdnatura.presentation.view.feature.delivery.model.ClientTicketSalix
import es.verdnatura.presentation.view.feature.delivery.model.RouteInfo
import es.verdnatura.presentation.view.feature.delivery.model.Ticket
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.Calendar

class TicketsFragment : BaseFragment<FragmentTicketsBinding, DeliveryViewModel>(
    DeliveryViewModel::class
) {
    private var title: String? = null
    private lateinit var route: RouteInfo

    private var adapter: TicketAdapter? = null
    private var pasillerosItemClickListener: OnPasillerosItemClickListener? = null
    private lateinit var myListClientTicket: MutableList<ClientTicketSalix>
    private var showSigned = false
    private var showSettings = false
    private lateinit var db: DeliveryDatabase
    private var isBack = false
    private lateinit var customDialogList: CustomDialogList
    private var firstVisibleItemPosition = -1

    companion object {
        //Tarea 6810 revisar fallos app
        private const val ARG_TITLE = "title"
        private const val ARG_ROUTE = "route"
        private const val REQUEST_CALL_PERMISSION = 1

        fun newInstance(title: String, entryPoint: String) = TicketsFragment().apply {
            arguments = Bundle().apply {
                putString(ARG_TITLE, title)
                putString(ARG_ROUTE, entryPoint)
            }
        }

        /* fun newInstance(title: String, entryPoint: String) =
             TicketsFragment(title, Gson().fromJson(entryPoint, RouteInfo::class.java))*/

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            title = it.getString(ARG_TITLE)
            route = Gson().fromJson(it.getString(ARG_ROUTE), RouteInfo::class.java)
        }
    }

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

    override fun init() {
        super.init()
        setEvents()
        setToolBar()
        binding.mainToolbar.toolbarTitle.text = route.name
        viewModel.getTickets(route.id)
        db = database(requireContext().applicationContext)
        println("tickets in ")

    }

    private fun setTitle() {

        binding.mainToolbar.toolbarSubtitle.text = if (::myListClientTicket.isInitialized) {
            myListClientTicket.filter { it.signed == 1 }.size.toString() + "/" + myListClientTicket.size
        } else {
            "0/0"
        }
        customDialogList = CustomDialogList(requireContext())
    }

    private fun setToolBar() {
        ma.hideBottomNavigation(View.GONE)
        binding.mainToolbar.backButton.setOnClickListener {
            ma.onMyBackPressed()
        }
        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

        val listIcons: ArrayList<ImageView> = ArrayList()
        val iconSettings = ImageView(context)
        val iconSort = ImageView(context)
        val iconSigned = ImageView(context)
        val iconSend = ImageView(context)

        iconSettings.setImageResource(R.drawable.ic_setting_ui)
        iconSort.setImageResource(R.drawable.ic_sort)
        iconSigned.setImageResource(R.drawable.ic_sign_ticket)
        iconSend.setImageResource(R.drawable.ic_send)

        iconSettings.tooltipText = getTooltip(R.drawable.ic_setting_ui)
        iconSort.tooltipText = getTooltip(R.drawable.ic_sort)
        iconSigned.tooltipText = getTooltip(R.drawable.ic_sign_ticket)
        iconSend.tooltipText = getTooltip(R.drawable.ic_send)

        listIcons.add(iconSigned)
        listIcons.add(iconSend)
        listIcons.add(iconSettings)
        listIcons.add(iconSort)

        changeColorIcon(iconSigned.drawable, showSigned)
        changeColorIcon(iconSettings.drawable, showSigned)

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

                override fun onOptionsItemSelected(item: Drawable) {

                    when (item) {
                        iconSettings.drawable -> {
                            showSigned = !showSigned
                            changeVisibleSettings(showSigned)
                            changeColorIcon(iconSettings.drawable, showSigned)
                            binding.kmStart.setText(route.kmStart?.toString() ?: "0")
                            binding.kmEnd.setText(route.kmEnd?.toString() ?: "0")

                            binding.hourInit.setText(getHourDay(route.started.isoToString()))
                            if (route.started == "0000-00-00 00:00:00" || route.started > route.finished) {
                                binding.hourEnd.setText(getHourDay("00:00"))
                            } else {
                                binding.hourEnd.setText(getHourDay(route.finished.isoToString()))
                            }

                        }

                        iconSort.drawable -> {
                            ma.onPasillerosItemClickListener(
                                PasillerosItemVO(
                                    title = R.string.titleWebViewer,
                                ), entryPoint = Gson().toJson(
                                    mutableMapOf(
                                        "entryPoint" to route.id, "web" to "${
                                            mobileApplication.dataStoreApp.getServerSalix()
                                        }#!/route/${route.id}/tickets"
                                    )
                                )
                            )
                        }

                        iconSigned.drawable -> {

                            showSigned = !showSigned

                            if (::myListClientTicket.isInitialized) {
                                adapter!!.updateList(if (showSigned) {
                                    myListClientTicket.filter { it.signed == 1 } as MutableList<ClientTicketSalix>
                                } else {
                                    myListClientTicket.filter { it.signed == 0 } as MutableList<ClientTicketSalix>
                                })
                            }
                            changeColorIcon(iconSigned.drawable, showSigned)

                        }

                        iconSend.drawable -> {

                            if (myListClientTicket.isEmpty() || route.email.isNullOrEmpty()) {
                                getString(R.string.routeNotTickets).toast(requireContext())
                            } else {
                                viewModel.driverRouteEmail(route.id, route.email!!)
                            }

                        }

                    }
                }
            })

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

    private fun changeColorIcon(icon: Drawable, isActivated: Boolean) {
        icon.setTint(
            ContextCompat.getColor(
                requireContext(),
                if (isActivated) R.color.verdnatura_pumpkin_orange else R.color.verdnatura_white
            )
        )
    }

    override fun onPause() {
        super.onPause()
        isBack = true
    }

    override fun onResume() {
        super.onResume()
        if (isBack) {
            viewModel.getTickets(route.id)
            isBack = false
        }

    }

    private fun setEvents() {
        binding.mainToolbar.backButton.setOnClickListener {
            if (!binding.itemcardLayout.isVisible) {
                ma.onMyBackPressed()
            } else {
                setSettingsRoute()

            }
        }
        setSettingsRoute()
        setRecyclerViewer()
    }

    private fun setRecyclerViewer() {
        binding.ticketsRecyclerview.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)

                val layoutManager = recyclerView.layoutManager as LinearLayoutManager
                firstVisibleItemPosition = layoutManager.findFirstCompletelyVisibleItemPosition()

            }
        })
    }

    private fun setSettingsRoute() {

        binding.kmStart.setText(route.kmStart.toString())
        binding.kmEnd.setText(route.kmEnd.toString())
        binding.saveButton.setOnClickListener {
            route.kmStart = binding.kmStart.text.toString().toLongOrNull()
            route.kmEnd = binding.kmEnd.text.toString().toLongOrNull()
            route.started = addDateToTime(binding.hourInit.text.toString())
            route.finished = addDateToTime(binding.hourEnd.text.toString())
            viewModel.routeUpdate(route)
        }
        binding.hourInit.setOnFocusChangeListener { _, b ->
            if (b) {
                showTimePicker(binding.hourInit)
            }
        }
        binding.hourEnd.setOnFocusChangeListener { _, b ->
            if (b) {
                showTimePicker(binding.hourEnd)
            }
        }

        /*  binding.hourEnd.setOnClickListener {
              showTimePicker(binding.hourEnd)
          }*/
    }

    override fun observeViewModel() {
        with(viewModel) {
            loadRouteList.observe(viewLifecycleOwner) { event ->
                event.getContentIfNotHandled().notNull {
                    // createListRoutes(it.list)
                }
            }
            loadNotes.observe(viewLifecycleOwner) { event ->
                event.getContentIfNotHandled().notNull {
                    viewModel.getTickets(route.id)
                }
            }

            clientTicketList.observe(viewLifecycleOwner) {
                if (it.list.isNotEmpty()) {
                    createLisTickets(it.list)

                }
            }
            responseStateAdd.observe(viewLifecycleOwner) {}

            responseUpdateRoute.observe(viewLifecycleOwner) {
                showSigned = !showSigned
                changeVisibleSettings(false)
                setToolBar()
            }
            responseLoadList.observe(viewLifecycleOwner) {
                createLisTickets(mutableListOf(), getSaved = true)
            }
        }
    }

    private fun changeVisibleSettings(isVisible: Boolean) {
        if (isVisible) {
            binding.itemcardLayout.visibility = View.GONE
            binding.ticketsRecyclerview.visibility = View.GONE
            binding.layoutKmHour.visibility = View.VISIBLE
        } else {
            binding.itemcardLayout.visibility = View.VISIBLE
            binding.ticketsRecyclerview.visibility = View.VISIBLE
            binding.layoutKmHour.visibility = View.GONE
        }

    }

    private fun createLisTickets(list: MutableList<ClientTicketSalix>, getSaved: Boolean = false) {

        var myListClientTicketAux: MutableList<ClientTicketSalix> = mutableListOf()

        lifecycleScope.launch {
            withContext(Dispatchers.IO) {
                if (getSaved) {
                    myListClientTicketAux =
                        db.clienTicketDao().getAll().filter { route.id == it.route }.toMutableList()
                } else {
                    myListClientTicketAux =
                        list.distinctBy { it.addressFk } as MutableList<ClientTicketSalix>

                    for (clientTicket in myListClientTicketAux) {
                        val addressId = clientTicket.addressFk
                        val ticketsForClient = list.filter { it.addressFk == addressId }
                        val mappedTickets = ticketsForClient.map { ticket ->
                            Ticket(
                                ticket.id,
                                ticket.packages,
                                ticket.ipt,
                                ticket.observationDelivery,
                                ticket.cmrFk
                            )
                        }
                        clientTicket.tickets = mappedTickets as MutableList<Ticket>
                    }

                    //db.clienTicketDao().delete()
                    myListClientTicketAux.forEach {
                        it.route = route.id
                    }
                    db.clienTicketDao().insert(myListClientTicketAux)

                }
            }
            myListClientTicket = myListClientTicketAux

            val myListFiltered = if (showSigned) {
                myListClientTicket.filter { it.signed == 1 }
            } else {
                myListClientTicket.filter { it.signed == 0 }
            }
            adapter = TicketAdapter(myListFiltered as MutableList<ClientTicketSalix>,
                object : OnItemButtonTicketRowClickListener {

                    override fun onItemButtonTicketRowClickListener(
                        item: ClientTicketSalix, action: String
                    ) {
                        when (action) {
                            "unload" -> {

                                val entryPoint = Gson().toJson(
                                    mutableMapOf(
                                        "route" to route.id.toString(), "address" to item.addressFk
                                    )
                                )
                                ma.onPasillerosItemClickListener(PasillerosItemVO(
                                    title =
                                    R.string.titleUnLoadTruck

                                ), entryPoint, myListClientTicket.filter { it.id == item.id })
                            }

                            "map" -> {
                                goMaps(item)
                            }

                            "note" -> {
                                showNotes(item)
                            }

                            "addNote" -> {
                                addNotes(item)
                            }

                            "call" -> {
                                showPhones(item)
                            }

                        }

                    }

                },
                object : OnItemButtonCMRRowClickListener {
                    override fun onItemButtonCMRRowClickListener(
                        item: Ticket
                    ) {

                        ma.onPasillerosItemClickListener(
                            PasillerosItemVO(
                                title = R.string.titleWebViewer,
                            ), entryPoint = Gson().toJson(
                                mutableMapOf(
                                    "entryPoint" to route.id, "web" to "${
                                        mobileApplication.dataStoreApp.getServerSalix()
                                    }/api/Routes/${item.cmrFk}/cmr?access_token=${
                                        mobileApplication.dataStoreApp.readDataStoreKey<String>(
                                            TOKEN
                                        )
                                    }"
                                )
                            )
                        )
                    }
                })

            binding.ticketsRecyclerview.addItemDecoration(
                ItemDescorationCustomized(
                    resources.getDimensionPixelSize(
                        R.dimen.vertical_spacing
                    )
                )
            )
            binding.ticketsRecyclerview.adapter = adapter
            binding.ticketsRecyclerview.layoutManager =
                LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
            adapter!!.notifyDataSetChanged()
            setTitle()
            setListPosition()
        }
    }

    private fun addNotes(itemClient: ClientTicketSalix) {

        val customDialogInput = CustomDialogInputNotes(requireContext())
        customDialogInput.setTitle(getString(R.string.notes))
        //customDialogInput.setDescription(itemClient.observationDelivery.toString())

        val adapter: GeneralAdapter
        val itemsNotes: List<GeneralItem> = listOf(
            GeneralItem(code = "", text = getString(R.string.clientNot)),
            GeneralItem(code = "", text = getString(R.string.clientAuthorization)),
            GeneralItem(code = "", text = getString(R.string.clientReject)),
            GeneralItem(code = "", text = getString(R.string.packagesMissing)),
            GeneralItem(code = "", text = getString(R.string.clientDevolution)),
        )

        adapter = GeneralAdapter(itemsNotes, object : OnGeneralItemRowClickListener {

            override fun onGeneralItemRowClickListener(item: GeneralItem) {
                itemClient.tickets.forEach { listClient ->
                    listClient.Note = customDialogInput.getValue()
                }
                customDialogInput.setValue(item.text.toString())

            }
        })
        customDialogInput.getRecyclerView().adapter = adapter
        customDialogInput.getRecyclerView().layoutManager =
            LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
        customDialogInput.setOkButton(getString(R.string.save)) {
            if (itemClient.observationDropOff == null) {
                viewModel.addFropOff(
                    ticketFK = itemClient.id,
                    note = customDialogInput.getValue(),

                    )
            } else {
                viewModel.updateNotesFromDropOff(
                    itemClient.id, description = customDialogInput.getValue()
                )
            }

            customDialogInput.dismiss()
        }.setKoButton(getString(R.string.cancel)) {
            customDialogInput.cancel()
            customDialogInput.dismiss()
        }
        customDialogInput.show()

    }

    fun showNotes(clientClicked: ClientTicketSalix) {
        val ticketNotes: MutableList<GeneralItem> = mutableListOf()
        //Tarea 6275
        if (!clientClicked.observationDelivery.isNullOrBlank()) {

            ticketNotes.add(
                GeneralItem(
                    text = getString(R.string.deliveryNote, clientClicked.observationDelivery),
                    code = ""
                )
            )
        }
        if (!clientClicked.observationDropOff.isNullOrBlank()) {

            ticketNotes.add(
                GeneralItem(
                    text = getString(R.string.deliveryDriverNote, clientClicked.observationDropOff),
                    code = ""
                )
            )
        }

        customDialogList.setValueVisibility(View.GONE)
        customDialogList.setTitle(getString(R.string.ticketNotes)).setKoButton(
            getString(
                R.string.cancel
            )
        ) {
            customDialogList.dismiss()
        }.hideDialog().show()

        val listPhonesAdapter = GeneralAdapter(ticketNotes, object : OnGeneralItemRowClickListener {
            override fun onGeneralItemRowClickListener(item: GeneralItem) {

                customDialogList.dismiss()
            }

        })

        customDialogList.getRecyclerView().adapter = listPhonesAdapter
        customDialogList.getRecyclerView().layoutManager =
            LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)

    }

    private fun setListPosition() {
        (binding.ticketsRecyclerview.layoutManager as LinearLayoutManager).scrollToPosition(
            firstVisibleItemPosition
        )
    }

    fun showPhones(clientClicked: ClientTicketSalix) {
        val phones: MutableList<GeneralItem> = mutableListOf()
        //Tarea 6275
        if (!clientClicked.clientPhone.isNullOrBlank()) {
            phones.add(
                GeneralItem(
                    text = "${getString(R.string.Cliente)}:${clientClicked.clientPhone}",
                    code = clientClicked.clientPhone.toString()
                )
            )
        }
        if (!clientClicked.clientMobile.isNullOrBlank()) {
            phones.add(
                GeneralItem(
                    text = "${getString(R.string.Cliente)}:${clientClicked.clientMobile}",
                    code = clientClicked.clientMobile.toString()
                )
            )
        }
        if (!clientClicked.addressPhone.isNullOrBlank()) {
            phones.add(
                GeneralItem(
                    text = "${getString(R.string.Cliente)}:${clientClicked.addressPhone}",
                    code = clientClicked.addressPhone.toString()
                )
            )
        }
        if (!clientClicked.salePersonPhone.isNullOrBlank()) phones.add(
            GeneralItem(
                text = "${getString(R.string.comercial)}:${clientClicked.salePersonPhone}",
                code = clientClicked.salePersonPhone.toString()
            )
        )

        customDialogList.setValueVisibility(View.GONE)
        customDialogList.setTitle(getString(R.string.phones)).setKoButton(
            getString(
                R.string.cancel
            )
        ) {
            customDialogList.dismiss()
        }.hideDialog().show()

        val listPhonesAdapter = GeneralAdapter(phones, object : OnGeneralItemRowClickListener {
            override fun onGeneralItemRowClickListener(item: GeneralItem) {
                phones.forEach {
                    if (it.code == item.code) {
                        if (ContextCompat.checkSelfPermission(
                                requireContext(), Manifest.permission.CALL_PHONE
                            ) == PackageManager.PERMISSION_GRANTED
                        ) {
                            val callIntent = Intent(Intent.ACTION_CALL)
                            callIntent.data = Uri.parse("tel:${it.code}")
                            startActivity(callIntent)
                            return@forEach

                        }
                    } else {
                        ActivityCompat.requestPermissions(
                            context as Activity,
                            arrayOf(Manifest.permission.CALL_PHONE),
                            REQUEST_CALL_PERMISSION
                        )
                    }
                    customDialogList.dismiss()
                }
            }

        })

        customDialogList.getRecyclerView().adapter = listPhonesAdapter
        customDialogList.getRecyclerView().layoutManager =
            LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)

    }

    fun goMaps(item: ClientTicketSalix) {

        val uri: String = if (item.latitude != null) {
            "geo:${item.latitude},${item.longitude}?q=" + item.nickname + " " + item.street + " " + item.city + " " + item.postalCode

        } else {
            "geo:0,0?q=" + item.nickname + " " + item.street + " " + item.city + " " + item.postalCode
        }
        val locationIntent = Intent(Intent.ACTION_VIEW, Uri.parse(uri))
        startActivity(locationIntent)

    }

    private fun showTimePicker(textV: TextView) {

        val mcurrentTime = Calendar.getInstance()
        val hour = mcurrentTime[Calendar.HOUR_OF_DAY]
        val minute = mcurrentTime[Calendar.MINUTE]
        val mTimePicker = TimePickerDialog(
            requireContext(), { _, selectedHour, selectedMinute ->
                textV.text = getString(R.string.hourMinute, selectedHour, selectedMinute)
            }, hour, minute, true
        )
        mTimePicker.setTitle(getString(R.string.selectTime))
        mTimePicker.show()

    }

}