/**
 *  Copyright (C) 2021 Anthony Chomienne
 *  This program is free software: you can redistribute it and/or modify it under the terms of the
 *  GNU Affero General Public License as published by the Free Software Foundation, version 3.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See the GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License along with this program.
 *  If not, see <https://www.gnu.org/licenses/>
 */

package fr.mobdev.peertubelive.activity

import android.content.DialogInterface
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.WindowManager
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import fr.mobdev.peertubelive.R
import fr.mobdev.peertubelive.databinding.HomeBinding
import fr.mobdev.peertubelive.dialog.AddInstanceDialog
import fr.mobdev.peertubelive.manager.DatabaseManager
import fr.mobdev.peertubelive.objects.OAuthData
import java.util.*

class MainActivity : AppCompatActivity() {

    private lateinit var accounts : List<OAuthData>
    private lateinit var adapter: AccountAdapter
    private lateinit var binding: HomeBinding
    private lateinit var prepareLive: ActivityResultLauncher<Intent>

    override fun onCreate(savedInstanceState: Bundle?) {
        window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.home)
        binding.instanceList.layoutManager = LinearLayoutManager(binding.root.context)
        prepareLive = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if(it.resultCode == -1 || it.resultCode == 0)
                return@registerForActivityResult
            val alertBuilder = AlertDialog.Builder(this)
            alertBuilder.setTitle(R.string.stream_ended)
            when (it.resultCode) {
                StreamActivity.BACKGROUND -> {
                    alertBuilder.setMessage(R.string.background_reason)
                }
                StreamActivity.BACK -> {
                    alertBuilder.setMessage(R.string.back_reason)
                }
                StreamActivity.LOCK -> {
                    alertBuilder.setMessage(R.string.lock_reason)
                }
                StreamActivity.STOP -> {
                    alertBuilder.setMessage(R.string.stop_reason)
                }
                StreamActivity.NETWORK_ERROR -> {
                    alertBuilder.setMessage(R.string.network_reason)
                }
            }
            alertBuilder.setPositiveButton(android.R.string.ok,null)
            alertBuilder.show()
        }
        setupList()
    }

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

    private fun setupList() {
        accounts = DatabaseManager.getCredentials(binding.root.context)
        if (accounts.isNotEmpty()) {
            if (!this::adapter.isInitialized) {
                adapter = AccountAdapter(accounts)
                adapter.onDeleteAccount = object: AccountAdapter.OnDeleteAccount {
                    override fun onDeleteAccount(oAuthData: OAuthData) {
                        val builder = AlertDialog.Builder(this@MainActivity)
                        builder.setMessage(getString(R.string.delete_account, oAuthData.username, oAuthData.baseUrl))
                        builder.setTitle(R.string.delete_account_title)
                        builder.setPositiveButton(R.string.yes){ _: DialogInterface, _: Int ->
                            DatabaseManager.deleteAccount(this@MainActivity, oAuthData)
                            setupList()
                        }
                        builder.setNegativeButton(R.string.no){ _: DialogInterface, _: Int ->
                            //Do Nothing
                        }
                        builder.show()
                    }

                };
                adapter.onClickListener = object: AccountAdapter.OnClickListener {


                    override fun onClick(oAuthData: OAuthData) {
                        if (oAuthData.refreshTokenExpires < Calendar.getInstance().timeInMillis) {
                            addOrUpdateAccount(oAuthData)
                        } else {
                            goLive(oAuthData)
                        }
                    }
                }
                binding.instanceList.adapter = adapter
            } else {
                adapter.setAccounts(accounts)
            }
            binding.noInstance.visibility = View.GONE
            binding.instanceList.visibility = View.VISIBLE
        }
        else {
            binding.noInstance.visibility = View.VISIBLE
            binding.instanceList.visibility = View.GONE
        }
    }

    private fun goLive(oAuthData: OAuthData) {
        val intent = Intent(this, CreateLiveActivity::class.java)
        intent.putExtra(CreateLiveActivity.OAUTH_DATA, oAuthData)
        prepareLive.launch(intent)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        super.onCreateOptionsMenu(menu)
        menuInflater.inflate(R.menu.home, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if(item.itemId == R.id.add_instance) {
            addOrUpdateAccount(null)
            return true
        }
        return false
    }

    private fun addOrUpdateAccount(shouldUpdateOAuthData: OAuthData?) {
        val wizard = AddInstanceDialog()
        if(shouldUpdateOAuthData != null)
            wizard.setOauthData(shouldUpdateOAuthData)
        wizard.setOnAddInstanceListener(object : AddInstanceDialog.OnAddInstanceListener {
            override fun addSuccess(oAuthData: OAuthData) {
                runOnUiThread {
                    setupList()
                    if (shouldUpdateOAuthData != null) {
                        goLive(oAuthData)
                    }
                }
            }
        })
        wizard.show(supportFragmentManager, "Wizard")
    }
}