package com.vnidrop.app.core

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import uniffi.vnidrop.ReceiveOutputSinkV2
import java.io.File

@Composable
actual fun rememberFileSystemService(): FileSystemService =
	remember { JvmFileSystemService() }

private class JvmFileSystemService : FileSystemService {
	override fun defaultReceiveFolder(): ReceiveFolder =
		ReceiveFolder(
			kind = ReceiveFolderKind.FileSystemPath,
			value = File(System.getProperty("user.home"), "Downloads").absolutePath,
			displayName = "Downloads",
		)

	override suspend fun validateReceiveFolder(folder: ReceiveFolder): FolderAccessStatus {
		if (folder.kind != ReceiveFolderKind.FileSystemPath) return FolderAccessStatus.Unavailable
		return runCatching {
			val directory = File(folder.value)
			if (!directory.exists()) directory.mkdirs()
			if (directory.isDirectory && directory.canWrite()) FolderAccessStatus.Writable else FolderAccessStatus.Unavailable
		}.getOrDefault(FolderAccessStatus.Unavailable)
	}

	override suspend fun inspectReceivedArtifacts(artifacts: List<ReceivedArtifactModel>): ReceivedStorageInspection {
		var bytes = 0UL
		var existing = 0
		var missing = 0
		for (artifact in artifacts) {
			val file = File(artifact.locator)
			if (file.isFile) {
				bytes += file.length().toULong()
				existing += 1
			} else {
				missing += 1
			}
		}
		return ReceivedStorageInspection(bytes, existing, missing, 0)
	}

	override suspend fun temporaryUsage(): ULong = 0UL

	override fun createReceiveOutputSink(folder: ReceiveFolder): ReceiveOutputSinkV2? = null

	override suspend fun sharePickedFiles(
		repository: CoreGateway,
		files: List<PickedShareFile>,
		transferName: String,
		senderName: String,
		accessPolicy: ShareAccessPolicy,
	): Result<Share> {
		require(files.isNotEmpty()) { "Select at least one file to share" }
		val sources = files.map { file ->
			uniffi.vnidrop.ShareSource(
				kind = uniffi.vnidrop.SourceKind.PATH,
				value = file.value,
				displayName = file.displayName,
				isDirectory = file.isDirectory || File(file.value).isDirectory,
			)
		}
		return repository.shareSources(sources, transferName, senderName, accessPolicy)
	}
}
