package com.castlabs.sdk.analytics_demo.recycle

import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.recyclerview.widget.RecyclerView
import com.castlabs.analytics.AnalyticsMetaData
import com.castlabs.android.SdkConsts
import com.castlabs.sdk.analytics_demo.R
import com.castlabs.sdk.analytics_demo.activities.PlayerActivity
import com.castlabs.sdk.analytics_demo.utils.APIService
import com.castlabs.sdk.analytics_demo.utils.BundleBuilder
import com.castlabs.sdk.analytics_demo.utils.Display
import com.castlabs.sdk.vimond.VimondPlugin
import org.json.JSONException
import org.json.JSONObject
import java.util.*

class DemoAdapter(private val data: ArrayList<DemoData>) : RecyclerView.Adapter<DemoAdapter.ViewHolder>() {

	companion object {
		var includeVimondMetadata = false
	}

	private lateinit var context: Context

	override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
		val view = LayoutInflater.from(parent.context).inflate(R.layout.recycle_demo, parent, false)
		context = parent.context
		return ViewHolder(view)
	}

	override fun onBindViewHolder(holder: ViewHolder, position: Int) {
		val mData = data[position]
		holder.tvTitle.text = mData.title
		holder.tvDescription.text = mData.description
		if (mData.isLoading) {
			holder.ivPlay.visibility = View.INVISIBLE
			holder.pbProgress.visibility = View.VISIBLE
		}
		else {
			holder.ivPlay.visibility = View.VISIBLE
			holder.pbProgress.visibility = View.INVISIBLE
		}
		setMargin(holder, position)
	}

	private fun setMargin(holder: ViewHolder, position: Int) {
		val params = holder.flMain.layoutParams as RecyclerView.LayoutParams
		val margin = Display.dpToPix(25, context).toInt()
		if (position == data.size - 1) params.bottomMargin = margin
		else params.bottomMargin = 0
		holder.flMain.layoutParams = params
	}

	override fun getItemCount(): Int {
		return data.size
	}

	inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

		val flMain: FrameLayout = itemView.findViewById(R.id.flMain)
		val tvTitle: TextView = itemView.findViewById(R.id.tvTitle)
		val tvDescription: TextView = itemView.findViewById(R.id.tvDescription)
		val ivPlay: ImageView = itemView.findViewById(R.id.ivPlay)
		val pbProgress: ProgressBar = itemView.findViewById(R.id.pbProgress)

		init {
		    itemView.setOnClickListener {
				if (includeVimondMetadata) getVimondToken(adapterPosition)
				else gotoPlayer(adapterPosition)
			}
		}

		private fun gotoPlayer(position: Int) {
			val mData = data[position]
			val intent = Intent(context, PlayerActivity::class.java)
			intent.putExtras(mData.bundle)
			context.startActivity(intent)
		}

		private fun getVimondToken(position: Int) {
			startLoading(position)
			val mData = data[position]
			val vimondSub = mData.bundle.get(BundleBuilder.VIMOND_SUB)
			val vimondAssetId = mData.bundle.get(BundleBuilder.VIMOND_ASSET_ID)
			val body = "{\n" +
					"  \"sub\": \"" + vimondSub + "\",\n" +
					"  \"aud\": \"bo-staging-audience\",\n" +
					"  \"https://vimond/entitlements\": [\n" +
					"    {\n" +
					"      \"quality\": \"fhd\",\n" +
					"      \"tvod\": {\n" +
					"        \"a\": [\n" +
					"          " + vimondAssetId + "\n" +
					"        ]\n" +
					"      }\n" +
					"    }\n" +
					"  ]\n" +
					"}"

			val call = APIService.apiInterface.getVimondToken(body)
			val apiService = APIService(call)
			apiService.onSuccess {
				try {
					val token = JSONObject(apiService.result!!).getString("token")
					getVimondRequest(position, token)
				}
				catch (e: JSONException) {
					stopLoading(position)
					showMessage("Could not parse Vimond token response")
				}
			}.onError {
				stopLoading(position)
				showMessage("Error: ${apiService.error}")
			}.start()
		}

		private fun getVimondRequest(position: Int, token: String) {
			val mData = data[position]
			val vimondAssetId = mData.bundle.get(BundleBuilder.VIMOND_ASSET_ID)
			val body = "{\n" +
					"  \"device\": {\n" +
					"    \"label\": \"desktop\",\n" +
					"    \"udid\": \"123-123-123\"\n" +
					"  }\n" +
					"}"

			val call = APIService.apiInterface.getVimondRequest(
				vimondAssetId.toString(),
				"application/json",
				"application/json",
				"Bearer $token",
				body
			)
			val apiService = APIService(call)
			apiService.onSuccess {
				stopLoading(position)
				val playerEventRequest = JSONObject()
				try {
					val obj = JSONObject(apiService.result!!)
					playerEventRequest.put("playerEventRequest", obj.getJSONArray("data")
						.getJSONObject(0).getJSONObject("playerEventRequest"))
					playerEventRequest.getJSONObject("playerEventRequest").getJSONObject("body")
						.getJSONObject("client").put("viewingSession", UUID.randomUUID())
					var analyticsMetaData = mData.bundle.get(SdkConsts.INTENT_ANALYTICS_DATA) as AnalyticsMetaData
					analyticsMetaData = VimondPlugin.createMetadata(
						playerEventRequest,
						token,
						analyticsMetaData
					)!!
					mData.bundle.putParcelable(SdkConsts.INTENT_ANALYTICS_DATA, analyticsMetaData)
					gotoPlayer(position)
				}
				catch (e: JSONException) {
					showMessage("Could not parse Vimond play response")
				}
			}.onError {
				stopLoading(position)
				showMessage("Error: ${apiService.error}")
			}.start()
		}

		private fun startLoading(position: Int) {
			val mData = data[position]
			mData.isLoading = true
			notifyItemChanged(position)
		}

		private fun stopLoading(position: Int) {
			val mData = data[position]
			mData.isLoading = false
			notifyItemChanged(position)
		}

		private fun showMessage(message: String) {
			Toast.makeText(context, message, Toast.LENGTH_LONG).show()
		}
	}
}
