package com.sinch.android.rtc.sample.push

import android.content.Intent
import android.media.AudioManager
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import com.sinch.android.rtc.calling.Call
import com.sinch.android.rtc.calling.CallListener
import java.util.*

class CallScreenActivity : BaseActivity() {

    private val audioPlayer by lazy {
        AudioPlayer(this)
    }
    private var durationTask: UpdateCallDurationTask? = null
    private var timer: Timer? = null

    private val callId: String get() = intent.getStringExtra(SinchService.CALL_ID).orEmpty()
    private val call: Call? get() = sinchServiceInterface?.getCall(callId)

    private lateinit var callDurationTextView: TextView
    private lateinit var callStateTextView: TextView
    private lateinit var callerNameTextView: TextView
    private lateinit var endCallButton: Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.callscreen)

        callDurationTextView = findViewById(R.id.callDuration)
        callerNameTextView = findViewById(R.id.remoteUser)
        callStateTextView = findViewById(R.id.callState)
        endCallButton = findViewById(R.id.hangupButton)

        endCallButton.setOnClickListener { endCall() }
        startService(Intent(applicationContext, OngoingCallService::class.java))
    }

    public override fun onServiceConnected() {
        if (call != null) {
            call?.addCallListener(SinchCallListener())
            callerNameTextView.text = call?.remoteUserId
            callStateTextView.text = call?.state.toString()
        } else {
            Log.e(TAG, "Started with invalid callId, aborting.")
            stopService(Intent(this, OngoingCallService::class.java))
            finish()
        }
    }

    public override fun onPause() {
        super.onPause()
        durationTask?.cancel()
        timer?.cancel()
    }

    public override fun onResume() {
        super.onResume()
        durationTask = UpdateCallDurationTask()
        timer = Timer().apply {
            schedule(durationTask, 0, 500)
        }
    }

    override fun onBackPressed() {
        // User should exit activity by ending call, not by going back.
    }

    private fun endCall() {
        audioPlayer.stopProgressTone()
        call?.hangup()
        stopService(Intent(this, OngoingCallService::class.java))
        finish()
    }

    private fun formatTimespan(totalSeconds: Int): String {
        val minutes = (totalSeconds / 60).toLong()
        val seconds = (totalSeconds % 60).toLong()
        return String.format(Locale.US, "%02d:%02d", minutes, seconds)
    }

    private fun updateCallDuration() {
        callDurationTextView.text = formatTimespan(call?.details?.duration ?: 0)
    }

    private inner class UpdateCallDurationTask : TimerTask() {
        override fun run() {
            runOnUiThread { updateCallDuration() }
        }
    }

    private inner class SinchCallListener : CallListener {

        override fun onCallEnded(call: Call) {
            val cause = call.details.endCause
            Log.d(TAG, "Call ended. Reason: $cause")
            audioPlayer.stopProgressTone()
            volumeControlStream = AudioManager.USE_DEFAULT_STREAM_TYPE
            val endMsg = "Call ended: " + call.details.toString()
            Toast.makeText(this@CallScreenActivity, endMsg, Toast.LENGTH_LONG).show()
            endCall()
        }

        override fun onCallEstablished(call: Call) {
            Log.d(TAG, "Call established")
            audioPlayer.stopProgressTone()
            callStateTextView.text = call.state.toString()
            volumeControlStream = AudioManager.STREAM_VOICE_CALL
            sinchServiceInterface?.audioController?.disableSpeaker()
        }

        override fun onCallProgressing(call: Call) {
            Log.d(TAG, "Call progressing")
            audioPlayer.playProgressTone()
        }
    }

    companion object {
        val TAG: String = CallScreenActivity::class.java.simpleName
    }
}