package com.amz.genie.activities

import android.content.Intent
import android.graphics.PorterDuff
import android.os.Bundle
import android.provider.Settings
import android.view.Gravity
import android.view.View
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.amz.genie.R
import com.amz.genie.adapters.AddActionAdapter
import com.amz.genie.fragments.ArchiveFragment
import com.amz.genie.fragments.AssignedFragment
import com.amz.genie.fragments.DashboardFragment
import com.amz.genie.fragments.InboxFragment
import com.amz.genie.fragments.TODOFragment
import com.amz.genie.helpers.Preferences
import com.amz.genie.helpers.Utils.forceLogoutAndGoLogin
import com.amz.genie.models.AddActionItem
import com.amz.genie.models.Komunikasi
import com.amz.genie.services.APIMain
import com.google.android.material.snackbar.Snackbar
import com.google.gson.Gson
import com.google.gson.JsonParser
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class MainActivity : BaseActivity(), View.OnClickListener {

    private var dashboardFragment = DashboardFragment()
    private var inboxFragment = InboxFragment()
    private var todoFragment = TODOFragment()
    private var assignedFragment = AssignedFragment()
    private var archiveFragment = ArchiveFragment()

    private lateinit var llDashboard: LinearLayout
    private lateinit var ivDashboard: ImageView
    private lateinit var tvDashboard: TextView
    private lateinit var llInbox: LinearLayout
    private lateinit var ivInbox: ImageView
    private lateinit var tvInbox: TextView
    private lateinit var llTodo: LinearLayout
    private lateinit var ivTodo: ImageView
    private lateinit var tvTodo: TextView
    private lateinit var llAssigned: LinearLayout
    private lateinit var ivAssigned: ImageView
    private lateinit var tvAssigned: TextView
    private lateinit var llArchive: LinearLayout
    private lateinit var ivArchive: ImageView
    private lateinit var tvArchive: TextView
    lateinit var ibSearch: ImageButton
    lateinit var ibAdd: ImageButton
    lateinit var ibMenu: ImageButton

    private var layouts: Array<LinearLayout>? = null
    private var imageViews: Array<ImageView>? = null
    private var textViews: Array<TextView>? = null

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

        initUI(savedInstanceState)
    }

    private fun initUI(savedInstanceState: Bundle?) {
        llDashboard = findViewById(R.id.ll_dashboard_bottom_navigation)
        ivDashboard = findViewById(R.id.iv_dashboard_bottom_navigation)
        tvDashboard = findViewById(R.id.tv_dashboard_bottom_navigation)
        llInbox = findViewById(R.id.ll_inbox_bottom_navigation)
        ivInbox = findViewById(R.id.iv_inbox_bottom_navigation)
        tvInbox = findViewById(R.id.tv_inbox_bottom_navigation)
        llTodo = findViewById(R.id.ll_todo_bottom_navigation)
        ivTodo = findViewById(R.id.iv_todo_bottom_navigation)
        tvTodo = findViewById(R.id.tv_todo_bottom_navigation)
        llAssigned = findViewById(R.id.ll_assigned_bottom_navigation)
        ivAssigned = findViewById(R.id.iv_assigned_bottom_navigation)
        tvAssigned = findViewById(R.id.tv_assigned_bottom_navigation)
        llArchive = findViewById(R.id.ll_archive_bottom_navigation)
        ivArchive = findViewById(R.id.iv_archive_bottom_navigation)
        tvArchive = findViewById(R.id.tv_archive_bottom_navigation)
        ibSearch = findViewById(R.id.ib_search_main)
        ibAdd = findViewById(R.id.ib_add_aksi_main)
        ibMenu = findViewById(R.id.ib_settings_main)

        layouts = arrayOf(llDashboard, llInbox, llTodo, llAssigned, llArchive)
        imageViews = arrayOf(ivDashboard, ivInbox, ivTodo, ivAssigned, ivArchive)
        textViews = arrayOf(tvDashboard, tvInbox, tvTodo, tvAssigned, tvArchive)

        layouts?.forEach {
            it.setOnClickListener(this)
        }

        if (savedInstanceState == null) {
            dashboardFragment = DashboardFragment()
            inboxFragment = InboxFragment()
            todoFragment = TODOFragment()
            assignedFragment = AssignedFragment()
            archiveFragment = ArchiveFragment()
            loadFragment(inboxFragment)
            ibSearch.visibility = View.VISIBLE
            setSelected(llInbox)
        }

        setupActions()
    }

    private fun setupActions() {
        ibAdd.setOnClickListener { showAddActionDialog() }
        ibMenu.setOnClickListener {
            val intent = Intent(this, MoreActivity::class.java)
            startActivity(intent)
        }
    }

    private fun disableTab(linearLayout: LinearLayout, imageView: ImageView, textView: TextView) {
        val params = LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.MATCH_PARENT
        )
        params.weight = 0.8f
        params.gravity= Gravity.CENTER
        linearLayout.layoutParams = params
        linearLayout.background = null
        textView.visibility = View.GONE
        imageView.background=null

        imageView.setColorFilter(
            ContextCompat.getColor(this, R.color.textColorSecondary),
            PorterDuff.Mode.MULTIPLY
        )
    }

    private fun enable(linearLayout: LinearLayout, imageView: ImageView, textView: TextView) {
        linearLayout.background = ContextCompat.getDrawable(this, R.drawable.bg_bottom)
        val params = LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.MATCH_PARENT
        )
        params.weight = 0.8f
        params.gravity= Gravity.CENTER
        linearLayout.layoutParams = params
        imageView.setColorFilter(
            ContextCompat.getColor(this,
                R.color.colorBlack
            ))
        textView.visibility = View.VISIBLE
        textView.setTextColor(ContextCompat.getColor(this, R.color.colorPrimaryDark))
    }

    private fun setSelected(mBarImg: LinearLayout) {
        for ((index, linearLayout) in this.layouts!!.withIndex()) {
            if (linearLayout === mBarImg) {
                enable(linearLayout, this.imageViews?.get(index)!!, textViews?.get(index)!!)
            } else {
                disableTab(linearLayout, imageViews?.get(index)!!, textViews?.get(index)!!)
            }
        }
    }

    override fun onClick(p0: View?) {
        when (p0!!.id) {
            R.id.ll_dashboard_bottom_navigation -> {
                loadFragment(dashboardFragment)
                setSelected(llDashboard)

                ibSearch.visibility = View.GONE
            }
            R.id.ll_inbox_bottom_navigation -> {
                loadFragment(inboxFragment)
                setSelected(llInbox)

                ibSearch.visibility = View.VISIBLE
            }
            R.id.ll_todo_bottom_navigation -> {
                loadFragment(todoFragment)
                setSelected(llTodo)

                ibSearch.visibility = View.GONE
            }
            R.id.ll_assigned_bottom_navigation -> {
                loadFragment(assignedFragment)
                setSelected(llAssigned)

                ibSearch.visibility = View.GONE
            }
            R.id.ll_archive_bottom_navigation -> {
                loadFragment(archiveFragment)
                setSelected(llArchive)

                ibSearch.visibility = View.GONE
            }
        }
    }

    override fun onResume() {
        super.onResume()

        if (Preferences.getUserData(this) != null) { // hanya kalau sudah login
            if (!arePushNotificationsEnabled(this)) {
                showNotificationDisabledPrompt()
            }
        }
    }

    private fun showNotificationDisabledPrompt() {
        Snackbar.make(findViewById(android.R.id.content),
            "Notifikasi sedang nonaktif. Aktifkan agar dapat pembaruan penting.",
            Snackbar.LENGTH_LONG
        ).setAction("Pengaturan") {
            openAppNotificationSettings()
        }.show()
    }

    private fun openAppNotificationSettings() {
        val intent = Intent().apply {
            action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
            putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
        }
        startActivity(intent)
    }

    private fun showAddActionDialog() {
        val dialogView = layoutInflater.inflate(R.layout.dialog_add_action, null)
        val rv = dialogView.findViewById<RecyclerView>(R.id.rvActions)

        val alertDialog = androidx.appcompat.app.AlertDialog.Builder(this)
            .setView(dialogView)
            .create()

        // 1) Siapkan list mutable, isi dulu id=0
        val items = mutableListOf(
            AddActionItem(0, "Custom")
        )

        // 2) Pasang adapter dari awal biar dialog bisa tampil, lalu nanti update saat API selesai
        val adapter = AddActionAdapter(items) { item ->
            alertDialog.dismiss()
            when (item.id) {
                0 -> { // Custom
                    startActivity(Intent(this@MainActivity,
                        AddCustomActionActivity::class.java))
                }
                else -> {
                    val intent = Intent(this@MainActivity,
                        AddTemplateActionActivity::class.java)
                    val data = Gson().toJson(item)
                    intent.putExtra("data", data)
                    startActivity(intent)
                }
            }
        }

        rv.layoutManager = LinearLayoutManager(this)
        rv.adapter = adapter

        alertDialog.show()

        // 3) Ambil data dari API, tambahkan ke list, lalu urutkan dari id=0
        APIMain.require().selectionServices
            .komunikasi(Preferences.getAccessToken(this))
            .enqueue(object : Callback<ArrayList<Komunikasi>> {
                override fun onResponse(
                    call: Call<ArrayList<Komunikasi>>,
                    response: Response<ArrayList<Komunikasi>>
                ) {
                    if (!response.isSuccessful) {
                        val raw = runCatching { response.errorBody()?.string().orEmpty() }.getOrDefault("")
                        val expired = raw.contains("Signature has expired", true) || raw.contains("token_expired", true)

                        val message = when {
                            (response.code() == 401 || response.code() == 500) && expired -> {
                                forceLogoutAndGoLogin(this@MainActivity)
                                "Session expired. Please login again."
                            }
                            response.code() == 400 -> runCatching {
                                JsonParser.parseString(raw).asJsonObject["message"].asString
                            }.getOrDefault("Bad request")
                            else -> "${response.code()}, ${response.message()}"
                        }

                        showSnack(message)
                        response.errorBody()?.close()

                        return
                    }

                    val body = response.body().orEmpty()

                    // tambahkan hasil API ke list
                    body.forEach { k ->
                        items.add(AddActionItem(k.kode, k.komunikasi,
                            k.id_tentang, k.id_tipe_komunikasi,
                            k.komunikasi_detail))
                    }

                    // urutkan dari id paling kecil (custom id=0 otomatis di atas)
                    items.sortBy { it.id }

                    // refresh adapter (kalau adapter kamu belum punya method update, lihat catatan di bawah)
                    adapter.notifyDataSetChanged()
                }

                override fun onFailure(call: Call<ArrayList<Komunikasi>>, t: Throwable) {
                    showSnack(t.message.toString())
                }
            })
    }

    private fun showSnack(message: String) {
        Snackbar.make(findViewById(android.R.id.content), message, Snackbar.LENGTH_LONG).show()
    }

}