package com.birdsounds.identify.presentation

import android.Manifest
import android.app.Activity
import android.content.pm.PackageManager
import android.util.Log
import androidx.annotation.RequiresPermission
import androidx.compose.foundation.MutatorMutex
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.core.content.ContextCompat
import androidx.navigation.NavHostController
import com.google.android.gms.wearable.ChannelClient
import com.google.android.gms.wearable.ChannelClient.ChannelCallback
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import java.time.Duration


class MainState(private val activity: Activity, private val requestPermission: () -> Unit) {
    private val playbackStateMutatorMutex = MutatorMutex()

    var appState by mutableStateOf<AppState>(AppState.Ready)


    var birdHeardState by mutableStateOf<BirdHeardState>(BirdHeardState.NotHearing)



    var recordingProgress by mutableStateOf(0f)
        private set
    var isPermissionDenied by mutableStateOf(false)
        private set
    private val soundRecorder = SoundRecorder(activity, "audiorecord.opus")
    private var navController: NavHostController? = null
    public fun setNavController(_navController: NavHostController) {
        navController = _navController
    }



    suspend fun onMicClicked() {
        playbackStateMutatorMutex.mutate {
            when (appState) {
                is AppState.Ready  -> when {
                    (ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) -> {
                        Log.e(TAG, "Permissions granted, continuing to record")
                        appState = AppState.Recording
                        navController?.navigate("species_list")
                        record(activity = activity, soundRecorder = soundRecorder, setProgress = { progress -> recordingProgress = progress })
                    }

                    else                                                                                                                 -> {
                        Log.e(TAG, "Requesting permissions")
                        requestPermission()
                    }
                }

                AppState.Recording -> {
                    appState = AppState.Ready
                }

            }
        }
    }


    suspend fun permissionResultReturned() {
        playbackStateMutatorMutex.mutate {
            if (ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
                appState = AppState.Recording

                record(activity=activity, soundRecorder = soundRecorder, setProgress = { progress ->
                    recordingProgress = progress
                })
                appState = AppState.Ready
            } else {
                isPermissionDenied = true
                appState = AppState.Ready
            }
        }
    }
}

sealed class AppState {
    object Ready : AppState()
    object Recording : AppState()
}

sealed class BirdHeardState {
    object Hearing : BirdHeardState()
    object NotHearing : BirdHeardState()
}



@RequiresPermission(Manifest.permission.RECORD_AUDIO)
private suspend fun record(activity: (Activity),soundRecorder: SoundRecorder,
                           setProgress: (progress: Float) -> Unit,
                           maxRecordingDuration: Duration = Duration.ofSeconds(10),
                           numberTicks: Int = 10) {

    val messagePath = "/message_path"

    coroutineScope { // Kick off a parallel job to

        Log.e(TAG, "Start recording") //
        val recordingJob = launch { soundRecorder.record() }
//    val recordingJob = launch { soundRecorder.record() }
//        SoundRecorder.record();
//        val ByteFlow: Flow<String> = flow {
//            while (true) {
//                var string_send = LocalDateTime.now().toString()
//                emit(string_send);
//                delay(250);
//                Log.e(TAG, "Emitting " + string_send)
//            }
//        }


//
//        val c_channel = channelClient.openChannel("Main","Audio");
//        val channel = c_channel.await();
//            val OutputStream = channelClient.getOutputStream(channel).await();
//            OutputStream.write(4);

//        ByteFlow.collect {
//
//
//
//            Log.e(TAG, "Received " + it)};

        //
        //        val delayPerTickMs = maxRecordingDuration.toMillis() / numberTicks
        //        val startTime = System.currentTimeMillis()
        //
        //        repeat(numberTicks) { index ->
        //            setProgress(index.toFloat() / numberTicks)
        //            delay(startTime + delayPerTickMs * (index + 1) - System.currentTimeMillis())
        //        } // Update the progress to be complete
        //        setProgress(1f)
        //
        //        // Stop recording
        //        recordingJob.cancel()
    }

}

object channelCallback : ChannelCallback() {
    override fun onChannelOpened(channel: ChannelClient.Channel) {
        super.onChannelOpened(channel)
    Log.e(TAG,"Opened channel")}
}

