package com.humand.demo.modules.IncomingCallMessagingService.activity

import android.app.Activity
import android.app.KeyguardManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import android.widget.TextView
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.workDataOf
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.humand.demo.MainActivity
import com.humand.demo.R
import com.humand.demo.modules.IncomingCallMessagingService.api.BackgroundWorker
import com.humand.demo.modules.IncomingCallMessagingService.common.CallPayload
import com.humand.demo.modules.IncomingCallMessagingService.common.Constants
import com.humand.demo.modules.IncomingCallMessagingService.player.RingtonePlayer
import com.humand.demo.modules.IncomingCallMessagingService.cancelNotification

class FullScreenCallActivity : Activity() {

    // This BroadcastReceiver is used to close the activity when a push event is received
    // that indicates the call should be terminated (e.g., accepted or rejected on another device).
    private val receiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            finish()
        }
    }

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

        //Add blur effect
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            val window = window
            window.setBackgroundBlurRadius(20)
            window.setFlags(
                WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
                WindowManager.LayoutParams.FLAG_BLUR_BEHIND
            )
        } else {
            //Fallback
            window.setDimAmount(0.8f)
            window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        }

        setShowWhenLocked(true)
        setTurnScreenOn(true)
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

        val payload = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            intent.getParcelableExtra(Constants.CALL_PAYLOAD, CallPayload::class.java)
        } else {
            @Suppress("DEPRECATION")
            intent.getParcelableExtra<CallPayload>(Constants.CALL_PAYLOAD)
        }

        payload?.let {
            showAvatar(it.callerAvatar, it.callerName,it.isGroup ?: false, it.type)
        }

        // setup caller name and description
        with(findViewById<TextView>(R.id.incoming_call_caller_name)) {
            text = payload?.callerName
        }

        // setup accept button
        val acceptButton = findViewById<View>(R.id.incoming_call_btn_accept)
        setupCallButton(
            root = acceptButton,
            iconRes = R.drawable.btn_call_accept,
            textRes = R.string.incoming_call_accept,
        )

        // setup decline button
        val declineButton = findViewById<View>(R.id.incoming_call_btn_decline)
        setupCallButton(
            root = declineButton,
            iconRes = R.drawable.btn_call_decline,
            textRes = R.string.incoming_call_decline,
        )

        acceptButton.setOnClickListener {
            stopNotification()

            //Open main app
            val launchIntent = Intent(this, MainActivity::class.java).apply {
                addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or
                        Intent.FLAG_ACTIVITY_NEW_TASK or
                        Intent.FLAG_ACTIVITY_SINGLE_TOP
                )
                putExtra(Constants.CALL_PAYLOAD, payload)
                putExtra(Constants.OPENED_FROM_FULL_SCREEN_CALL_ACTIVITY, true)
            }
            startActivity(launchIntent)
            finish()
        }

        declineButton.setOnClickListener {
            stopNotification()
            payload?.let {
                val inputData = workDataOf(
                    Constants.CallPayloadKeys.ID to it.id,
                    Constants.CallPayloadKeys.PROVIDER_CALL_ID to it.providerCallId,
                    Constants.CallPayloadKeys.CALLER to it.callerName,
                    Constants.CallPayloadKeys.IS_GROUP to (it.isGroup ?: false),
                    Constants.CallPayloadKeys.INITIALIZATION_CONFIG to it.initializationConfig
                )
                val workRequest = OneTimeWorkRequestBuilder<BackgroundWorker>()
                    .setInputData(inputData)
                    .build()
                WorkManager.getInstance(this).enqueue(workRequest)
            }
            finish()
        }

        // btn press animation
        val buttonTouchHandler: (View, MotionEvent) -> Boolean = { view, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    view.alpha = 0.6f
                }

                MotionEvent.ACTION_MOVE -> {
                    val rect = Rect()
                    view.getGlobalVisibleRect(rect)
                    if (!rect.contains(event.rawX.toInt(), event.rawY.toInt())) {
                        view.alpha = 1f
                    } else {
                        view.alpha = 0.6f
                    }
                }

                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                    view.alpha = 1f
                }
            }
            false
        }

        acceptButton.setOnTouchListener(buttonTouchHandler)
        declineButton.setOnTouchListener(buttonTouchHandler)
    }

    override fun onResume() {
        super.onResume()
        LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
            IntentFilter(Constants.CLOSE_FULL_SCREEN_ACTIVITY_EVENT)
        )
    }

    override fun onPause() {
        super.onPause()
        LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)
    }

    fun getInitials(name: String?): String {
        if (name.isNullOrBlank()) return "?"

        return name
            .split(" ")
            .filter { it.isNotBlank() }
            .map { it.first().uppercaseChar() }
            .joinToString("")
            .take(2)
    }

    fun stopNotification() {
        cancelNotification(this)
    }

    private fun setupCallButton(
        root: View,
        iconRes: Int,
        textRes: Int,
    ) {
        val icon = root.findViewById<ImageView>(R.id.incoming_call_btn_icon)
        val label = root.findViewById<TextView>(R.id.incoming_call_btn_title)
        label.setText(textRes)
        icon.setImageResource(iconRes)
    }

    private fun showAvatar(url:String?, name:String, isGroup: Boolean = false,type: Constants.NotificationType) {
        val avatarView = findViewById<ImageView>(R.id.incoming_call_avatar)
        val avatarInitialsView = findViewById<TextView>(R.id.incoming_call_avatar_initials)

        val showGroupChatPlaceholder:()->Unit = {
            avatarView.setImageResource(R.drawable.group_call)
            avatarView.visibility = View.VISIBLE
            avatarInitialsView.visibility = View.GONE
        }

        val showInitials: ()->Unit = {
            avatarView.visibility = View.GONE
            avatarInitialsView.visibility = View.VISIBLE
            avatarInitialsView.text = getInitials(name)
        }

        if( type == Constants.NotificationType.CALL_JOIN_REQUESTED){
            showGroupChatPlaceholder()
            return
        }

        val showPlaceholderHandler:()-> Unit =  {
            if(isGroup){
                showGroupChatPlaceholder()
            }
            else {
                showInitials()
            }
        }

        showPlaceholderHandler()

        if(url.isNullOrBlank()){
            return
        }

        url?.let {
            Glide.with(this)
                .load(it)
                .circleCrop()
                .into(object : CustomTarget<Drawable>() {
                    override fun onResourceReady(
                        resource: Drawable,
                        transition: Transition<in Drawable>?
                    ) {
                        avatarView.setImageDrawable(resource)
                        avatarView.alpha = 0f
                        avatarInitialsView.visibility = View.GONE
                        avatarView.visibility = View.VISIBLE

                        avatarView.animate().alpha(1f)
                            .setDuration(300)
                            .start()
                    }

                    override fun onLoadCleared(placeholder: Drawable?) {}
                    override fun onLoadFailed(errorDrawable: Drawable?) {
                        showPlaceholderHandler()
                    }
                })
        }
    }
    
    override fun onDestroy() {
        super.onDestroy()
        RingtonePlayer.stop()
    }
}
