package org.foxarmy.barcodescannerforemployees.activities

import android.app.DatePickerDialog
import android.os.Bundle
import android.view.View
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.addTextChangedListener
import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
import org.foxarmy.barcodescannerforemployees.DBStorageController
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
import org.foxarmy.barcodescannerforemployees.dataclasses.Product
import org.foxarmy.barcodescannerforemployees.views.AbstractProductView
import java.text.SimpleDateFormat
import java.util.*

class AddProductActivity : AppCompatActivity() {

    private lateinit var scanButton: Button
    private lateinit var abstractProductView: AbstractProductView
    private lateinit var expiryDateRadioButton: RadioButton
    private lateinit var shelfLifeRadioButton: RadioButton

    private lateinit var expiryDateTextView: TextView
    private lateinit var expiryDateSelectButton: Button

    private lateinit var shelfLifeTextView: TextView
    private lateinit var shelfLifeTextEdit: EditText

    private lateinit var amountTextEdit: EditText

    private lateinit var dateOfProductionSelectButton: Button
    private lateinit var saveProductButton: Button

    private var expiryDateOverShelfLife: Boolean? = null
    private var updatingExistentProduct = false
    private var product: Product? = null
    private var abstractProduct: AbstractProduct? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.fragment_add_product)

        scanButton = findViewById(R.id.scanButton)
        abstractProductView = findViewById(R.id.abstractProductView)
        expiryDateRadioButton = findViewById(R.id.expiryDateRadio)
        shelfLifeRadioButton = findViewById(R.id.shelfLifeRadio)

        expiryDateTextView = findViewById(R.id.expiryDateTextView)
        expiryDateSelectButton = findViewById(R.id.selectExpiryDateButton)

        shelfLifeTextView = findViewById(R.id.shelfLife)
        shelfLifeTextEdit = findViewById(R.id.shelfLifeTextEdit)

        amountTextEdit = findViewById(R.id.amountTextEdit)

        dateOfProductionSelectButton = findViewById(R.id.selectDateOfProductionButton)
        saveProductButton = findViewById(R.id.saveProductButton)

        val extras = intent.extras
        product = extras!!.get("product") as Product?

        if (product != null) {
            abstractProduct = DBStorageController(this).findAbstractProductById(DBStorageController(this).readableDatabase, product!!.abstractProductId)
            abstractProductView.abstractProduct = abstractProduct!!
            expiryDateRadioButton.isSelected = true
            shelfLifeRadioButton.isSelected = false

            expiryDateOverShelfLife = true
            updatingExistentProduct = true
            update()
        } else {
            product = Product(0, 0, 0, 0, 0)
            abstractProduct = AbstractProduct(0, "", "", 0.0, "", 0, 0)
        }

        scanButton.setOnClickListener {
            val scanner = GmsBarcodeScanning.getClient(this)
            scanner.startScan()
                .addOnSuccessListener { bc ->
                    abstractProduct = DBStorageController(this).findAbstractProductByBarcode(DBStorageController(this).readableDatabase, bc.rawValue.toString())
                    product!!.abstractProductId = abstractProduct!!.id

                    displayAbstractProduct(abstractProduct!!)
                }
                .addOnFailureListener {
                    Toast.makeText(this, "Cannot scan barcode", Toast.LENGTH_SHORT).show()
                }
        }

        expiryDateRadioButton.setOnClickListener {
            expiryDateOverShelfLife = true
            update()
        }

        shelfLifeRadioButton.setOnClickListener {
            expiryDateOverShelfLife = false
            update()
        }

        dateOfProductionSelectButton.setOnClickListener {
            val c = Calendar.getInstance()
            val year = c.get(Calendar.YEAR)
            val month = c.get(Calendar.MONTH)
            val day = c.get(Calendar.DAY_OF_MONTH)

            val dpd = DatePickerDialog(this, { _, y, m, d ->
                product!!.dateOfProduction = SimpleDateFormat("dd.MM.yyyy").parse("$d.${m+1}.$y")!!.time / 1000
                update()
            }, year, month, day)

            dpd.show()
        }

        expiryDateSelectButton.setOnClickListener {
            val c = Calendar.getInstance()
            val year = c.get(Calendar.YEAR)
            val month = c.get(Calendar.MONTH)
            val day = c.get(Calendar.DAY_OF_MONTH)

            val dpd = DatePickerDialog(this, { _, y, m, d ->
                product!!.dateOfExpiry = SimpleDateFormat("dd.MM.yyyy").parse("$d.${m+1}.$y")!!.time / 1000
                update()
            }, year, month, day)

            dpd.show()
        }

        amountTextEdit.addTextChangedListener {
            val text = amountTextEdit.text.toString()
            if (text == "") return@addTextChangedListener
            product!!.amount = text.toInt()
        }

        saveProductButton.setOnClickListener {
            if (expiryDateOverShelfLife == null) {
                Toast.makeText(this, "Please, choose and fill in shelf life or expiry date.", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }
            if (product!!.dateOfProduction == 0.toLong()) {
                Toast.makeText(this, "Please, choose date of production.", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            if (!expiryDateOverShelfLife!!) {
                if (shelfLifeTextEdit.text.toString() != "") {
                    evaluateDateOfExpiry(shelfLifeTextEdit.text.toString().toInt())
                }
            } else {
                if (product!!.dateOfExpiry == 0.toLong()) {
                    Toast.makeText(this, "Please, choose date of expiry.", Toast.LENGTH_SHORT).show()
                    return@setOnClickListener
                }
            }

            if (product!!.amount == 0) {
                Toast.makeText(this, "Please, specify an amount of product.", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            if (updatingExistentProduct) {
                DBStorageController(this).updateProduct(DBStorageController(this).writableDatabase, product!!)
            } else {
                DBStorageController(this).insertNewProduct(DBStorageController(this).writableDatabase, product!!)
            }

            finish()
        }
    }

    private fun update () {
        if (expiryDateOverShelfLife == true) {
            expiryDateTextView.visibility = View.VISIBLE
            expiryDateSelectButton.visibility = View.VISIBLE

            shelfLifeTextEdit.visibility = View.INVISIBLE
            shelfLifeTextView.visibility = View.INVISIBLE
        } else if (expiryDateOverShelfLife == false){
            expiryDateTextView.visibility = View.INVISIBLE
            expiryDateSelectButton.visibility = View.INVISIBLE

            shelfLifeTextEdit.visibility = View.VISIBLE
            shelfLifeTextView.visibility = View.VISIBLE
        }
        val dateOfProductionParsed = SimpleDateFormat("dd.MM.yyyy").format(Date(product!!.dateOfProduction * 1000))
        findViewById<TextView>(R.id.dateOfProductionTextView).text = "Date of production: $dateOfProductionParsed"

        val expiryDateParsed = SimpleDateFormat("dd.MM.yyyy").format(Date(product!!.dateOfExpiry * 1000))
        expiryDateTextView.text = "Expiry date: $expiryDateParsed"

        if (amountTextEdit.text.toString() == "") {
            amountTextEdit.setText(product!!.amount.toString())
        } else {
            product!!.amount = amountTextEdit.text.toString().toInt()
        }

        abstractProductView.update()
    }

    private fun evaluateDateOfExpiry(shelfLifeMonths: Int) {
        if (product!!.dateOfProduction == 0.toLong() ) {
            return
        }

        val c = Calendar.getInstance()
        c.timeInMillis = product!!.dateOfProduction * 1000

        c.add(Calendar.MONTH, shelfLifeMonths)
        product!!.dateOfExpiry = c.timeInMillis / 1000
    }

    private fun displayAbstractProduct(abstractProduct: AbstractProduct) {
        abstractProductView.abstractProduct = abstractProduct
        abstractProductView.update()
    }
}