package me.zobrist.tichucounter

import android.app.AlertDialog
import android.content.Intent
import android.os.Bundle
import android.text.InputType
import android.view.Menu
import android.view.MenuItem
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.ScrollView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
import androidx.core.widget.doOnTextChanged
import com.google.gson.Gson
import me.zobrist.tichucounter.databinding.ActivityMainBinding
import java.util.*

class MainActivity : AppCompatActivity()
{

    private var updateOnChange: Boolean=true

    private lateinit var history: History
    private var currentRound=Round()
    private var systemLocale=Locale.getDefault()


    private lateinit var binding: ActivityMainBinding


    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        binding=ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        setSupportActionBar(binding.toolbar)

        binding.contentMain.inputTeamA.setRawInputType(InputType.TYPE_NULL)
        binding.contentMain.inputTeamB.setRawInputType(InputType.TYPE_NULL)
        binding.contentMain.inputTeamA.requestFocus()
        disableSubmitButton()
        updateTheme(this.getSharedPreferences("Settings" , MODE_PRIVATE).getInt("Theme" , 2))
        keepScreenOn(
            this.getSharedPreferences("Settings" , MODE_PRIVATE)
                .getBoolean("Screen_On" , false)
        )


        val json=this.getSharedPreferences("Settings" , MODE_PRIVATE)
            .getString("history" , "{\"scores\":[]}")
        history=Gson().fromJson(json , History::class.java)
        binding.contentMain.nameTeamA.setText(
            this.getSharedPreferences("Settings" , MODE_PRIVATE).getString("nameTeamA" , "TeamA")
        )
        binding.contentMain.nameTeamB.setText(
            this.getSharedPreferences("Settings" , MODE_PRIVATE).getString("nameTeamB" , "TeamB")
        )
        updateView()

        this.setListenes()


    }

    private fun setListenes()
    {
        binding.contentMain.inputTeamA.setOnFocusChangeListener { _ , b ->
            if (b)
            {
                hideKeyboard()
            }
        }

        binding.contentMain.inputTeamB.setOnFocusChangeListener { _ , b ->
            if (b)
            {
                hideKeyboard()
            }
        }

        binding.contentMain.inputTeamA.doOnTextChanged { text , _ , _ , _ ->
            if (binding.contentMain.inputTeamA.isFocused)
            {
                if (binding.contentMain.inputTeamA.text.isNotEmpty())
                {
                    if (updateOnChange)
                    {
                        currentRound=try
                        {
                            Round(text.toString().toInt() , true)

                        }
                        catch (e: java.lang.Exception)
                        {
                            Round(1 , 1)
                        }
                        binding.contentMain.inputTeamB.setText(currentRound.scoreB.toString())
                    }
                    else
                    {
                        updateOnChange=true
                    }
                }
                else
                {
                    binding.contentMain.inputTeamA.text.clear()
                    binding.contentMain.inputTeamB.text.clear()
                }
            }

            if (currentRound.isValidRound() && binding.contentMain.inputTeamA.text.isNotEmpty() && binding.contentMain.inputTeamB.text.isNotEmpty())
            {
                enableSubmitButton()
            }
            else
            {
                disableSubmitButton()
            }
        }

        binding.contentMain.inputTeamB.doOnTextChanged { text , _ , _ , _ ->
            if (binding.contentMain.inputTeamB.isFocused)
            {
                if (binding.contentMain.inputTeamB.text.isNotEmpty())
                {
                    if (updateOnChange)
                    {
                        currentRound=try
                        {
                            Round(text.toString().toInt() , false)

                        }
                        catch (e: java.lang.Exception)
                        {
                            Round(1 , 1)
                        }
                        binding.contentMain.inputTeamA.setText(currentRound.scoreA.toString())

                    }
                    else
                    {
                        updateOnChange=true
                    }

                }
                else
                {
                    binding.contentMain.inputTeamA.text.clear()
                    binding.contentMain.inputTeamB.text.clear()
                }
            }

            if (currentRound.isValidRound() && binding.contentMain.inputTeamA.text.isNotEmpty() && binding.contentMain.inputTeamB.text.isNotEmpty())
            {
                enableSubmitButton()
            }
            else
            {
                disableSubmitButton()
            }
        }

        binding.contentMain.buttonAdd100.setOnClickListener {
            giveFocusToAIfNone()

            if (binding.contentMain.inputTeamA.isFocused)
            {

                currentRound.scoreA=try
                {
                    binding.contentMain.inputTeamA.text.toString().toInt() + 100
                }
                catch (e: Exception)
                {
                    currentRound.scoreB=0
                    binding.contentMain.inputTeamB.setText(currentRound.scoreB.toString())
                    100
                }
                updateOnChange=false
                binding.contentMain.inputTeamA.setText(currentRound.scoreA.toString())
            }

            if (binding.contentMain.inputTeamB.isFocused)
            {
                currentRound.scoreB=try
                {
                    binding.contentMain.inputTeamB.text.toString().toInt() + 100
                }
                catch (e: Exception)
                {
                    currentRound.scoreA=0
                    binding.contentMain.inputTeamA.setText(currentRound.scoreA.toString())
                    100

                }
                updateOnChange=false
                binding.contentMain.inputTeamB.setText(currentRound.scoreB.toString())

            }
        }

        binding.contentMain.buttonSub100.setOnClickListener {
            giveFocusToAIfNone()

            if (binding.contentMain.inputTeamA.isFocused)
            {
                currentRound.scoreA=try
                {
                    binding.contentMain.inputTeamA.text.toString().toInt() - 100
                }
                catch (e: Exception)
                {
                    currentRound.scoreB=0
                    binding.contentMain.inputTeamB.setText(currentRound.scoreB.toString())
                    -100
                }
                updateOnChange=false
                binding.contentMain.inputTeamA.setText(currentRound.scoreA.toString())
            }

            if (binding.contentMain.inputTeamB.isFocused)
            {
                currentRound.scoreB=try
                {
                    binding.contentMain.inputTeamB.text.toString().toInt() - 100
                }
                catch (e: Exception)
                {
                    currentRound.scoreA=0
                    binding.contentMain.inputTeamA.setText(currentRound.scoreA.toString())
                    -100
                }
                updateOnChange=false
                binding.contentMain.inputTeamB.setText(currentRound.scoreB.toString())
            }
        }

        binding.contentMain.button0.setOnClickListener {
            giveFocusToAIfNone()
            appendToFocusedInput('0')
        }

        binding.contentMain.button1.setOnClickListener {
            giveFocusToAIfNone()
            appendToFocusedInput('1')
        }

        binding.contentMain.button2.setOnClickListener {
            giveFocusToAIfNone()
            appendToFocusedInput('2')
        }

        binding.contentMain.button3.setOnClickListener {
            giveFocusToAIfNone()
            appendToFocusedInput('3')
        }

        binding.contentMain.button4.setOnClickListener {
            giveFocusToAIfNone()
            appendToFocusedInput('4')
        }

        binding.contentMain.button5.setOnClickListener {
            giveFocusToAIfNone()
            appendToFocusedInput('5')
        }

        binding.contentMain.button6.setOnClickListener {
            giveFocusToAIfNone()
            appendToFocusedInput('6')
        }

        binding.contentMain.button7.setOnClickListener {
            giveFocusToAIfNone()
            appendToFocusedInput('7')
        }

        binding.contentMain.button8.setOnClickListener {
            giveFocusToAIfNone()
            appendToFocusedInput('8')
        }

        binding.contentMain.button9.setOnClickListener {
            giveFocusToAIfNone()
            appendToFocusedInput('9')
        }

        binding.contentMain.buttonInv.setOnClickListener {
            val tempInt: Int

            giveFocusToAIfNone()

            if (binding.contentMain.inputTeamA.isFocused)
            {
                if (binding.contentMain.inputTeamA.text.toString().equals("-"))
                {
                    binding.contentMain.inputTeamA.text.clear()
                }
                else if (binding.contentMain.inputTeamA.text.isNotEmpty())
                {
                    tempInt=binding.contentMain.inputTeamA.text.toString().toInt() * -1
                    binding.contentMain.inputTeamA.setText(tempInt.toString())
                }
                else
                {
                    updateOnChange=false
                    appendToFocusedInput('-')
                    currentRound=Round(1 , 1)
                }


            }
            else if (binding.contentMain.inputTeamB.isFocused)
            {
                if (binding.contentMain.inputTeamB.text.toString().equals("-"))
                {
                    binding.contentMain.inputTeamB.text.clear()
                }
                else if (binding.contentMain.inputTeamB.text.isNotEmpty())
                {
                    tempInt=binding.contentMain.inputTeamB.text.toString().toInt() * -1
                    binding.contentMain.inputTeamB.setText(tempInt.toString())
                }
                else
                {
                    updateOnChange=false
                    appendToFocusedInput('-')
                    currentRound=Round(1 , 1)
                }
            }
        }

        binding.contentMain.buttonBack.setOnClickListener {
            giveFocusToAIfNone()

            if (binding.contentMain.inputTeamA.isFocused)
            {
                if (binding.contentMain.inputTeamA.text.isNotEmpty())
                {
                    val string=binding.contentMain.inputTeamA.text.toString()
                    binding.contentMain.inputTeamA.setText(string.substring(0 , string.length - 1))
                }

            }
            else if (binding.contentMain.inputTeamB.isFocused)
            {
                if (binding.contentMain.inputTeamB.text.isNotEmpty())
                {
                    val string=binding.contentMain.inputTeamB.text.toString()
                    binding.contentMain.inputTeamB.setText(string.substring(0 , string.length - 1))
                }
            }
        }

        binding.contentMain.submit.setOnClickListener {
            giveFocusToAIfNone()

            if (binding.contentMain.inputTeamA.text.isNotEmpty() && binding.contentMain.inputTeamB.text.isNotEmpty())
            {

                history.logRound(
                    Round(
                        binding.contentMain.inputTeamA.text.toString().toInt() ,
                        binding.contentMain.inputTeamB.text.toString().toInt()
                    )
                )

                updateView()

                binding.contentMain.inputTeamA.text.clear()
                binding.contentMain.inputTeamB.text.clear()
                disableSubmitButton()

                binding.contentMain.scrollViewHistory.fullScroll(ScrollView.FOCUS_DOWN)
            }
        }
    }

    override fun onSaveInstanceState(outState: Bundle)
    {
        super.onSaveInstanceState(outState)

        val prefs=this.getSharedPreferences("Settings" , MODE_PRIVATE).edit()
        prefs.putString("history" , Gson().toJson(history))
        prefs.putString("nameTeamA" , binding.contentMain.nameTeamA.text.toString())
        prefs.putString("nameTeamB" , binding.contentMain.nameTeamB.text.toString())
        prefs.apply()

    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.menu_main , menu)

        menu.findItem(R.id.action_screenOn).isChecked=
            this.getSharedPreferences("Settings" , MODE_PRIVATE)
                .getBoolean("Screen_On" , false)
        return true
    }


    override fun onOptionsItemSelected(item: MenuItem): Boolean
    {
        return when (item.itemId)
        {
            R.id.action_clear ->
            {
                val builder=AlertDialog.Builder(this)
                builder.setMessage(getString(R.string.confirmClear))
                    .setTitle(R.string.clear)
                    .setCancelable(false)
                    .setPositiveButton(getString(R.string.yes)) { dialog , _ ->
                        dialog.dismiss()
                        clearAll()
                    }
                    .setNegativeButton(getString(R.string.no)) { dialog , _ ->
                        dialog.cancel()
                    }

                builder.create().show()
                true
            }
            R.id.action_undo ->
            {
                undoLastRound()
                true
            }
            R.id.action_theme ->
            {
                chooseThemeDialog()
                true
            }
            R.id.action_language ->
            {
                chooseLanguageDialog()
                true
            }
            R.id.action_screenOn ->
            {
                item.isChecked=!item.isChecked
                keepScreenOn(item.isChecked)
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }

    private fun hideKeyboard()
    {
        val imm: InputMethodManager=
            getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(currentFocus!!.windowToken , 0)
    }

    private fun giveFocusToAIfNone()
    {
        if (!binding.contentMain.inputTeamA.isFocused && !binding.contentMain.inputTeamB.isFocused)
        {
            binding.contentMain.inputTeamA.requestFocus()
        }
    }

    private fun undoLastRound()
    {
        history.revertLastRound()
        updateView()
    }

    private fun updateView()
    {
        binding.contentMain.scoreA.text=history.getScoreA().toString()
        binding.contentMain.scoreB.text=history.getScoreB().toString()

        binding.contentMain.historyA.text=history.getHistoryA()
        binding.contentMain.historyB.text=history.getHistoryB()
    }

    private fun clearAll()
    {
        binding.contentMain.historyA.text=""
        binding.contentMain.historyB.text=""
        binding.contentMain.inputTeamA.text.clear()
        binding.contentMain.inputTeamB.text.clear()
        binding.contentMain.scoreA.text="0"
        binding.contentMain.scoreB.text="0"

        history.clearAll()
    }

    private fun appendToFocusedInput(toAppend: Char)
    {
        if (binding.contentMain.inputTeamA.isFocused)
        {
            binding.contentMain.inputTeamA.text.append(toAppend)
        }
        else if (binding.contentMain.inputTeamB.isFocused)
        {
            binding.contentMain.inputTeamB.text.append(toAppend)
        }
    }

    private fun enableSubmitButton()
    {
        binding.contentMain.submit.imageAlpha=255 // 0 being transparent and 255 being opaque
        binding.contentMain.submit.isEnabled=true
    }

    private fun disableSubmitButton()
    {
        binding.contentMain.submit.imageAlpha=60 // 0 being transparent and 255 being opaque
        binding.contentMain.submit.isEnabled=false
    }

    private fun chooseThemeDialog()
    {

        val builder=AlertDialog.Builder(this)
        builder.setTitle(getString(R.string.choose_theme_text))
        val styles=arrayOf(
            getString(R.string.light) ,
            getString(R.string.dark) ,
            getString(R.string.android_default_text)
        )

        val checkedItem=
            this.getSharedPreferences("Settings" , MODE_PRIVATE).getInt("Theme" , 2)

        val prefs=this.getSharedPreferences("Settings" , MODE_PRIVATE).edit()


        builder.setSingleChoiceItems(styles , checkedItem) { dialog , which ->

            prefs.putInt("Theme" , which)
            prefs.apply()

            updateTheme(which)

            dialog.dismiss()
        }

        val dialog=builder.create()
        dialog.show()
    }

    private fun chooseLanguageDialog()
    {

        val builder=AlertDialog.Builder(this)
        builder.setTitle(getString(R.string.choose_language_text))

        val languages_map=mapOf(
            getString(R.string.english) to "en" ,
            getString(R.string.german) to "de"
        )

        val languages_display_keys=languages_map.keys.toTypedArray()
        val languages_display_values=languages_map.values.toTypedArray()

        val checkedItem=AppCompatDelegate.getApplicationLocales()[0].toString()
        var checkedItemIndex=languages_display_values.indexOf(checkedItem)

        if (checkedItemIndex == -1)
        {
            checkedItemIndex=0
        }

        builder.setSingleChoiceItems(languages_display_keys , checkedItemIndex) { dialog , which ->

            val newLocale=
                LocaleListCompat.forLanguageTags(languages_map[languages_display_keys[which]])

            AppCompatDelegate.setApplicationLocales(newLocale)

            startActivity(Intent(this , MainActivity::class.java))
            finish()

            dialog.dismiss()
        }

        val dialog=builder.create()
        dialog.show()
    }

    private fun updateTheme(which: Int)
    {
        when (which)
        {
            0 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
            1 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
            2 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
        }
        delegate.applyDayNight()
    }

    private fun keepScreenOn(keepOn: Boolean)
    {
        if (keepOn)
        {
            window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        }
        else
        {
            window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        }

        val prefs=this.getSharedPreferences("Settings" , MODE_PRIVATE).edit()
        prefs.putBoolean("Screen_On" , keepOn)
        prefs.apply()
    }
}