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

import android.Manifest
import android.app.Activity
import android.app.AlertDialog
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.Build
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.RequiresApi
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 com.google.gson.Gson
import es.verdnatura.R
import es.verdnatura.databinding.FragmentTicketsBinding
import es.verdnatura.db.DeliveryDatabase
import es.verdnatura.domain.ConstAndValues.BASEURLSALIX
import es.verdnatura.domain.ConstAndValues.TOKEN
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.*
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.ExpeditionInfoLoadUnload
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(
    var title: String = "", var route: RouteInfo
) : BaseFragment<FragmentTicketsBinding, DeliveryViewModel>(
    DeliveryViewModel::class
) {

    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

    companion object {
        fun newInstance(title: String, entryPoint: String) =
            TicketsFragment(title, Gson().fromJson(entryPoint, RouteInfo::class.java))

        private const val REQUEST_CALL_PERMISSION = 1

    }

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

    @RequiresApi(Build.VERSION_CODES.O)
    override fun init() {
        super.init()
        setEvents()
        setToolBar()
        binding.mainToolbar.toolbarTitle.text = route.name
        viewModel.getTickets(route.id)
        db = database(requireContext().applicationContext)

    }

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

    @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

        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)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            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())
                            binding.kmEnd.setText(route?.kmEnd?.toString())

                        }

                        iconSort.drawable -> {
                            ma.onPasillerosItemClickListener(
                                PasillerosItemVO(
                                    title = getString(R.string.titleWebViewer),
                                ), entryPoint = Gson().toJson(
                                    mutableMapOf(
                                        "entryPoint" to route.id,
                                        "web" to "${
                                            mobileApplication.dataStoreApp.readDataStoreKey<String>(
                                                BASEURLSALIX
                                            )
                                        }#!/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) {
                requireActivity().onBackPressed()
            } else {
                setSettingsRoute()

            }
        }
        setSettingsRoute()
    }

    private fun setSettingsRoute() {

        binding.kmStart.setText(route.kmStart.toString())
        binding.kmEnd.setText(route.kmEnd.toString())
        binding.hourInit.setText(getHourDay(route.started))
        binding.hourEnd.setText(getHourDay(route.finished))

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

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

    @RequiresApi(Build.VERSION_CODES.O)
    override fun observeViewModel() {
        with(viewModel) {
            loadRouteList.observe(viewLifecycleOwner) { event ->
                event.getContentIfNotHandled().notNull {
                    // createListRoutes(it.list)
                }
            }


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

                }
            }
            responseStateAdd.observe(viewLifecycleOwner) {}
            response.observe(viewLifecycleOwner) {
                if (!it.isError) {
                    ma.messageWithSound(it.response, false, false, "", true)
                }
            }
            responseUpdateRoute.observe(viewLifecycleOwner) {
                showSigned = !showSigned
                changeVisibleSettings(false)
                setToolBar()
            }
            responseLoadList.observe(viewLifecycleOwner) {
                ma.messageWithSound(getString(R.string.offline), true, false, "", true)
                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.ticketObservation,
                                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 = getString(
                                        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 = getString(R.string.titleWebViewer),
                            ), entryPoint = Gson().toJson(
                                mutableMapOf(
                                    "entryPoint" to route.id,
                                    "web" to "${
                                        mobileApplication.dataStoreApp.readDataStoreKey<String>(
                                            BASEURLSALIX
                                        )
                                    }/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()
        }
    }

    private fun addNotes(itemClient: ClientTicketSalix) {

        val customDialogInput = CustomDialogInputNotes(requireContext())
        customDialogInput.setTitle("Notas")

        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)) {
            viewModel.addNotes(itemClient.tickets, customDialogInput.getValue())
            customDialogInput.dismiss()
        }.setKoButton(getString(R.string.cancel)) {
            customDialogInput.cancel()
            customDialogInput.dismiss()
        }
        customDialogInput.show()

    }

    private fun showNotes(item: ClientTicketSalix) {

        val alertDialog = AlertDialog.Builder(requireContext()).create()
        alertDialog.setTitle(getString(R.string.info))
        alertDialog.setMessage(item.ticketObservation)
        alertDialog.setButton(
            AlertDialog.BUTTON_NEUTRAL, getString(R.string.close)
        ) { dialog, _ -> dialog.dismiss() }
        alertDialog.show()

    }

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

    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.clientMobile.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)
                        }
                    } 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 = "$selectedHour:$selectedMinute" },
            hour,
            minute,
            true
        )
        mTimePicker.setTitle(getString(R.string.selectTime))
        mTimePicker.show()

    }
}