package org.libre.agosto.p2play

import android.content.Intent
import android.os.AsyncTask
import android.os.Bundle
import android.os.Handler
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView
import androidx.core.view.GravityCompat
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.navigation.NavigationView
import com.squareup.picasso.Picasso
import org.libre.agosto.p2play.adapters.VideosAdapter
import org.libre.agosto.p2play.ajax.Videos
import org.libre.agosto.p2play.databinding.ActivityMainBinding
import org.libre.agosto.p2play.helpers.getViewManager
import org.libre.agosto.p2play.models.VideoModel
import org.libre.agosto.p2play.singletons.PlaybackSingleton

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
    private lateinit var recyclerView: RecyclerView
    private lateinit var viewAdapter: RecyclerView.Adapter<VideosAdapter.ViewHolder>
    private lateinit var viewManager: RecyclerView.LayoutManager
    private val client: Videos = Videos()
    private lateinit var lastItem: MenuItem
    lateinit var myMenu: Menu
    private val db = Database(this)
    var section: String = ""
    var searchVal: String = ""
    var pagination = 0

    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)
        setSupportActionBar(binding.toolbar)

        val toggle = ActionBarDrawerToggle(this, binding.drawerLayout, binding.toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
        binding.drawerLayout.addDrawerListener(toggle)
        toggle.syncState()

        binding.navView.setNavigationItemSelectedListener(this)

        viewManager = getViewManager(this, resources)

        // Init RecyclerView
        this.initRecycler()

        this.getTrengindVideos()

        binding.content.swipeContainer.setOnRefreshListener {
            this.refresh()
        }


        binding.content.mini.miniPlayerImage.setOnClickListener { this.resumeVideo() }
        binding.content.mini.miniPlayerTitle.setOnClickListener { this.resumeVideo() }
        binding.content.mini.miniPlayerAuthor.setOnClickListener { this.resumeVideo() }
        // binding.content.mini.setOnClickListener { this.resumeVideo() }
        binding.content.mini.miniPlayPause.setOnClickListener { this.playPausePlayer() }

        Handler().postDelayed({
            // Title for nav_bar
            binding.navView.getHeaderView(0).findViewById<TextView>(R.id.side_emailTxt).text = getString(R.string.nav_header_subtitle) + " " + this.packageManager.getPackageInfo(this.packageName, 0).versionName
        }, 2000)
    }

    // Generic function for set data to RecyclerView
    private fun initRecycler() {
        val data = arrayListOf<VideoModel>()
        viewAdapter = VideosAdapter(data)

        recyclerView = findViewById<RecyclerView>(R.id.list).apply {
            // use this setting to improve performance if you know that changes
            // in content do not change the layout size of the RecyclerView
            setHasFixedSize(true)

            // use a linear layout manager
            layoutManager = viewManager

            // specify an viewAdapter (see also next example)
            adapter = viewAdapter

            this.addOnScrollListener(object : RecyclerView.OnScrollListener() {
                override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                    super.onScrolled(recyclerView, dx, dy)
                    // super.onScrolled(recyclerView!!, dx, dy)

                    if (!binding.content.swipeContainer.isRefreshing) {
                        if (!canScrollVertically(1)) {
                            loadMore()
                        }
                    }
                }
            })
        }
        binding.content.swipeContainer.isRefreshing = false
    }

    private fun addVideos(videos: ArrayList<VideoModel>) {
        binding.content.swipeContainer.isRefreshing = true

        try {
            if (this.pagination == 0) {
                (viewAdapter as VideosAdapter).clearData()
                recyclerView.scrollToPosition(0)
            }

            (viewAdapter as VideosAdapter).addData(videos)
        } catch (err: Exception) {
            err.printStackTrace()
            ManagerSingleton.toast(getString(R.string.errorMsg), this)
        }

        binding.content.swipeContainer.isRefreshing = false
    }

    private fun refresh() {
        binding.content.swipeContainer.isRefreshing = true
        this.pagination = 0
        when (section) {
            "local" -> this.getLocalVideos()
            "popular" -> this.getPopularVideos()
            "trending" -> this.getTrengindVideos()
            "last" -> this.getLastVideos()
            "sub" -> this.getSubscriptionVideos()
            "search" -> this.searchVideos()
            "my_videos" -> {
                if (ManagerSingleton.token.token != "") {
                    this.getMyVideos()
                } else {
                    this.getLastVideos()
                }
            }
        }
    }

    private fun getSubscriptionVideos() {
        if (ManagerSingleton.user.status != 1) {
            ManagerSingleton.toast("Inicia session primero", this)
            startActivity(Intent(this, LoginActivity::class.java))
            return
        }
        binding.content.swipeContainer.isRefreshing = true
        section = "sub"
        setTitle(R.string.title_subscriptions)
        AsyncTask.execute {
            val videos = client.videoSubscriptions(ManagerSingleton.token.token, this.pagination)
            runOnUiThread {
                this.addVideos(videos)
            }
        }
    }

    // Last videos
    private fun getLastVideos() {
        binding.content.swipeContainer.isRefreshing = true
        section = "last"
        setTitle(R.string.title_recent)
        AsyncTask.execute {
            val videos = client.getLastVideos(this.pagination)
            runOnUiThread {
                this.addVideos(videos)
            }
        }
    }

    // Popular videos
    private fun getPopularVideos() {
        binding.content.swipeContainer.isRefreshing = true
        section = "popular"
        setTitle(R.string.title_popular)
        AsyncTask.execute {
            val videos = client.getPopularVideos(this.pagination)
            runOnUiThread {
                this.addVideos(videos)
            }
        }
    }

    // Trending videos
    private fun getTrengindVideos() {
        binding.content.swipeContainer.isRefreshing = true
        section = "trending"
        setTitle(R.string.title_trending)
        AsyncTask.execute {
            val videos = client.getTrendingVideos(this.pagination)
            runOnUiThread {
                this.addVideos(videos)
            }
        }
    }

    // Local videos
    private fun getLocalVideos() {
        binding.content.swipeContainer.isRefreshing = true
        section = "local"
        setTitle(R.string.title_local)
        AsyncTask.execute {
            val videos = client.getLocalVideos(this.pagination)
            runOnUiThread {
                this.addVideos(videos)
            }
        }
    }

    // Videos of user
    private fun getMyVideos() {
        binding.content.swipeContainer.isRefreshing = true
        section = "my_videos"
        setTitle(R.string.title_myVideos)
        AsyncTask.execute {
            val videos = client.myVideos(ManagerSingleton.token.token, this.pagination)
            runOnUiThread {
                this.addVideos(videos)
            }
        }
    }

    // Videos history of user
    private fun getHistory() {
        binding.content.swipeContainer.isRefreshing = true
        section = "my_videos"
        setTitle(R.string.nav_history)
        AsyncTask.execute {
            val videos = client.videoHistory(ManagerSingleton.token.token, this.pagination)
            runOnUiThread {
                this.addVideos(videos)
            }
        }
    }

    // Most liked
    private fun getMostLiked() {
        binding.content.swipeContainer.isRefreshing = true
        section = "liked"
        setTitle(R.string.nav_likes)
        AsyncTask.execute {
            val videos = client.getMostLikedVideos(this.pagination)
            runOnUiThread {
                this.addVideos(videos)
            }
        }
    }

    override fun onBackPressed() {
        if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
            binding.drawerLayout.closeDrawer(GravityCompat.START)
        } else if (!section.equals("trending")) {
            // Hot fix
            pagination = 0
            this.getTrengindVideos()
        } else {
            super.onBackPressed()
        }
    }

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

        val searchItem = menu.findItem(R.id.app_bar_search)
        val searchView = searchItem.actionView as SearchView

        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextChange(p0: String?): Boolean {
                return true
            }

            override fun onQueryTextSubmit(p0: String?): Boolean {
                if (!p0.isNullOrBlank()) {
                    searchVal = p0
                    pagination = 0
                    searchView.onActionViewCollapsed()
                    searchVideos()
                }
                return true
            }
        })

        myMenu = menu
        setSideData()
        return true
    }

    override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
        myMenu = menu!!

        return super.onPrepareOptionsMenu(menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        when (item.itemId) {
            R.id.action_settings -> {
                val intent = Intent(this, SettingsActivity2::class.java)
                startActivity(intent)
                return true
            }
            R.id.action_login -> {
                val intent = Intent(this, LoginActivity::class.java)
                startActivity(intent)
                return true
            }
            R.id.action_logout -> {
                logout()
                return true
            }
            else -> return super.onOptionsItemSelected(item)
        }
    }

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        // Handle navigation view item clicks here.

        // if(::lastItem.isInitialized){
        // lastItem.isChecked = false
        // }
        lastItem = item
        pagination = 0

        // item.isChecked = true
        when (item.itemId) {
            R.id.nav_subscriptions -> getSubscriptionVideos()
            R.id.nav_popular -> getPopularVideos()
            R.id.nav_trending -> getTrengindVideos()
            R.id.nav_recent -> getLastVideos()
            R.id.nav_local -> getLocalVideos()
            R.id.nav_about -> {
                val intent = Intent(this, AboutActivity::class.java)
                startActivity(intent)
            }
            R.id.nav_history -> getHistory()
            R.id.nav_myVideos -> getMyVideos()
            R.id.nav_likes -> getMostLiked()
        }

        binding.drawerLayout.closeDrawer(GravityCompat.START)
        return true
    }

    override fun onResume() {
        super.onResume()
        setSideData()

        if (PlaybackSingleton.player != null && PlaybackSingleton.player!!.isPlaying) {
            PlaybackSingleton.runMediaSession(this)

            binding.content.mini.miniPlayerTitle.text = PlaybackSingleton.video!!.name
            binding.content.mini.miniPlayerAuthor.text = PlaybackSingleton.video!!.username
            Picasso.get().load("https://${ManagerSingleton.url}${PlaybackSingleton.video!!.thumbUrl}").into(binding.content.mini.miniPlayerImage)
            binding.content.mini.miniPlayPause.setImageResource(R.drawable.ic_pause_24)
            binding.content.mini.miniPlayer.visibility = View.VISIBLE
        } else {
            binding.content.mini.miniPlayer.visibility = View.GONE
        }
    }

    override fun onDestroy() {
        if (PlaybackSingleton.player != null) {
            PlaybackSingleton.release()
        }
        super.onDestroy()
    }

    private fun setSideData() {
        if (ManagerSingleton.user.status == 1) {
            binding.navView.menu.findItem(R.id.ml).isVisible = true

            val headerView = binding.navView.getHeaderView(0)
            headerView.findViewById<TextView>(R.id.side_usernameTxt).text = ManagerSingleton.user.username
            headerView.findViewById<TextView>(R.id.side_emailTxt).text = ManagerSingleton.user.email
            if (ManagerSingleton.user.avatar != "" && headerView.findViewById<ImageView>(R.id.side_imageView) != null) {
                 Picasso.get().load("https://" + ManagerSingleton.url + ManagerSingleton.user.avatar).into(headerView.findViewById<ImageView>(R.id.side_imageView))
            }
            headerView.findViewById<ImageView>(R.id.side_imageView).setOnClickListener {
                pagination = 0
                getMyVideos()
                binding.drawerLayout.closeDrawer(GravityCompat.START)
            }
            if (::myMenu.isInitialized) {
                myMenu.findItem(R.id.action_login).isVisible = false
                myMenu.findItem(R.id.action_logout).isVisible = true
            }
        } else {
            binding.navView.menu.findItem(R.id.ml).isVisible = false
        }
    }

    private fun logout() {
        if (::myMenu.isInitialized) {
            myMenu.findItem(R.id.action_login).isVisible = true
            myMenu.findItem(R.id.action_logout).isVisible = false
        }
        val headerView = binding.navView.getHeaderView(0)
        binding.navView.menu.findItem(R.id.ml).isVisible = false
        headerView.findViewById<TextView>(R.id.side_usernameTxt).text = getString(R.string.nav_header_title)
        headerView.findViewById<TextView>(R.id.side_emailTxt).text = getString(R.string.nav_header_subtitle) + " " + this.packageManager.getPackageInfo(this.packageName, 0).versionName
        headerView.findViewById<ImageView>(R.id.side_imageView).setImageResource(R.drawable.default_avatar)
        headerView.findViewById<ImageView>(R.id.side_imageView).setOnClickListener { }
        db.logout()
        ManagerSingleton.logout()

        this.refresh()
        ManagerSingleton.toast(getString(R.string.logout_msg), this)
        setSideData()
    }

    private fun loadMore() {
        binding.content.swipeContainer.isRefreshing = true
        this.pagination += ManagerSingleton.videosCount

        when (section) {
            "local" -> this.getLocalVideos()
            "popular" -> this.getPopularVideos()
            "trending" -> this.getTrengindVideos()
            "last" -> this.getLastVideos()
            "sub" -> this.getSubscriptionVideos()
            "search" -> this.searchVideos()
            "my_videos" -> {
                if (ManagerSingleton.token.token != "") {
                    this.getMyVideos()
                } else {
                    this.getLastVideos()
                }
            }
            "liked" -> this.getMostLiked()
        }
    }

    private fun searchVideos() {
        binding.content.swipeContainer.isRefreshing = true
        section = "search"
        this.title = this.searchVal
        AsyncTask.execute {
            val videos = client.search(this.searchVal, this.pagination)
            runOnUiThread {
                this.addVideos(videos)
            }
        }
    }

    private fun resumeVideo() {
        val intent = Intent(this, ReproductorActivity::class.java)
        intent.putExtra("resume", true)
        startActivity(intent)
    }

    private fun playPausePlayer() {
        PlaybackSingleton.player?.let {
            if (it.isPlaying) {
                it.pause()
                binding.content.mini.miniPlayPause.setImageResource(R.drawable.ic_play_arrow_24)
            } else {
                it.play()
                binding.content.mini.miniPlayPause.setImageResource(R.drawable.ic_pause_24)
            }
        }
    }
}
