// Copyright (C) 2026 Jason M. Schwefel. All Rights Reserved.
package com.coldboreballisticsllc.scopedope.domain.usecase

import android.content.ContentValues
import android.content.Context
import android.graphics.Bitmap
import android.net.Uri
import android.provider.MediaStore
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import javax.inject.Inject

class SavePngUseCase @Inject constructor(
    @ApplicationContext private val context: Context,
) {
    /**
     * Saves [bitmap] as a PNG in Pictures/ScopeDOPE on the device's primary
     * external storage.  Returns the [Uri] of the saved file on success.
     *
     * Caller must hold WRITE_EXTERNAL_STORAGE (API < 29) or have
     * READ_MEDIA_IMAGES (API 33+); on API 29–32 no permission is required.
     */
    suspend fun invoke(bitmap: Bitmap, filenameStem: String = "scopedope"): Result<Uri> =
        withContext(Dispatchers.IO) {
            runCatching {
                val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date())
                val displayName = "${filenameStem}_$timestamp.png"

                val values = ContentValues().apply {
                    put(MediaStore.Images.Media.DISPLAY_NAME, displayName)
                    put(MediaStore.Images.Media.MIME_TYPE,    "image/png")
                    put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/ScopeDOPE")
                    put(MediaStore.Images.Media.IS_PENDING,   1)
                }

                val resolver = context.contentResolver
                val collectionUri = MediaStore.Images.Media.getContentUri(
                    MediaStore.VOLUME_EXTERNAL_PRIMARY
                )

                val itemUri = resolver.insert(collectionUri, values)
                    ?: throw IOException("MediaStore insert returned null")

                try {
                    resolver.openOutputStream(itemUri)?.use { out ->
                        if (!bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)) {
                            throw IOException("Bitmap.compress failed")
                        }
                    } ?: throw IOException("Could not open output stream for $itemUri")

                    values.clear()
                    values.put(MediaStore.Images.Media.IS_PENDING, 0)
                    resolver.update(itemUri, values, null, null)
                } catch (e: Exception) {
                    // Remove the pending entry so a ghost file is not left in the gallery.
                    resolver.delete(itemUri, null, null)
                    throw e
                }

                itemUri
            }
        }
}
