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

import android.Manifest
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.location.Location
import android.os.Build
import android.view.View
import android.widget.ImageView
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.gson.Gson
import es.verdnatura.MobileApplication
import es.verdnatura.R
import es.verdnatura.databinding.ActivitySignBinding
import es.verdnatura.db.DeliveryDatabase
import es.verdnatura.domain.toast
import es.verdnatura.presentation.base.BaseActivity
import es.verdnatura.presentation.base.LocationUpdateCallback
import es.verdnatura.presentation.base.database
import es.verdnatura.presentation.common.GeneralAdapter
import es.verdnatura.presentation.common.GeneralItem
import es.verdnatura.presentation.common.OnGeneralItemRowClickListener
import es.verdnatura.presentation.common.OnOptionsSelectedListener
import es.verdnatura.presentation.common.SignListener
import es.verdnatura.presentation.common.ToolBarAdapterTooltip
import es.verdnatura.presentation.view.component.CustomDialog
import es.verdnatura.presentation.view.component.CustomDialogList
import es.verdnatura.presentation.view.feature.delivery.model.ClientTicketSalix
import es.verdnatura.presentation.view.feature.delivery.model.MyLocation
import es.verdnatura.presentation.view.feature.delivery.model.SignedTickets
import es.verdnatura.presentation.view.feature.delivery.model.TicketObservation
import es.verdnatura.presentation.view.feature.delivery.viewmodels.DeliveryViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

class SignedActivity : BaseActivity<ActivitySignBinding>(), LocationUpdateCallback, SignListener {

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

    private lateinit var fusedLocationClient: com.google.android.gms.location.FusedLocationProviderClient
    private var lastLocationCurrent: MyLocation = MyLocation(0.0, 0.0)
    private lateinit var ticketsSet: HashSet<Long>
    private lateinit var clientTicket: ClientTicketSalix
    private lateinit var db: DeliveryDatabase
    private lateinit var deliveryViewModel: DeliveryViewModel
    private lateinit var listClaimTicketObservations: List<TicketObservation>

    override fun init() {
        deliveryViewModel = DeliveryViewModel(application as MobileApplication)
        when (intent.getStringExtra("objectSigned")) {

            "ticket" -> {
                binding.mainToolbar.toolbarTitle.text = getString(R.string.sign)
                clientTicket =
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) (
                            intent.extras?.getSerializable(
                                "clientTicketList",
                                ClientTicketSalix::class.java
                            )
                            )!! else (
                            @Suppress("DEPRECATED")
                            intent.extras!!.getSerializable("clientTicketList") as? ClientTicketSalix
                            )!!
                setViews(clientTicket)
                setLocation()
            }

        }

        setEvents()
        (application as MobileApplication).setSignListener(this)
        db = database(this.applicationContext)

    }

    private fun setToolBar() {
        // binding.mainToolbar.toolbarIcons.visibility = View.GONE

        val listIcons: ArrayList<ImageView> = ArrayList()
        val iconObservation = ImageView(this)
        iconObservation.setImageResource(R.drawable.ic_claim_ui)
        iconObservation.tooltipText = getString(R.string.showClaimObservation)
        listIcons.add(iconObservation)



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

                override fun onOptionsItemSelected(item: Drawable) {
                    when (item) {
                        iconObservation.drawable -> {
                            showNotes(listClaimTicketObservations)
                        }
                    }
                }

            })

        binding.mainToolbar.toolbarIcons.layoutManager =
            LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)

    }

    private fun showDialogConfirm() {
        val customDialog = CustomDialog(this)
        customDialog.setTitle(getString(R.string.confirm))
            .setDescription(getString(R.string.sureSign)).setOkButton(getString(R.string.ok)) {

                reviewDistance()
                customDialog.dismiss()

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

    private fun reviewDistance() {

        val locationCurrent = Location("").apply {
            this.latitude = lastLocationCurrent.Latitude
            this.longitude = lastLocationCurrent.Longitude
        }
        val locationClient = Location("").apply {
            this.latitude = clientTicket.latitude ?: 0.0
            this.longitude = clientTicket.longitude ?: 0.0
        }


        if (clientTicket.latitude != null && clientTicket.longitude != null) {
            if (locationCurrent.distanceTo(locationClient) > 100) {

                val customDialogDistance = CustomDialog(this)
                customDialogDistance.setTitle(getString(R.string.confirm)).setDescription(
                    getString(R.string.locationDiferent) + getString(R.string.distance) + locationCurrent.distanceTo(
                        locationClient
                    )
                ).setOkButton(getString(R.string.keep)) {

                    uploadImage(MyLocation(locationClient.longitude, locationClient.latitude))
                    customDialogDistance.dismiss()

                }.setKoButton(getString(R.string.modify)) {
                    uploadImage(lastLocationCurrent)
                    customDialogDistance.dismiss()
                }.show()
            } else {
                uploadImage(MyLocation(locationClient.longitude, locationClient.latitude))
            }
        } else {
            uploadImage(lastLocationCurrent)
        }
    }

    private fun setEvents() {
        binding.btnSave.setOnClickListener {
            showDialogConfirm()
        }
        binding.mainToolbar.backButton.setOnClickListener {
            finish()
        }
    }

    private fun setViews(clientTicketList: ClientTicketSalix) {

        binding.nameAddress.text = clientTicketList.nickname
        ticketsSet = HashSet()
        var sum = 0
        for (exp in clientTicketList.tickets) {
            ticketsSet.add(exp.Id)
            sum += exp.Packages

        }
        //Tarea 7541

        deliveryViewModel.getTicketObservations(ticketsSet.toList())
        deliveryViewModel.responseObservations.observe(this) { itList ->
            listClaimTicketObservations = itList
            if (itList.isNotEmpty()) {
                if (itList.count { it.observationType != null } > 0) {
                    showNotes(itList)
                    setToolBar()
                }
            }
        }
        binding.idTickets.text = ticketsSet.toList().toString()
        binding.totalPackages.text = sum.toString()

    }

    private fun showNotes(listClaimObservations: List<TicketObservation>) {
        val ticketNotes: MutableList<GeneralItem> = mutableListOf()
        //Tarea 6275
        for (item in listClaimObservations) {
            if (item.observationType != null)
                ticketNotes.add(
                    GeneralItem(
                        text = "${item.ticketFk}:${item.description}", code = ""
                    )
                )
        }
        val customDialogList = CustomDialogList(this)

        customDialogList.setValueVisibility(View.GONE)
        customDialogList.setTitle(getString(R.string.notesClaim)).setKoButton(
            getString(
                R.string.accept
            )
        ) {
            customDialogList.dismiss()
        }.show()

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

                    customDialogList.dismiss()
                }

            })

        customDialogList.getRecyclerView().adapter = listObservationsAdapter
        customDialogList.getRecyclerView().layoutManager =
            LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)

    }

    private fun uploadImage(location: MyLocation) {

        val drawing = binding.ink.bitmap
        val file = File(bitMapToString(drawing, tickets = ticketsSet.toList()))
        val queryMap: MutableMap<String?, String?> = HashMap()
        queryMap["tickets"] = ticketsSet.toString()
        queryMap["location"] = Gson().toJson(location)
        queryMap["signedTime"] = SimpleDateFormat("yyyy-LL-dd HH:mm", Locale.getDefault()).format(
            Date()
        )

        val mySign = SignedTickets(
            queryMap, baseContext.externalCacheDir.toString() + "/" + file.name
        )

        deliveryViewModel.saveSign(
            mySign.fileName, mySign.queryMapList,
        )

        deliveryViewModel.responseSign.observe(this) {

            if (!it.isError) {
                finish()
            } else {
                it.message.toast(this)
                lifecycleScope.launch {
                    withContext(Dispatchers.IO) {
                        db.signedTicketDao().insert(mySign)
                    }
                }

            }
        }

    }

    @Throws(IOException::class)
    fun bitMapToString(bitmap: Bitmap, tickets: List<Long>): String {
        var fileNameSign = baseContext.externalCacheDir.toString() + "/sign"
        for (ticket in tickets) {
            fileNameSign += "_$ticket"
        }
        //Create a file to write bitmap data
        val f = File("$fileNameSign.png")
        f.createNewFile()

        //Convert bitmap to byte array
        val baos = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos)
        val b = baos.toByteArray()

        //write the bytes in file
        val fos = FileOutputStream(f)
        fos.write(b)
        fos.flush()
        fos.close()
        return "$fileNameSign.png"
    }

    private fun setLocation() {
        ActivityCompat.requestPermissions(
            this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 111
        )
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
        locationUpdateCallback = this
        requestLocationUpdates(fusedLocationClient)

    }

    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<out String>, grantResults: IntArray
    ) {

        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        val permission = Manifest.permission.ACCESS_FINE_LOCATION
        if (requestCode == 111) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                requestLocationUpdates(fusedLocationClient)
            } else {
                if (!shouldShowRequestPermissionRationale(permission)) {

                    val builder = AlertDialog.Builder(this)
                    builder.apply {
                        setTitle(getString(R.string.permissionRequired))
                        setMessage(getString(R.string.manuallyPermission))
                        setPositiveButton(
                            "Aceptar"
                        ) { _, _ ->
                            finish()
                        }

                    }

                    val dialog = builder.create()
                    dialog.show()

                } else {

                    val activity = this
                    val builder = AlertDialog.Builder(this)
                    builder.apply {
                        setTitle(getString(R.string.permissionRequired))
                        setMessage(getString(R.string.advicePermission))
                        setPositiveButton(
                            getString(R.string.accept)
                        ) { dialog, _ ->
                            dialog.dismiss()
                            ActivityCompat.requestPermissions(
                                activity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 111
                            )

                        }
                        setNegativeButton(
                            getString(R.string.cancel)
                        ) { _, _ ->
                            finish()
                        }
                    }

                    val dialog = builder.create()
                    dialog.show()
                }

            }
        }
    }

    override fun onLocationReceived(location: LocationResult) {
        if (location.locations.isNotEmpty()) {
            lastLocationCurrent.Longitude = location.locations.last().longitude
            lastLocationCurrent.Latitude = location.locations.last().latitude
        }
    }

    override fun onApplicationEventAnimation(visibility: Int) {
        binding.splashAnimation.visibility = visibility

    }

}



