package com.rugvedsarika.cashcounter

import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.speech.tts.TextToSpeech
import android.widget.Button
import android.widget.EditText
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.text.NumberFormat
import java.util.Locale

class MainActivity : AppCompatActivity(), TextToSpeech.OnInitListener {

    private val notes = mutableListOf<CurrencyNote>()
    
    // New UI Elements
    private lateinit var tvTotalNotes: TextView
    private lateinit var tvCashTotal: TextView
    private lateinit var tvFinalTotal: TextView
    private lateinit var tvWords: TextView
    private lateinit var etOnlineAmt: EditText
    private lateinit var etCreditAmt: EditText
    private lateinit var etDebitAmt: EditText
    private lateinit var btnSpeak: ImageButton
    private lateinit var tvDate: TextView
    
    private var tts: TextToSpeech? = null
    private var languageCode = "en"
    
    private val noteViews = mutableListOf<View>()

    private val currencyFormat = NumberFormat.getCurrencyInstance(Locale.forLanguageTag("en-IN")).apply {
        maximumFractionDigits = 0
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Initialize Data (2000 is removed as per typical usage, can add if needed)
        notes.clear()
        notes.add(CurrencyNote(500, 0, R.drawable.img_500))
        notes.add(CurrencyNote(200, 0, R.drawable.img_200))
        notes.add(CurrencyNote(100, 0, R.drawable.img_100))
        notes.add(CurrencyNote(50, 0, R.drawable.img_50))
        notes.add(CurrencyNote(20, 0, R.drawable.img_20))
        notes.add(CurrencyNote(10, 0, R.drawable.img_10))

        // Initialize Views
        val container = findViewById<LinearLayout>(R.id.notesContainer)
        tvTotalNotes = findViewById(R.id.tvTotalNotes)
        tvCashTotal = findViewById(R.id.tvCashTotal)
        tvFinalTotal = findViewById(R.id.tvFinalTotal)
        tvWords = findViewById(R.id.tvWords)
        etOnlineAmt = findViewById(R.id.etOnlineAmt)
        etCreditAmt = findViewById(R.id.etCreditAmt)
        etDebitAmt = findViewById(R.id.etDebitAmt)
        btnSpeak = findViewById(R.id.btnSpeak)
        tvDate = findViewById(R.id.tvDate)

        // Set Current Date
        val calendar = java.util.Calendar.getInstance()
        val sdf = java.text.SimpleDateFormat("dd-MM-yyyy", Locale.getDefault())
        tvDate.text = sdf.format(calendar.time)

        tvDate.setOnClickListener {
            val year = calendar.get(java.util.Calendar.YEAR)
            val month = calendar.get(java.util.Calendar.MONTH)
            val day = calendar.get(java.util.Calendar.DAY_OF_MONTH)

            val datePickerDialog = android.app.DatePickerDialog(this, { _, selectedYear, selectedMonth, selectedDay ->
                calendar.set(selectedYear, selectedMonth, selectedDay)
                tvDate.text = sdf.format(calendar.time)
            }, year, month, day)
            datePickerDialog.show()
        }

        // Initialize TTS
        tts = TextToSpeech(this, this)

        val btnReset = findViewById<Button>(R.id.btnReset)
        val btnSave = findViewById<Button>(R.id.btnSave)
        val btnShare = findViewById<Button>(R.id.btnShare)
        val btnMenu = findViewById<android.widget.ImageButton>(R.id.btnMenu)

        // Setup List
        val inflater = LayoutInflater.from(this)
        // Check if img_5 exists (it was not in the ls list, so I will filter out 5 for now to avoid crash or use placeholder)
        // Actually I'll just stick to notes I KNOW exist: 500, 200, 100, 50, 20, 10.
        // If user wants 5, I need that resource. Screenshot has 5. I will use img_50 as placeholder for now or remove if it crashes.
        // Wait, list_dir showed img_10, 100, 20, 200, 50, 500. No 5. I will remove 5 from list.
        // notes.removeIf { it.value == 5 }


        for (note in notes) {
            val view = inflater.inflate(R.layout.item_note, container, false)
            setupNoteRow(view, note)
            container.addView(view)
            noteViews.add(view)
        }
        
        // Listeners for manual inputs
        val inputWatcher = object : TextWatcher {
            override fun afterTextChanged(s: Editable?) = calculateAll()
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
        }
        etOnlineAmt.addTextChangedListener(inputWatcher)
        etCreditAmt.addTextChangedListener(inputWatcher)
        etDebitAmt.addTextChangedListener(inputWatcher)

        calculateAll()

        // Click Listeners
        btnMenu.setOnClickListener { showMenu(it) }
        btnSave.setOnClickListener { saveToHistory() }
        btnShare.setOnClickListener { shareData() }
        
        btnReset.setOnClickListener {
            val prefs = getSharedPreferences("app_prefs", MODE_PRIVATE)
            if (prefs.getBoolean("haptics_enabled", true)) {
                it.performHapticFeedback(android.view.HapticFeedbackConstants.CONTEXT_CLICK)
            }
            resetAll()
        }

        btnSpeak.setOnClickListener {
            val textToSpeak = tvWords.text.toString()
            if (textToSpeak.isNotEmpty()) {
                speakText(textToSpeak)
            }
        }
    }

    override fun onResume() {
        super.onResume()
        val prefs = getSharedPreferences("app_prefs", MODE_PRIVATE)
        languageCode = prefs.getString("language_code", "en") ?: "en"
        calculateAll()
        updateTTSLocale()
    }

    private fun updateTTSLocale() {
        val locale = when (languageCode) {
            "hi" -> Locale.forLanguageTag("hi-IN")
            "mr" -> Locale.forLanguageTag("mr-IN")
            else -> Locale.forLanguageTag("en-IN")
        }
        tts?.language = locale
    }

    override fun onInit(status: Int) {
        if (status == TextToSpeech.SUCCESS) {
            val result = tts?.setLanguage(Locale.forLanguageTag("en-IN"))
            if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                Toast.makeText(this, "Language not supported", Toast.LENGTH_SHORT).show()
            }
        } else {
            Toast.makeText(this, "TTS Initialization failed", Toast.LENGTH_SHORT).show()
        }
    }

    private fun speakText(text: String) {
        tts?.speak(text, TextToSpeech.QUEUE_FLUSH, null, null)
    }

    override fun onDestroy() {
        if (tts != null) {
            tts?.stop()
            tts?.shutdown()
        }
        super.onDestroy()
    }

    private fun setupNoteRow(view: View, note: CurrencyNote) {
        val imgNote = view.findViewById<ImageView>(R.id.imgNote)
        val etQuantity = view.findViewById<EditText>(R.id.etQuantity)
        val tvSubtotal = view.findViewById<TextView>(R.id.tvSubtotal)
        val tvDenomination = view.findViewById<TextView>(R.id.tvDenomination)

        imgNote.setImageResource(note.imageRes)
        tvDenomination.text = note.value.toString()
        
        tvSubtotal.text = "0"

        etQuantity.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) {}
            override fun afterTextChanged(s: Editable?) {
                val qtyString = s.toString()
                val qty = if (qtyString.isEmpty()) 0 else qtyString.toInt()
                
                note.quantity = qty
                val subtotal = note.value * note.quantity
                tvSubtotal.text = subtotal.toString() // Just number for row total as per screenshot
                
                calculateAll()
            }
        })
    }

    private fun calculateAll() {
        var cashTotal = 0
        var totalNotes = 0
        
        for (note in notes) {
            cashTotal += (note.value * note.quantity)
            totalNotes += note.quantity
        }
        
        val onlineAmt = etOnlineAmt.text.toString().toIntOrNull() ?: 0
        val creditAmt = etCreditAmt.text.toString().toIntOrNull() ?: 0
        val debitAmt = etDebitAmt.text.toString().toIntOrNull() ?: 0
        
        val finalTotal = cashTotal + onlineAmt + creditAmt - debitAmt
        
        // Update UI
        tvTotalNotes.text = totalNotes.toString()
        tvCashTotal.text = formatCurrency(cashTotal)
        tvFinalTotal.text = formatCurrency(finalTotal)
        tvWords.text = when (languageCode) {
            "hi" -> convertToHindiCurrency(finalTotal) + " रुपये"
            "mr" -> convertToMarathiCurrency(finalTotal) + " रुपये"
            else -> convertToIndianCurrency(finalTotal) + " Rupees"
        }
    }

    private fun resetAll() {
        for (view in noteViews) {
            val etQuantity = view.findViewById<EditText>(R.id.etQuantity)
            etQuantity.text.clear() 
        }
        etOnlineAmt.text.clear()
        etCreditAmt.text.clear()
        etDebitAmt.text.clear()
        calculateAll()
    }

    private fun formatCurrency(amount: Int): String {
        return currencyFormat.format(amount)
    }
    
    private fun convertToIndianCurrency(n: Int): String {
        if (n == 0) return "Zero"
        return convert(n.toLong())
    }
    
    private fun convert(n: Long): String {
        val units = arrayOf("", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen")
        val tens = arrayOf("", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety")

        if (n < 0) return "Minus " + convert(-n)
        if (n < 20) return units[n.toInt()]
        if (n < 100) return tens[n.toInt() / 10] + (if (n % 10 != 0L) " " + units[(n % 10).toInt()] else "")
        if (n < 1000) return units[(n / 100).toInt()] + " Hundred" + (if (n % 100 != 0L) " " + convert(n % 100) else "")
        if (n < 100000) return convert(n / 1000) + " Thousand" + (if (n % 1000 != 0L) " " + convert(n % 1000) else "")
        if (n < 10000000) return convert(n / 100000) + " Lakh" + (if (n % 100000 != 0L) " " + convert(n % 100000) else "")
        return convert(n / 10000000) + " Crore" + (if (n % 10000000 != 0L) " " + convert(n % 10000000) else "")
    }

    private fun convertToHindiCurrency(n: Int): String {
        if (n == 0) return "शून्य"
        return convertHindi(n.toLong())
    }

    private fun convertHindi(n: Long): String {
        val units = arrayOf("", "एक", "दो", "तीन", "चार", "पाँच", "छह", "सात", "आठ", "नौ", "दस", "ग्यारह", "बारह", "तेरह", "चौदह", "पंद्रह", "सोलह", "सत्रह", "अठारह", "उन्नीस")
        val tens = arrayOf("", "", "बीस", "तीस", "चालीस", "पचास", "साठ", "सत्तर", "अस्सी", "नब्बे")

        if (n < 0) return "ऋण " + convertHindi(-n)
        if (n < 20) return units[n.toInt()]
        if (n < 100) return tens[n.toInt() / 10] + (if (n % 10 != 0L) " " + units[(n % 10).toInt()] else "")
        if (n < 1000) return units[(n / 100).toInt()] + " सौ" + (if (n % 100 != 0L) " " + convertHindi(n % 100) else "")
        if (n < 100000) return convertHindi(n / 1000) + " हजार" + (if (n % 1000 != 0L) " " + convertHindi(n % 1000) else "")
        if (n < 10000000) return convertHindi(n / 100000) + " लाख" + (if (n % 100000 != 0L) " " + convertHindi(n % 100000) else "")
        return convertHindi(n / 10000000) + " करोड़" + (if (n % 10000000 != 0L) " " + convertHindi(n % 10000000) else "")
    }

    private fun convertToMarathiCurrency(n: Int): String {
        if (n == 0) return "शून्य"
        return convertMarathi(n.toLong())
    }

    private fun convertMarathi(n: Long): String {
        val units = arrayOf("", "एक", "दोन", "तीन", "चार", "पाच", "सहा", "सात", "आठ", "नऊ", "दहा", "अकरा", "बारा", "तेरा", "चौदा", "पंधरा", "सोळा", "सतरा", "अठरा", "एकोणीस")
        val tens = arrayOf("", "", "वीस", "तीस", "चाळीस", "पन्नास", "साठ", "सत्तर", "ऐंशी", "नव्वद")

        if (n < 0) return "उणे " + convertMarathi(-n)
        if (n < 20) return units[n.toInt()]
        if (n < 100) return tens[n.toInt() / 10] + (if (n % 10 != 0L) " " + units[(n % 10).toInt()] else "")
        if (n < 1000) return units[(n / 100).toInt()] + "शे" + (if (n % 100 != 0L) " " + convertMarathi(n % 100) else "")
        if (n < 100000) return convertMarathi(n / 1000) + " हजार" + (if (n % 1000 != 0L) " " + convertMarathi(n % 1000) else "")
        if (n < 10000000) return convertMarathi(n / 100000) + " लाख" + (if (n % 100000 != 0L) " " + convertMarathi(n % 100000) else "")
        return convertMarathi(n / 10000000) + " कोटी" + (if (n % 10000000 != 0L) " " + convertMarathi(n % 10000000) else "")
    }

    private fun showMenu(anchor: View) {
        val popup = androidx.appcompat.widget.PopupMenu(this, anchor)
        popup.menu.add("History")
        popup.menu.add("Settings")
        
        popup.setOnMenuItemClickListener { item ->
            when (item.title) {
                "History" -> {
                    startActivity(android.content.Intent(this, HistoryActivity::class.java))
                    true
                }
                "Settings" -> {
                    startActivity(android.content.Intent(this, SettingsActivity::class.java))
                    true
                }
                else -> false
            }
        }
        popup.show()
    }

    private fun saveToHistory() {
        var cashTotal = 0
        for (note in notes) {
            cashTotal += (note.value * note.quantity)
        }
        val onlineAmt = etOnlineAmt.text.toString().toIntOrNull() ?: 0
        val creditAmt = etCreditAmt.text.toString().toIntOrNull() ?: 0
        val debitAmt = etDebitAmt.text.toString().toIntOrNull() ?: 0
        val finalTotal = cashTotal + onlineAmt + creditAmt - debitAmt

        if (finalTotal == 0) {
            android.widget.Toast.makeText(this, "Nothing to save!", android.widget.Toast.LENGTH_SHORT).show()
            return
        }

        val builder = androidx.appcompat.app.AlertDialog.Builder(this)
        builder.setTitle("Save Record")
        
        val input = EditText(this)
        input.hint = "Enter Remarks (Optional)"
        input.inputType = android.text.InputType.TYPE_CLASS_TEXT
        
        val container = androidx.appcompat.widget.LinearLayoutCompat(this)
        val params = androidx.appcompat.widget.LinearLayoutCompat.LayoutParams(
            androidx.appcompat.widget.LinearLayoutCompat.LayoutParams.MATCH_PARENT, 
            androidx.appcompat.widget.LinearLayoutCompat.LayoutParams.WRAP_CONTENT
        )
        params.setMargins(48, 24, 48, 24)
        input.layoutParams = params
        container.addView(input)
        
        builder.setView(container)

        builder.setPositiveButton("Save")   { _, _ ->
            val remarks = input.text.toString()
            val breakdown = notes.filter { it.quantity > 0 }
                .joinToString(", ") { "${it.value}x${it.quantity}" }

            val historyItem = com.rugvedsarika.cashcounter.data.HistoryEntity(
                timestamp = System.currentTimeMillis(),
                totalAmount = finalTotal,
                breakdown = breakdown,
                remarks = remarks
            )

            lifecycleScope.launch(kotlinx.coroutines.Dispatchers.IO) {
                com.rugvedsarika.cashcounter.data.AppDatabase.getDatabase(this@MainActivity).historyDao().insert(historyItem)
                kotlinx.coroutines.withContext(kotlinx.coroutines.Dispatchers.Main) {
                    android.widget.Toast.makeText(this@MainActivity, "Saved successfully!", android.widget.Toast.LENGTH_SHORT).show()
                }
            }
        }
        builder.setNegativeButton("Cancel", null)
        builder.show()
    }

    private fun shareData() {
        var cashTotal = 0
        for (note in notes) {
            cashTotal += (note.value * note.quantity)
        }
        val onlineAmt = etOnlineAmt.text.toString().toIntOrNull() ?: 0
        val creditAmt = etCreditAmt.text.toString().toIntOrNull() ?: 0
        val debitAmt = etDebitAmt.text.toString().toIntOrNull() ?: 0
        val finalTotal = cashTotal + onlineAmt + creditAmt - debitAmt

        if (finalTotal == 0) {
            android.widget.Toast.makeText(this, "Nothing to share!", android.widget.Toast.LENGTH_SHORT).show()
            return
        }

        val sb = StringBuilder()
        sb.append("Cash Counter Summary\n")
        sb.append("----------------\n")
        
        // Notes breakdown
        for (note in notes) {
            if (note.quantity > 0) {
                sb.append("₹${note.value} x ${note.quantity} = ₹${note.value * note.quantity}\n")
            }
        }
        if (onlineAmt > 0) sb.append("Online: ₹$onlineAmt\n")
        if (creditAmt > 0) sb.append("Credit: ₹$creditAmt\n")
        if (debitAmt > 0) sb.append("Debit: -₹$debitAmt\n")
        
        sb.append("----------------\n")
        sb.append("Total Amount: ${formatCurrency(finalTotal)}\n")
        sb.append("Generated by Cash Counter App")

        val intent = android.content.Intent(android.content.Intent.ACTION_SEND)
        intent.type = "text/plain"
        intent.putExtra(android.content.Intent.EXTRA_TEXT, sb.toString())
        startActivity(android.content.Intent.createChooser(intent, "Share via"))
    }
}
