package com.yorvana.ui.util

import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import androidx.compose.material3.SnackbarHostState
import androidx.core.net.toUri
import com.google.common.truth.Truth.assertThat
import com.yorvana.R
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import io.mockk.runs
import io.mockk.slot
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config

@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [34])
class EmailLaunchRequestTest {
    @Test
    fun `launchEmail starts mailto email intent`() =
        runTest {
            val context = mockk<Context>()
            val intentSlot = slot<Intent>()
            every { context.startActivity(capture(intentSlot)) } just runs

            launchEmail(
                context = context,
                snackbarHostState = SnackbarHostState(),
                noEmailAppMessageRes = R.string.email_no_app_found,
                request =
                    EmailLaunchRequest(
                        recipient = "support@example.com",
                        subject = "Subject",
                        body = "Body",
                    ),
            )

            val intent = intentSlot.captured
            assertThat(intent.action).isEqualTo(Intent.ACTION_SENDTO)
            assertThat(intent.data).isEqualTo("mailto:".toUri())
            assertThat(intent.getStringArrayExtra(Intent.EXTRA_EMAIL)).asList().containsExactly("support@example.com")
            assertThat(intent.getStringExtra(Intent.EXTRA_SUBJECT)).isEqualTo("Subject")
            assertThat(intent.getStringExtra(Intent.EXTRA_TEXT)).isEqualTo("Body")
        }

    @Test
    fun `launchEmail shows snackbar when no email app is available`() =
        runTest {
            val context = mockk<Context>()
            val snackbarHostState = SnackbarHostState()
            every { context.startActivity(any()) } throws ActivityNotFoundException()
            every { context.getString(R.string.email_no_app_found) } returns "No email app found"

            val launchJob =
                launch {
                    launchEmail(
                        context = context,
                        snackbarHostState = snackbarHostState,
                        noEmailAppMessageRes = R.string.email_no_app_found,
                        request =
                            EmailLaunchRequest(
                                recipient = "support@example.com",
                                subject = "Subject",
                            ),
                    )
                }
            runCurrent()

            assertThat(snackbarHostState.currentSnackbarData?.visuals?.message).isEqualTo("No email app found")
            snackbarHostState.currentSnackbarData?.dismiss()
            launchJob.join()
        }
}
