package bou.amine.apps.readerforselfossv2.android.fragments

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import bou.amine.apps.readerforselfossv2.android.HomeActivity
import bou.amine.apps.readerforselfossv2.android.R
import bou.amine.apps.readerforselfossv2.android.databinding.FilterFragmentBinding
import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName
import bou.amine.apps.readerforselfossv2.repository.Repository
import bou.amine.apps.readerforselfossv2.utils.getColorHexCode
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
import bou.amine.apps.readerforselfossv2.utils.getIcon
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.ViewTarget
import com.bumptech.glide.request.transition.Transition
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.chip.Chip
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.kodein.di.DI
import org.kodein.di.DIAware
import org.kodein.di.android.x.closestDI
import org.kodein.di.instance

class FilterSheetFragment : BottomSheetDialogFragment(), DIAware {
    private lateinit var binding: FilterFragmentBinding
    override val di: DI by closestDI()
    private val repository: Repository by instance()

    private var selectedChip: Chip? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View {
        binding =
            FilterFragmentBinding.inflate(
                inflater,
                container,
                false,
            )

        try {
            CoroutineScope(Dispatchers.Main).launch {
                handleTagChips(requireContext())
                handleSourceChips(requireContext())

                binding.progressBar2.visibility = GONE
                binding.filterView.visibility = VISIBLE
            }
        } catch (e: IllegalStateException) {
            dismiss()
            e.sendSilentlyWithAcraWithName("FilterSheetFragment > onCreateView")
        }

        binding.floatingActionButton2.setOnClickListener {
            (activity as HomeActivity).getElementsAccordingToTab()
            (activity as HomeActivity).fetchOnEmptyList()
            dismiss()
        }
        return binding.root
    }

    private suspend fun handleSourceChips(context: Context) {
        val sourceGroup = binding.sourcesGroup

        repository.getSourcesDetailsOrStats().forEachIndexed { _, source ->
            val c = Chip(context)
            c.ellipsize = TextUtils.TruncateAt.END

            Glide.with(context)
                .load(source.getIcon(repository.baseUrl))
                .into(
                    object : ViewTarget<Chip?, Drawable?>(c) {
                        override fun onResourceReady(
                            resource: Drawable,
                            transition: Transition<in Drawable?>?,
                        ) {
                            try {
                                c.chipIcon = resource
                            } catch (e: Exception) {
                                e.sendSilentlyWithAcraWithName("sources > onResourceReady")
                            }
                        }
                    },
                )

            c.text = source.title.getHtmlDecoded()

            c.setOnCloseIconClickListener {
                (it as Chip).isCloseIconVisible = false
                selectedChip = null
                repository.setSourceFilter(null)
            }

            c.setOnClickListener {
                if (selectedChip != null) {
                    selectedChip!!.isCloseIconVisible = false
                }
                (it as Chip).isCloseIconVisible = true
                selectedChip = it
                repository.setSourceFilter(source)

                repository.setTagFilter(null)
            }

            if (repository.sourceFilter.value?.equals(source) == true) {
                c.isCloseIconVisible = true
                selectedChip = c
            }

            c.isEnabled = source.error.isNullOrBlank()

            if (!source.error.isNullOrBlank() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                c.tooltipText = source.error
            }

            sourceGroup.addView(c)
        }
    }

    private suspend fun handleTagChips(context: Context) {
        val tagGroup = binding.tagsGroup

        val tags = repository.getTags()

        tags.forEachIndexed { _, tag ->
            val c = Chip(context)
            c.ellipsize = TextUtils.TruncateAt.END
            c.text = tag.tag

            if (tag.color.isNotEmpty()) {
                try {
                    val gd = GradientDrawable()
                    val gdColor =
                        try {
                            Color.parseColor(tag.getColorHexCode())
                        } catch (e: IllegalArgumentException) {
                            e.sendSilentlyWithAcraWithName("color issue " + tag.color + " / " + tag.getColorHexCode())
                            resources.getColor(R.color.colorPrimary)
                        }
                    gd.setColor(gdColor)
                    gd.shape = GradientDrawable.RECTANGLE
                    gd.setSize(30, 30)
                    gd.cornerRadius = 30F
                    c.chipIcon = gd
                } catch (e: Exception) {
                    e.sendSilentlyWithAcraWithName("tags > GradientDrawable")
                }
            }

            c.setOnCloseIconClickListener {
                (it as Chip).isCloseIconVisible = false
                selectedChip = null
                repository.setTagFilter(null)
            }

            c.setOnClickListener {
                if (selectedChip != null) {
                    selectedChip!!.isCloseIconVisible = false
                }
                (it as Chip).isCloseIconVisible = true
                selectedChip = it
                repository.setTagFilter(tag)

                repository.setSourceFilter(null)
            }

            if (repository.tagFilter.value?.equals(tag) == true) {
                c.isCloseIconVisible = true
                selectedChip = c
            }

            tagGroup.addView(c)
        }
    }

    companion object {
        const val TAG = "FilterModalBottomSheet"
    }
}