package com.tt.honeyDue.platform

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.interop.LocalUIViewController
import com.tt.honeyDue.models.HoneyDueShareCodec
import com.tt.honeyDue.models.Residence
import com.tt.honeyDue.network.APILayer
import com.tt.honeyDue.network.ApiResult
import kotlinx.coroutines.launch
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.usePinned
import platform.Foundation.*
import platform.UIKit.UIActivityViewController
import platform.UIKit.UIViewController

@Composable
actual fun rememberShareResidence(): Pair<ResidenceSharingState, (Residence) -> Unit> {
    val viewController = LocalUIViewController.current
    val scope = rememberCoroutineScope()
    var state by remember { mutableStateOf(ResidenceSharingState()) }

    val shareFunction: (Residence) -> Unit = share@{ residence ->
        scope.launch {
            state = ResidenceSharingState(isLoading = true)

            when (val result = APILayer.generateSharePackage(residence.id)) {
                is ApiResult.Success -> {
                    val jsonContent = HoneyDueShareCodec.encodeSharedResidence(result.data)
                    val fileUrl = writeShareFile(jsonContent, residence.name)
                    if (fileUrl == null) {
                        state = ResidenceSharingState(isLoading = false, error = "Failed to create share package")
                        return@launch
                    }

                    state = ResidenceSharingState(isLoading = false)
                    presentShareSheet(viewController, fileUrl)
                }
                is ApiResult.Error -> {
                    state = ResidenceSharingState(
                        isLoading = false,
                        error = result.message.ifBlank { "Failed to generate share package" }
                    )
                }
                else -> {
                    state = ResidenceSharingState(isLoading = false, error = "Failed to generate share package")
                }
            }
        }
    }

    return Pair(state, shareFunction)
}

@OptIn(ExperimentalForeignApi::class)
private fun writeShareFile(jsonContent: String, displayName: String): NSURL? {
    val fileName = HoneyDueShareCodec.safeShareFileName(displayName)
    val filePath = NSTemporaryDirectory().plus(fileName)

    val bytes = jsonContent.encodeToByteArray()
    val data = bytes.usePinned { pinned ->
        NSData.create(bytes = pinned.addressOf(0), length = bytes.size.toULong())
    }
    val didCreate = NSFileManager.defaultManager.createFileAtPath(
        path = filePath,
        contents = data,
        attributes = null
    )
    if (!didCreate) return null

    return NSURL.fileURLWithPath(filePath)
}

private fun presentShareSheet(viewController: UIViewController, fileUrl: NSURL) {
    val activityViewController = UIActivityViewController(
        activityItems = listOf(fileUrl),
        applicationActivities = null
    )
    viewController.presentViewController(
        viewControllerToPresent = activityViewController,
        animated = true,
        completion = null
    )
}
