package com.rugvedsarika.toolbox.calculators

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.rugvedsarika.toolbox.R
import com.rugvedsarika.toolbox.databinding.FragmentStandardCalculatorBinding
import net.objecthunter.exp4j.ExpressionBuilder
import java.text.DecimalFormat

class StandardCalculatorFragment : Fragment() {

    private var _binding: FragmentStandardCalculatorBinding? = null
    private val binding get() = _binding!!

    private var lastNumeric: Boolean = false
    private var stateError: Boolean = false
    private var lastDot: Boolean = false

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentStandardCalculatorBinding.inflate(inflater, container, false)
        return binding.root
    }

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

        binding.toolbar.setNavigationOnClickListener {
            findNavController().navigateUp()
        }

        binding.toolbar.setOnMenuItemClickListener { menuItem ->
            when (menuItem.itemId) {
                R.id.action_history -> {
                    findNavController().navigate(
                        R.id.historyFragment,
                        bundleOf("toolId" to "standard_calculator")
                    )
                    true
                }
                else -> false
            }
        }

        setClickListeners()
    }

    private fun setClickListeners() {
        val digitButtons = listOf(
            binding.gridButtons.getChildAt(4), // 7
            binding.gridButtons.getChildAt(5), // 8
            binding.gridButtons.getChildAt(6), // 9
            binding.gridButtons.getChildAt(8), // 4
            binding.gridButtons.getChildAt(9), // 5
            binding.gridButtons.getChildAt(10), // 6
            binding.gridButtons.getChildAt(12), // 1
            binding.gridButtons.getChildAt(13), // 2
            binding.gridButtons.getChildAt(14), // 3
            binding.gridButtons.getChildAt(16)  // 0
        )

        digitButtons.forEach { button ->
            (button as Button).setOnClickListener { onDigit(button.text.toString()) }
        }

        binding.btnAc.setOnClickListener { onClear() }
        binding.gridButtons.getChildAt(1).setOnClickListener { onOperator("(") } 
        binding.gridButtons.getChildAt(2).setOnClickListener { onOperator("%") }
        binding.gridButtons.getChildAt(3).setOnClickListener { onOperator("/") }
        binding.gridButtons.getChildAt(7).setOnClickListener { onOperator("*") }
        binding.gridButtons.getChildAt(11).setOnClickListener { onOperator("-") }
        binding.gridButtons.getChildAt(15).setOnClickListener { onOperator("+") }
        binding.gridButtons.getChildAt(17).setOnClickListener { onDecimal() }
        binding.btnDelete.setOnClickListener { onDelete() }
        binding.btnEquals.setOnClickListener { onEqual() }
    }

    private fun onDigit(digit: String) {
        if (stateError) {
            binding.tvExpression.text = digit
            stateError = false
        } else {
            binding.tvExpression.append(digit)
        }
        lastNumeric = true
        onCalculate()
    }

    private fun onDecimal() {
        if (lastNumeric && !stateError && !lastDot) {
            binding.tvExpression.append(".")
            lastNumeric = false
            lastDot = true
        }
    }

    private fun onOperator(operator: String) {
        if (lastNumeric && !stateError) {
            binding.tvExpression.append(operator)
            lastNumeric = false
            lastDot = false
        }
    }

    private fun onClear() {
        binding.tvExpression.text = ""
        binding.tvResult.text = ""
        lastNumeric = false
        stateError = false
        lastDot = false
    }

    private fun onDelete() {
        val text = binding.tvExpression.text.toString()
        if (text.isNotEmpty()) {
            binding.tvExpression.text = text.dropLast(1)
            val newText = binding.tvExpression.text.toString()
            if (newText.isNotEmpty()) {
                lastNumeric = newText.last().isDigit()
                lastDot = newText.contains(".") // Simplified
                onCalculate()
            } else {
                onClear()
            }
        }
    }

    private fun onEqual() {
        if (lastNumeric && !stateError) {
            val text = binding.tvExpression.text.toString()
            try {
                val expression = ExpressionBuilder(text).build()
                val result = expression.evaluate()
                binding.tvResult.text = formatResult(result)
                binding.tvExpression.text = binding.tvResult.text
                lastDot = binding.tvExpression.text.contains(".")
            } catch (ex: Exception) {
                binding.tvResult.text = "Error"
                stateError = true
                lastNumeric = false
            }
        }
    }

    private fun onCalculate() {
        if (lastNumeric && !stateError) {
            val text = binding.tvExpression.text.toString()
            try {
                val expression = ExpressionBuilder(text).build()
                val result = expression.evaluate()
                binding.tvResult.text = formatResult(result)
            } catch (ex: Exception) {
                // Keep the last result or show nothing
            }
        }
    }

    private fun formatResult(result: Double): String {
        return if (result == result.toLong().toDouble()) {
            result.toLong().toString()
        } else {
            DecimalFormat("#.#######").format(result)
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}
