package de.storchp.fdroidbuildstatus

import android.annotation.SuppressLint
import android.app.Activity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import de.storchp.fdroidbuildstatus.databinding.ItemMainAppbuildBinding
import de.storchp.fdroidbuildstatus.model.App
import de.storchp.fdroidbuildstatus.model.AppBuild
import de.storchp.fdroidbuildstatus.model.BuildCycle
import de.storchp.fdroidbuildstatus.utils.DrawableUtils

class MainAppListAdapter(
    private val context: Activity,
    private val onItemClickListener: AdapterView.OnItemClickListener,
    private val onItemLongClickListener: AdapterView.OnItemLongClickListener
) :
    RecyclerView.Adapter<MainAppListAdapter.ViewHolder>() {
    var appList: MutableList<App> = mutableListOf()
        @SuppressLint("NotifyDataSetChanged")
        set(value) {
            field = value
            notifyDataSetChanged()
        }

    val lastAppId: String?
        get() {
            return appList.lastOrNull()?.id
        }

    fun addItems(newItems: List<App>) {
        val oldSize = appList.size
        appList.addAll(newItems)
        notifyItemRangeInserted(oldSize, newItems.size)
    }

    class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {

        val favouriteIcon: ImageView = view.findViewById(R.id.favouriteIcon)
        val disabledIcon: ImageView = view.findViewById(R.id.disabledIcon)
        val needsUpdateIcon: ImageView = view.findViewById(R.id.needsUpdateIcon)
        val archivedIcon: ImageView = view.findViewById(R.id.archivedIcon)
        val noPackagesIcon: ImageView = view.findViewById(R.id.noPackagesIcon)
        val noUpdateCheckIcon: ImageView = view.findViewById(R.id.noUpdateCheckIcon)
        val appName: TextView = view.findViewById(R.id.app_name)
        val appId: TextView = view.findViewById(R.id.app_id)
        val appBuilds: LinearLayout = view.findViewById(R.id.app_builds)

        init {
            DrawableUtils.setIconWithTint(
                view.context,
                disabledIcon,
                R.drawable.ic_disabled_24dp,
                appName.currentTextColor
            )
            DrawableUtils.setIconWithTint(
                view.context,
                archivedIcon,
                R.drawable.ic_archive_24,
                appName.currentTextColor
            )
            DrawableUtils.setIconWithTint(
                view.context,
                noPackagesIcon,
                R.drawable.ic_no_packages_24,
                appName.currentTextColor
            )
            DrawableUtils.setIconWithTint(
                view.context,
                noUpdateCheckIcon,
                R.drawable.ic_no_update_check_24,
                appName.currentTextColor
            )
            DrawableUtils.setIconWithTint(
                view.context,
                needsUpdateIcon,
                R.drawable.ic_upgrade_24dp,
                appName.currentTextColor
            )
        }

        fun setListeners(
            onItemClickListener: AdapterView.OnItemClickListener,
            onItemLongClickListener: AdapterView.OnItemLongClickListener
        ) {
            view.setOnClickListener {
                onItemClickListener.onItemClick(null, it, layoutPosition, itemId)
            }
            view.setOnLongClickListener {
                onItemLongClickListener.onItemLongClick(null, it, layoutPosition, itemId)
                true
            }
        }

    }

    fun getItemForPosition(position: Int): App? {
        return if (position == 0) {
            null
        } else appList[position - 1]
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(viewGroup.context)
            .inflate(R.layout.item_main_app, viewGroup, false)

        return ViewHolder(view)
    }

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        val app = appList[position]
        viewHolder.appName.text = app.name
        viewHolder.appId.text = app.id
        viewHolder.disabledIcon.visibility = if (app.disabled) View.VISIBLE else View.GONE
        viewHolder.archivedIcon.visibility = if (app.archived) View.VISIBLE else View.GONE
        viewHolder.noPackagesIcon.visibility = if (app.noPackages) View.VISIBLE else View.GONE
        viewHolder.noUpdateCheckIcon.visibility = if (app.noUpdateCheck) View.VISIBLE else View.GONE
        viewHolder.needsUpdateIcon.visibility = if (app.needsUpdate) View.VISIBLE else View.GONE
        viewHolder.appBuilds.removeAllViews()
        app.appBuildsByVersionCodeAndStatus
            .forEach { (_: String?, builds: List<AppBuild>) ->
                addAppBuild(
                    viewHolder,
                    context.layoutInflater,
                    builds
                )
            }
        viewHolder.setListeners(onItemClickListener, onItemLongClickListener)

        DrawableUtils.setIconWithTint(
            context,
            viewHolder.favouriteIcon,
            app.favouriteIcon,
            viewHolder.appName.currentTextColor
        )
    }

    override fun getItemCount() = appList.size

    private fun addAppBuild(
        binding: ViewHolder,
        inflater: LayoutInflater,
        builds: List<AppBuild>
    ) {
        val bindingBuild = ItemMainAppbuildBinding.inflate(inflater, binding.appBuilds, false)
        val appBuild = builds[0]
        bindingBuild.version.text = appBuild.fullVersion
        setBuildTypIcon(
            bindingBuild.buildRunTypeRunning,
            builds,
            BuildCycle.RUNNING,
            bindingBuild.version.currentTextColor
        )
        setBuildTypIcon(
            bindingBuild.buildRunTypeFinished,
            builds,
            BuildCycle.BUILD,
            bindingBuild.version.currentTextColor
        )
        setBuildTypIcon(
            bindingBuild.buildRunTypeUpdate,
            builds,
            BuildCycle.UPDATE,
            bindingBuild.version.currentTextColor
        )
        DrawableUtils.setIconWithTint(
            context,
            bindingBuild.statusIcon,
            appBuild.status.iconRes,
            context.getColor(appBuild.status.getIconColorRes(bindingBuild.version.currentTextColor))
        )
        binding.appBuilds.addView(bindingBuild.root)
    }

    private fun setBuildTypIcon(
        bindingBuild: ImageView,
        builds: List<AppBuild>,
        buildCycle: BuildCycle,
        color: Int,
    ) {
        if (builds.any { (_, _, appBuildCycle): AppBuild -> appBuildCycle === buildCycle }) {
            bindingBuild.visibility = View.VISIBLE
            DrawableUtils.setIconWithTint(context, bindingBuild, buildCycle.iconRes, color)
        } else {
            bindingBuild.visibility = View.GONE
        }
    }

}