package com.amz.genie.fragments

import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.amz.genie.R
import com.amz.genie.activities.GeneralDetailActivity
import com.amz.genie.activities.MainActivity
import com.amz.genie.adapters.GeneralAdapter
import com.amz.genie.helpers.Preferences
import com.amz.genie.helpers.Utils.forceLogoutAndGoLogin
import com.amz.genie.helpers.Utils.isNetworkAvailable
import com.amz.genie.helpers.Utils.showEmpty
import com.amz.genie.models.GeneralResponse
import com.amz.genie.models.GeneralThreadItem
import com.amz.genie.models.Pengguna
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
import kotlin.collections.orEmpty


class TODOFragment : Fragment() {

    private lateinit var srlTODO: SwipeRefreshLayout
    private lateinit var tvEmpty: TextView
    private lateinit var rvTODO: RecyclerView
    private lateinit var adapter: GeneralAdapter
    private lateinit var detailLauncher: androidx.activity.result.ActivityResultLauncher<Intent>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        detailLauncher =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                val needsRefresh = result.data?.getBooleanExtra("needs_refresh", false) ?: false
                if (result.resultCode == android.app.Activity.RESULT_OK && needsRefresh) {
                    initData()
                }
            }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_todo, container, false)
        initUI(view)
        return view
    }

    private fun initUI(view: View) {
        srlTODO = view.findViewById(R.id.srl_todo)
        tvEmpty = view.findViewById(R.id.tv_empty_todo)
        rvTODO = view.findViewById(R.id.rl_todo)

        val userData = Gson().fromJson(Preferences.getUserData(requireContext()),
            Pengguna::class.java)
        adapter = GeneralAdapter(userData.pegawai?.kode!!) { item ->
            val intent = Intent(requireContext(), GeneralDetailActivity::class.java)

            val gson = Gson()
            val dataJson = gson.toJson(item, GeneralThreadItem::class.java)
            intent.putExtra("data", dataJson)
            detailLauncher.launch(intent)
        }

        rvTODO.layoutManager = LinearLayoutManager(requireContext())
        rvTODO.adapter = adapter
        rvTODO.setHasFixedSize(true)

        srlTODO.setOnRefreshListener { initData() }

        initData()
    }

    private fun initData() {
        if (!isNetworkAvailable(requireContext())) {
            showSnack(getString(R.string.no_internet_message))
            srlTODO.isRefreshing = false
            return
        }

        showLoading(true)

        APIMain.require().generalServices
            .list(
                Preferences.getAccessToken(requireContext()),
                2
            )
            .enqueue(object : Callback<GeneralResponse> {

                override fun onResponse(call: Call<GeneralResponse>, response: Response<GeneralResponse>) {
                    showLoading(false)

                    if (response.isSuccessful) {
                        val list = response.body()?.items.orEmpty()

                        if (list.isEmpty()) {
                            showEmpty(true, tvEmpty, rvTODO)
                            adapter.submitList(emptyList())
                        } else {
                            showEmpty(false, tvEmpty, rvTODO)
                            adapter.submitList(list)
                        }
                        return
                    }

                    handleError(response)
                }

                override fun onFailure(call: Call<GeneralResponse>, t: Throwable) {
                    showLoading(false)
                    showSnack(t.message ?: "Terjadi kesalahan")
                }
            })
    }

    private fun handleError(response: Response<GeneralResponse>) {
        showLoading(false)
        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(requireActivity())
                "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)
    }

    private fun showLoading(show: Boolean) {
        srlTODO.isRefreshing = false
        (activity as? MainActivity)?.showProgressDialog(show)
    }

    private fun showSnack(message: String) {
        (activity as? MainActivity)?.let { act ->
            Snackbar.make(act.findViewById(android.R.id.content), message, Snackbar.LENGTH_LONG).show()
        }
    }

    private fun setupActions() {
        (activity as? MainActivity)?.setSearchClick({
            Toast.makeText(requireContext(), "TEST RUN", Toast.LENGTH_LONG).show()
        }, (activity as MainActivity).ibSearch)
    }

    override fun onResume() {
        super.onResume()
        setupActions()
    }

    override fun onPause() {
        super.onPause()
        (activity as? MainActivity)?.ibSearch?.setOnClickListener(null)
    }

    override fun onDestroy() {
        super.onDestroy()
        (activity as? MainActivity)?.ibSearch?.setOnClickListener(null)
    }
}