package es.verdnatura.presentation.view.feature.packaging.fragment

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Environment
import android.view.View
import android.widget.ImageView
import androidx.core.graphics.drawable.toBitmap
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.esafirm.imagepicker.features.ImagePickerConfig
import com.esafirm.imagepicker.features.registerImagePicker
import com.esafirm.imagepicker.model.Image
import es.verdnatura.R
import es.verdnatura.databinding.FragmentPackagingObsBinding
import es.verdnatura.domain.ConstAndValues.ENTRYID
import es.verdnatura.domain.ConstAndValues.ENTRYNUMBERIMAGES
import es.verdnatura.domain.ConstAndValues.ENTRYOBSERVATIONORIGINAL
import es.verdnatura.domain.ConstAndValues.ENTRYOBSERVATIONS
import es.verdnatura.domain.ConstAndValues.SUPPLIERNAME
import es.verdnatura.domain.ConstAndValues.WAREHOUSEFK
import es.verdnatura.domain.notNull
import es.verdnatura.presentation.base.BaseFragment
import es.verdnatura.presentation.common.OnImageTrashClickListener
import es.verdnatura.presentation.common.OnImageUpdateClickListener
import es.verdnatura.presentation.common.OnOptionsSelectedListener
import es.verdnatura.presentation.common.OnPasillerosItemClickListener
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.packaging.adapter.ListImageAdapter
import es.verdnatura.presentation.view.feature.packaging.fragment.ObservFragment.ImageUtils.getDrawableFromImageUri
import es.verdnatura.presentation.view.feature.pasillero.model.PasillerosItemVO
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

class ObservFragment(
    var entryPoint: String = ""

) : BaseFragment<FragmentPackagingObsBinding, SupplierViewModel>(
    SupplierViewModel::class
) {

    private var adapterListImage: ListImageAdapter? = null
    private var listImages: MutableList<Image>? = null
    private var listImagesOriginal: MutableList<Image>? = mutableListOf()
    private lateinit var customDialog: CustomDialog
    private var pasillerosItemClickListener: OnPasillerosItemClickListener? = null
    private var layoutManager: LinearLayoutManager? = null
    private lateinit var customDialogList: CustomDialogList

    companion object {
        fun newInstance(entryPoint: String) = ObservFragment(entryPoint)
    }

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

    override fun onAttach(context: Context) {
        if (context is OnPasillerosItemClickListener) pasillerosItemClickListener = context
        super.onAttach(context)
    }

    override fun init() {
        customDialog = CustomDialog(requireContext())
        ma.hideBottomNavigation(View.GONE)
        setToolBar()
        setEvents()
        setObservations()
        loadImages()
        super.init()
    }

    private fun setObservations() {
        binding.observations.setText(
            mobileApplication.dataStoreApp.readDataStoreKey<String>(
                ENTRYOBSERVATIONS
            )
        )
    }

    private fun setToolBar() {

        binding.mainToolbar.toolbarTitle.text = buildString {
            append(mobileApplication.dataStoreApp.readDataStoreKey<String>(SUPPLIERNAME))
        }

        val listIcons: ArrayList<ImageView> = ArrayList()
        val iconNext = ImageView(context)
        iconNext.setImageResource(R.drawable.ic_chevron_right_black_24dp)
        iconNext.tooltipText = getString(R.string.nextEntrySummary)

        listIcons.add(iconNext)
        binding.mainToolbar.toolbarIcons.adapter =
            ToolBarAdapterTooltip(listIcons, object : OnOptionsSelectedListener {
                override fun onOptionsItemSelected(item: Drawable) {
                    when (item) {
                        iconNext.drawable -> {

                            if (listImages == null || listImages!!.isEmpty()) {
                                ma.messageWithSound(
                                    message = getString(R.string.entryInputImage),
                                    isError = true,
                                    isPlayed = true
                                )
                            } else {

                                runBlocking {
                                    mobileApplication.dataStoreApp.editDataStoreKey(
                                        ENTRYNUMBERIMAGES,
                                        if (listImages.isNullOrEmpty()) 0 else {
                                            listImages!!.size
                                        }
                                    )
                                    mobileApplication.dataStoreApp.editDataStoreKey(
                                        ENTRYOBSERVATIONS,
                                        binding.observations.text.toString()
                                    )
                                }


                                if (!binding.observations.text.isNullOrBlank()) {
                                    val originalObservation =
                                        mobileApplication.dataStoreApp.readDataStoreKey<String>(
                                            ENTRYOBSERVATIONORIGINAL
                                        )

                                    viewModel.entryUpdateObserv(
                                        mobileApplication.dataStoreApp.readDataStoreKey(
                                            ENTRYID
                                        ),
                                        originalObservation + " " + binding.observations.text.toString()
                                    )

                                } else {
                                    openSummary()
                                }
                            }

                        }

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

    }

    private fun openSummary() {
        ma.onPasillerosItemClickListener(
            PasillerosItemVO(title = R.string.titlePackagingSummary),
            getString(R.string.titlePackagingSummary)
        )
    }

    private fun setEvents() {

        val launcher = registerImagePicker {

            //  listImages?.clear()
            try {
                listImages = it as? MutableList<Image>
                // listImagesOriginal = it as? MutableList<Image>
            } catch (ex: Exception) {

            }
            if (listImages != null && listImages!!.isNotEmpty()) {
                //setAdapter(listImages!!)
                //  listImagesOriginal?.clear()
                //  listImagesOriginal?.addAll(listImages!!)
                runBlocking { mobileApplication.dataStoreApp.saveImages(listImages) }
                loadImages()
                uploadImages(listImages!!)
            }

        }

        binding.mainToolbar.backButton.setOnClickListener {
            ma.onMyBackPressed()
        }
        binding.openPickerImages.setOnClickListener {
            val config = ImagePickerConfig {
                doneButtonText = getString(R.string.done) // done button text
                language = "es" // Set image picker language
                arrowColor = Color.WHITE // set toolbar arrow up color
                theme = R.style.ToolPickerImage
                /*    mode = ImagePickerMode.SINGLE // default is multi image mode
                    language = "in" // Set image picker language
                    theme = R.style.ImagePickerTheme
                    // set whether pick action or camera action should return immediate result or not. Only works in single mode for image picker
                    returnMode = if (returnAfterCapture) ReturnMode.ALL else ReturnMode.NONE
                    isFolderMode = folderMode // set folder mode (false by default)
                    isIncludeVideo = includeVideo // include video (false by default)
                    isOnlyVideo = onlyVideo // include video (false by default)
                    arrowColor = Color.RED // set toolbar arrow up color
                    folderTitle = "Folder" // folder selection title
                    imageTitle = "Tap to select" // image selection title
                    doneButtonText = "DONE" // done button text
                    limit = 10 // max images can be selected (99 by default)
                    isShowCamera = true // show camera or not (true by default)
                    savePath = ImagePickerSavePath("Camera") // captured image directory name ("Camera" folder by default)
                    savePath = ImagePickerSavePath(Environment.getExternalStorageDirectory().path, isRelative = false) // can be a full path
                    excludedImages = images.toFiles() // don't show anything on this selected images
                    selectedImages = images  // original selected images, used in multi mode*/
            }

            launcher.launch(config)
            listImages?.let { images ->
                listImagesOriginal?.addAll(images)
            }
        }

    }

    private fun loadImages() {
        lifecycleScope.launch {
            mobileApplication.dataStoreApp.getImages().collect { images ->
                listImages = images.toMutableList()
                setAdapter(listImages!!)
            }
        }
    }

    private fun uploadImages(listImages: MutableList<Image>) {

        for (item in listImages) {
            val drawable = getDrawableFromImageUri(requireContext(), item.uri)
            val bitmap = drawable!!.toBitmap()

            viewModel.entryUploadPhotoSalix(
                idEntry = mobileApplication.dataStoreApp.readDataStoreKey<Int>(ENTRYID),
                warehouseId = mobileApplication.dataStoreApp.readDataStoreKey<Int>(
                    WAREHOUSEFK
                ),
                companyId = 442,
                dmsTypeId = 27,
                reference = mobileApplication.dataStoreApp.readDataStoreKey<Int>(
                    ENTRYID
                ).toString(),
                description = mobileApplication.dataStoreApp.readDataStoreKey<Int>(
                    ENTRYID
                ).toString(),
                hasFile = false,
                urlImage = saveBitmapAsTempFile(requireContext(), bitmap)
            )
        }

    }

    override fun observeViewModel() {
        with(viewModel) {
            loadEntryUpdate.observe(viewLifecycleOwner) { event ->
                event.getContentIfNotHandled().notNull {
                    openSummary()
                }
            }
        }
    }

    private fun setAdapter(list: MutableList<Image>) {
        adapterListImage =
            ListImageAdapter(list, object : OnImageUpdateClickListener {

                override fun onImageUpdateClickListener(item: Any) {

                    val drawable = getDrawableFromImageUri(requireContext(), (item as Image).uri)
                    val bitmap = drawable!!.toBitmap()

                    viewModel.entryUploadPhotoSalix(
                        idEntry = mobileApplication.dataStoreApp.readDataStoreKey<Int>(ENTRYID),
                        warehouseId = mobileApplication.dataStoreApp.readDataStoreKey<Int>(
                            WAREHOUSEFK
                        ),
                        companyId = 442,
                        dmsTypeId = 27,
                        reference = mobileApplication.dataStoreApp.readDataStoreKey<Int>(
                            ENTRYID
                        ).toString(),
                        description = mobileApplication.dataStoreApp.readDataStoreKey<Int>(
                            ENTRYID
                        ).toString(),
                        hasFile = false,
                        urlImage = saveBitmapAsTempFile(requireContext(), bitmap)
                    )

                }

            }, object : OnImageTrashClickListener {

                override fun onImageTrashClickListener(item: Any) {
                    list.remove(item)
                    adapterListImage!!.notifyDataSetChanged()
                }

            })

        binding.listImagesRecycler.adapter = adapterListImage
        layoutManager =
            LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
        binding.listImagesRecycler.layoutManager = layoutManager
    }

    private fun saveBitmapAsTempFile(context: Context, bitmap: Bitmap): String {
        val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
        val fileName = "IMG_$timeStamp"

        val storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        val tempFile = File.createTempFile(fileName, ".jpg", storageDir)

        return try {
            val fileOutputStream = FileOutputStream(tempFile)
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream)
            fileOutputStream.close()
            tempFile.absolutePath

        } catch (e: IOException) {
            e.printStackTrace()
            ""
        }
    }

    object ImageUtils {

        fun getDrawableFromImageUri(context: Context, imageUri: Uri): Drawable? {
            return try {
                // Obtener el InputStream de la URI
                val inputStream: InputStream? = context.contentResolver.openInputStream(imageUri)

                // Convertir el InputStream a un Bitmap
                val bitmap: Bitmap? = BitmapFactory.decodeStream(inputStream)

                // Convertir el Bitmap a un Drawable
                val drawable = bitmap?.let { BitmapDrawable(context.resources, it) }

                // Cerrar el InputStream
                inputStream?.close()

                // Retornar el Drawable
                drawable
            } catch (e: Exception) {
                e.printStackTrace()
                null
            }
        }
    }

}

