package com.example.kasirapp

import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.Spinner
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.kasirapp.data.AppDatabase
import com.example.kasirapp.data.Product
import com.example.kasirapp.data.Transaction
import com.example.kasirapp.data.TransactionItem
import kotlinx.coroutines.launch
import java.text.NumberFormat
import java.text.SimpleDateFormat
import java.util.*

class MainActivity : AppCompatActivity() {

    // region Data Classes & Enums
    data class CartItem(val product: Product, var quantity: Int, var note: String? = null)

    enum class OrderMode { DINE_IN_INDOOR, DINE_IN_OUTDOOR, TAKEAWAY }
    // endregion

    // region State & Variables
    private var fullProductList = listOf<Product>()
    private val cart = mutableListOf<CartItem>()
    private val db by lazy { AppDatabase.getDatabase(this) }
    private lateinit var productAdapter: ProductAdapter
    private lateinit var cartAdapter: CartAdapter

    private lateinit var rvProducts: RecyclerView
    private lateinit var rvCart: RecyclerView
    private lateinit var totalText: TextView
    private lateinit var emptyCartText: TextView
    private lateinit var searchEditText: EditText

    private var customerName: String = ""
    private var tableNumber: Int = 0
    private var currentOrderMode: OrderMode = OrderMode.DINE_IN_INDOOR
    private lateinit var userRole: String
    // endregion

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        userRole = intent.getStringExtra("role") ?: "kasir"

        if (userRole == "admin") {
            startActivity(Intent(this, AdminDashboardActivity::class.java))
            finish()
            return
        }

        setContentView(R.layout.activity_main)

        initializeViews()
        setupRecyclerViews()
        setupSearch()
        
        findViewById<TextView>(R.id.subtitle_text).text = "Selamat datang, ${userRole.replaceFirstChar { it.uppercase() }}!"

        findViewById<Button>(R.id.btn_logout).setOnClickListener { logout() }
        findViewById<Button>(R.id.btn_dine_in).setOnClickListener { showSeatingChoiceDialog() }
        findViewById<Button>(R.id.btn_takeaway).setOnClickListener { 
            currentOrderMode = OrderMode.TAKEAWAY
            Toast.makeText(this, "Mode Takeaway Dipilih", Toast.LENGTH_SHORT).show() 
        }
        findViewById<Button>(R.id.btn_clear_cart).setOnClickListener { clearCart() }
        findViewById<Button>(R.id.btn_checkout).setOnClickListener { checkout() }

        loadProducts()
        updateCartDisplay()
    }

    private fun initializeViews() {
        rvProducts = findViewById(R.id.rv_products)
        rvCart = findViewById(R.id.rv_cart)
        emptyCartText = findViewById(R.id.empty_cart_text)
        totalText = findViewById(R.id.total_text)
        searchEditText = findViewById(R.id.et_search_menu)
    }

    private fun setupRecyclerViews() {
        // Products RecyclerView
        productAdapter = ProductAdapter(emptyList()) { product ->
            addToCart(product)
        }
        rvProducts.adapter = productAdapter
        rvProducts.layoutManager = GridLayoutManager(this, 2)

        // Cart RecyclerView
        cartAdapter = CartAdapter(cart, 
            onIncrease = { item -> increaseQuantity(item) },
            onDecrease = { item -> decreaseQuantity(item) },
            onRemove = { item -> removeFromCart(item) },
            onNoteClick = { item -> showNoteDialog(item) }
        )
        rvCart.adapter = cartAdapter
        rvCart.layoutManager = LinearLayoutManager(this)
    }

    override fun onResume() {
        super.onResume()
        if (userRole == "kasir") {
            loadProducts()
        }
    }

    private fun setupSearch() {
        searchEditText.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                filterProducts(s.toString())
            }

            override fun afterTextChanged(s: Editable?) {}
        })
    }

    private fun filterProducts(query: String) {
        val filteredList = if (query.isBlank()) {
            fullProductList
        } else {
            fullProductList.filter { it.name.contains(query, ignoreCase = true) }
        }
        productAdapter.updateProducts(filteredList)
    }
    
    private fun logout() {
        AlertDialog.Builder(this)
            .setTitle("Logout")
            .setMessage("Apakah Anda yakin ingin logout?")
            .setPositiveButton("Ya") { _, _ ->
                val intent = Intent(this, LoginActivity::class.java)
                intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                startActivity(intent)
                finish()
            }
            .setNegativeButton("Batal", null)
            .show()
    }

    private fun showSeatingChoiceDialog() {
        val dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_seating_choice, null)
        val dialog = AlertDialog.Builder(this).setView(dialogView).create()
        dialogView.findViewById<CardView>(R.id.card_indoor).setOnClickListener {
            currentOrderMode = OrderMode.DINE_IN_INDOOR
            Toast.makeText(this, "Area Dalam Ruangan (Indoor) Dipilih", Toast.LENGTH_SHORT).show()
            dialog.dismiss()
        }
        dialogView.findViewById<CardView>(R.id.card_outdoor).setOnClickListener {
            currentOrderMode = OrderMode.DINE_IN_OUTDOOR
            Toast.makeText(this, "Area Luar Ruangan (Outdoor) Dipilih", Toast.LENGTH_SHORT).show()
            dialog.dismiss()
        }
        dialog.show()
    }

    private fun addToCart(product: Product) {
        val existingItem = cart.find { it.product.id == product.id }
        if (product.stock <= (existingItem?.quantity ?: 0)) {
            Toast.makeText(this, "Stok tidak mencukupi", Toast.LENGTH_SHORT).show()
            return
        }
        if (existingItem != null) {
            existingItem.quantity++
        } else {
            cart.add(CartItem(product, 1))
        }
        updateCartDisplay()
    }

    private fun increaseQuantity(item: CartItem) {
        if (item.product.stock > item.quantity) {
            item.quantity++
            updateCartDisplay()
        }
    }

    private fun decreaseQuantity(item: CartItem) {
        if (item.quantity > 1) {
            item.quantity--
            updateCartDisplay()
        } else {
            removeFromCart(item)
        }
    }

    private fun removeFromCart(item: CartItem) {
        cart.remove(item)
        updateCartDisplay()
    }

    private fun clearCart() {
        AlertDialog.Builder(this)
            .setTitle("Hapus Keranjang")
            .setMessage("Yakin ingin mengosongkan keranjang?")
            .setPositiveButton("Ya") { _, _ ->
                cart.clear()
                updateCartDisplay()
            }
            .setNegativeButton("Batal", null)
            .show()
    }

    private fun updateCartDisplay() {
        cartAdapter.updateData(ArrayList(cart))
        rvCart.isVisible = cart.isNotEmpty()
        emptyCartText.isVisible = cart.isEmpty()
        updateTotal()
    }

    private fun checkout() {
        if (cart.isEmpty()) {
            Toast.makeText(this, "Keranjang masih kosong", Toast.LENGTH_SHORT).show()
            return
        }
        showCustomerInfoDialog()
    }

    private fun showCustomerInfoDialog() {
        val dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_customer_info, null)
        val nameInput = dialogView.findViewById<EditText>(R.id.inputCustomerName)
        val tableSpinner = dialogView.findViewById<Spinner>(R.id.spinnerTable)

        if (currentOrderMode == OrderMode.TAKEAWAY) {
            tableSpinner.visibility = View.GONE
        } else {
            tableSpinner.adapter = ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, (1..20).map { "Meja $it" })
        }

        AlertDialog.Builder(this).setTitle("Data Pelanggan").setView(dialogView)
            .setPositiveButton("Lanjut") { _, _ ->
                customerName = nameInput.text.toString()
                if (customerName.isBlank()) {
                    Toast.makeText(this, "Nama tidak boleh kosong", Toast.LENGTH_SHORT).show()
                    return@setPositiveButton
                }
                if (currentOrderMode != OrderMode.TAKEAWAY) {
                    tableNumber = tableSpinner.selectedItem.toString().filter { it.isDigit() }.toInt()
                }
                showPaymentMethodDialog()
            }
            .setNegativeButton("Batal", null).show()
    }

    private fun showPaymentMethodDialog() {
        val total = cart.sumOf { (it.product.price * it.quantity).toLong() }.toInt()
        val paymentMethods = arrayOf("Cash", "QRIS")
        AlertDialog.Builder(this)
            .setTitle("Pilih Metode Pembayaran")
            .setItems(paymentMethods) { _, which ->
                when (paymentMethods[which]) {
                    "Cash" -> goToReceiptPreview("Cash", total)
                    "QRIS" -> showQrisDialog(total)
                }
            }
            .setNegativeButton("Batal", null)
            .show()
    }

    private fun showQrisDialog(total: Int) {
        val dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_qris, null)
        val totalTextView = dialogView.findViewById<TextView>(R.id.qrisTotal)
        totalTextView.text = "Total: ${formatCurrency(total)}"

        val qrisDialog = AlertDialog.Builder(this)
            .setTitle("Scan QRIS untuk Pembayaran")
            .setView(dialogView)
            .setPositiveButton("Konfirmasi Pembayaran") { dialog, _ ->
                dialog.dismiss()
                Toast.makeText(this, "Pembayaran Dikonfirmasi", Toast.LENGTH_SHORT).show()
                goToReceiptPreview("QRIS", total)
            }
            .setNegativeButton("Ubah Metode") { dialog, _ ->
                dialog.dismiss()
                showPaymentMethodDialog()
            }
            .setOnCancelListener { 
                showPaymentMethodDialog() 
            }
            .create()

        qrisDialog.show()
    }

    private fun goToReceiptPreview(method: String, total: Int) {
        lifecycleScope.launch {
            processTransaction(method, total)
            loadProducts()

            val intent = Intent(this@MainActivity, ReceiptPreviewActivity::class.java).apply {
                putExtra("receipt_text", buildReceiptText(method, total))
            }
            startActivity(intent)

            cart.clear()
            updateCartDisplay()
        }
    }

    private fun showNoteDialog(item: CartItem) {
        val input = EditText(this).apply { setText(item.note) }
        AlertDialog.Builder(this).setTitle("Catatan untuk ${item.product.name}").setView(input)
            .setPositiveButton("Simpan") { _, _ -> 
                item.note = input.text.toString().ifBlank { null } 
                updateCartDisplay() 
            }
            .setNegativeButton("Batal", null).show()
    }

    private fun loadProducts() {
        lifecycleScope.launch {
            var products = db.productDao().getAllProducts()
            if (products.isEmpty()) {
                insertInitialProducts()
                products = db.productDao().getAllProducts()
            }
            fullProductList = products
            filterProducts(searchEditText.text.toString()) // Apply current filter
        }
    }

    private suspend fun insertInitialProducts() {
        val initialProducts = listOf(
            Product(name = "Nasi Goreng", price = 15000, category = "Makanan", imageResName = "nasi_goreng", stock = 10),
            Product(name = "Mie Goreng", price = 12000, category = "Makanan", imageResName = "mie_goreng", stock = 8),
            Product(name = "Ayam Bakar", price = 18000, category = "Makanan", imageResName = "ayam_bakar", stock = 5),
            Product(name = "Sate Ayam", price = 20000, category = "Makanan", imageResName = "sate_ayam", stock = 7),
            Product(name = "Es Teh Manis", price = 5000, category = "Minuman", imageResName = "es_teh", stock = 20),
            Product(name = "Es Jeruk", price = 7000, category = "Minuman", imageResName = "es_jeruk", stock = 15),
            Product(name = "Jus Alpukat", price = 12000, category = "Minuman", imageResName = "jus_alpukat", stock = 10),
            Product(name = "Kopi", price = 8000, category = "Minuman", imageResName = "kopi", stock = 12),
            Product(name = "Keripik", price = 10000, category = "Snack", imageResName = "keripik", stock = 25),
            Product(name = "Roti Bakar", price = 8000, category = "Snack", imageResName = "roti_bakar", stock = 18)
        )
        db.productDao().insertAll(initialProducts)
    }

    private suspend fun processTransaction(paymentMethod: String, total: Int) {
        val newTransaction = Transaction(
            customerName = customerName,
            tableNumber = if (currentOrderMode != OrderMode.TAKEAWAY) tableNumber else null,
            orderMode = currentOrderMode.name,
            total = total,
            paymentMethod = paymentMethod,
            timestamp = System.currentTimeMillis()
        )
        val transactionId = db.transactionDao().insertTransaction(newTransaction)

        val transactionItems = cart.map { cartItem ->
            val updatedProduct = cartItem.product.copy(stock = cartItem.product.stock - cartItem.quantity)
            db.productDao().updateProduct(updatedProduct)
            
            TransactionItem(
                transactionId = transactionId,
                productId = cartItem.product.id,
                productName = cartItem.product.name,
                quantity = cartItem.quantity,
                price = cartItem.product.price
            )
        }
        db.transactionDao().insertTransactionItems(transactionItems)
    }

    private fun buildReceiptText(method: String, total: Int): String {
        val timeStr = SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.getDefault()).format(Date())
        return buildString {
            append("Struk Pembayaran")
            append("\n--------------------\n")
            append("Nama: $customerName\n")
            if (currentOrderMode != OrderMode.TAKEAWAY) append("Meja: $tableNumber (${currentOrderMode.name.substringAfter("DINE_IN_")})\n")
            append("Metode: $method\n")
            append("Waktu: $timeStr\n--------------------\n")
            cart.forEach { append("${it.product.name} x${it.quantity} = ${formatCurrency(it.product.price * it.quantity)}\n") }
            append("--------------------\nTOTAL: ${formatCurrency(total)}\n\nTerima kasih!\n")
        }
    }

    private fun formatCurrency(amount: Int): String = NumberFormat.getCurrencyInstance(Locale("id", "ID")).format(amount.toLong())
    private fun updateTotal() { 
        val total = cart.sumOf { (it.product.price * it.quantity).toLong() }.toInt()
        totalText.text = formatCurrency(total) 
    }
}