package org.foxarmy.barcodescannerforemployees.fragments

import android.content.Intent
import android.os.Bundle
import android.provider.BaseColumns
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.core.view.children
import androidx.fragment.app.Fragment
import org.foxarmy.barcodescannerforemployees.AbstractProductContract
import org.foxarmy.barcodescannerforemployees.DBStorageController
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.activities.AddAbstractProductActivity
import org.foxarmy.barcodescannerforemployees.databinding.FragmentStorageBinding
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
import org.foxarmy.barcodescannerforemployees.generateThumbnailForImage
import org.foxarmy.barcodescannerforemployees.views.AbstractProductView
import kotlin.concurrent.thread

class StorageFragment : Fragment() {

    private lateinit var binding: FragmentStorageBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentStorageBinding.inflate(inflater)

        fillUpSortBySpinner()

        binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onNothingSelected(parent: AdapterView<*>?) {
                updateContent()
            }

            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                updateContent()
            }
        }

        return binding.root
    }

    override fun onResume() {
        super.onResume()

        updateContent()
    }

    private fun fillUpSortBySpinner() {
        val sorts = mutableListOf("Name", "Category")

        val arrayAdapter = ArrayAdapter(requireContext(), androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, sorts)
        arrayAdapter.setDropDownViewResource(androidx.appcompat.R.layout.support_simple_spinner_dropdown_item)
        binding.spinner.adapter = arrayAdapter
    }

    fun removeSelected() {
        thread {
            val grv = binding.contentGridLayout

            val db = DBStorageController(requireContext())
            var deleted = false
            for (view: AbstractProductView in grv.children.iterator() as Iterator<AbstractProductView>) {
                activity!!.runOnUiThread {
                    view.findViewById<ImageView>(R.id.productPicture).setImageURI(null)
                }
                if (view.isProductSelected) {
                    db.eraseAbstractProduct(db.writableDatabase, view.abstractProduct.id, requireContext())
                    deleted = true
                }
            }

            if (!deleted) {
                activity!!.runOnUiThread {
                    Toast.makeText(requireContext(), "Nothing to delete", Toast.LENGTH_SHORT).show()
                }
            }
            updateContent()
        }
    }

    fun updateSelected() {
        val grv = binding.contentGridLayout

        for (view: AbstractProductView in grv.children.iterator() as Iterator<AbstractProductView>) {
            if (view.isProductSelected) {
                val addProductIntent = Intent(requireContext(), AddAbstractProductActivity::class.java)
                val extras = Bundle()
                extras.putParcelable("abstractProduct", view.abstractProduct)
                addProductIntent.putExtras(extras)
                ContextCompat.startActivity(requireContext(), addProductIntent, extras)
            }
        }
    }

    fun updateContent() {
        thread {
            val grv = binding.contentGridLayout
            activity!!.runOnUiThread{
                grv.removeAllViews()
            }

            val db = DBStorageController(requireContext()).readableDatabase
            val projection = arrayOf(
                BaseColumns._ID,
                AbstractProductContract.AbstractProductEntry.BARCODE,
                AbstractProductContract.AbstractProductEntry.PRODUCT_NAME,
                AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT,
                AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME,
                AbstractProductContract.AbstractProductEntry.CATEGORY,
                AbstractProductContract.AbstractProductEntry.UNIT
            )

            var orderBy: String = ""
            Log.d("QWERTYUIOP", binding.spinner.selectedItem.toString())
            when(binding.spinner.selectedItem) {
                "Name" -> {
                    orderBy = "${AbstractProductContract.AbstractProductEntry.PRODUCT_NAME} ASC"
                }
                "Category" -> {
                    orderBy = "${AbstractProductContract.AbstractProductEntry.CATEGORY} ASC"
                }
            }

            val cursor = db.query(AbstractProductContract.AbstractProductEntry.TABLE_NAME, projection, null, null, null, null, orderBy)

            with (cursor) {
                while(moveToNext()) {
                    val productId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
                    val barcode = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.BARCODE))
                    val productName = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
                    val netWeight = getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
                    val productImageHash = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
                    val category = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.CATEGORY))
                    val unit = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.UNIT))

                    val product = AbstractProduct(productId, barcode, productName, netWeight, productImageHash, category, unit)

                    generateThumbnailForImage(context!!, productImageHash)

                    val abstractProduct = AbstractProductView(
                        requireActivity(),
                        requireContext(),
                        product
                    )

                    activity!!.runOnUiThread{
                        grv.addView(abstractProduct)
                    }
                }
            }
        }.join()
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        updateContent()
    }
}