package mg.dot.feufaro

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Environment
import android.widget.Toast
import androidx.core.content.FileProvider
import feufaro.composeapp.generated.resources.Res
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream

class AndroidFileRepository(private val context: Context) : FileRepository {

    override suspend fun getOutputStream(filePath: String): OutputStream {
        // On utilise getExternalFilesDir pour le debug (accessible via ADB/Vim)
        val folder = context.getExternalFilesDir(null)
        val outputFile = File(folder, filePath)

        // On s'assure que le dossier existe
        outputFile.parentFile?.mkdirs()

        return FileOutputStream(outputFile)
    }

    override suspend fun saveFile(filePath: String, data: ByteArray) {
        val folder = context.getExternalFilesDir(null)
        println("Save to xx27 $folder $filePath")
        File(folder, filePath).writeBytes(data)
    }
    override suspend fun readFileLines(filePath: String): List<String> = withContext(Dispatchers.IO) {
        try {
            when {
                filePath.startsWith("content://") -> {
                    val uri = Uri.parse(filePath)
                    val inputStream = context.contentResolver.openInputStream(uri)
                        ?: throw IOException("Impossible d'ouvrir : $filePath")
                    inputStream.bufferedReader(Charsets.UTF_8).readLines()
                }
                filePath.startsWith("assets://") -> {
                    readAssetFileLines(filePath)
                }

                else -> {
                    val file = File(filePath)
                    println("AndroidRead: Tentative sur ${file.absolutePath}")
                    println("AndroidRead: Existe=${file.exists()} | Lisible=${file.canRead()}")

                    if (!file.exists()) {
                        throw IOException("Le fichier n'existe pas : $filePath")
                    }
                    file.bufferedReader(Charsets.UTF_8).useLines { it.toList() }
                }
            }
        } catch (e: IOException) {
            throw IOException("Failed to read file or asset '$filePath'")
        }
    }
    override suspend fun readFileContent(filePath: String): String = withContext(Dispatchers.IO) {
        val lines = readFileLines(filePath)
        lines.joinToString("\n") { it }
    }
    private suspend fun readAssetFileLines(assetFileName: String): List<String> {
        return try {
            Res.readBytes("files/"+assetFileName.removePrefix("assets://")).decodeToString().split("\n")
        } catch (e: IOException) {
            println("Could not read /"+assetFileName.removePrefix("assets://"))
            throw IOException("Could not read asset file: $assetFileName", e)
        }
    }

    /* Exwternal files */
    override fun getFileName(shortName: String): String {
        val folder = context.getExternalFilesDir(null)
        return "$folder/$shortName"
    }
    /*override suspend fun readFileBytes(filePath: String): ByteArray = withContext(Dispatchers.IO) {
        val folder = context.getExternalFilesDir(null)
        val file = File(folder, filePath)
        if (!file.exists()) throw IOException("File not found: ${file.absolutePath}")
        file.readBytes()
    }*/
    override suspend fun saveLocalFile(filePath: String, data: ByteArray) = withContext(Dispatchers.IO) {
        val file = if (filePath.contains("/") ) {
            File(filePath)
        } else {
            File(getAppPublicFolder(), filePath)
        }

        try {
            file.parentFile?.mkdirs()
            file.writeBytes(data)
            println("Fichier sauvegardé dans : ${file.absolutePath}")

            if (file.extension.lowercase() == "pdf") {
                openPdfFile(context = context, filePath = file.absolutePath)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            throw e
        }
    }
    private fun getAppPublicFolder(): File {
        val publicDocsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
        val appDir = File(publicDocsDir, "Feufaro")
        if (!appDir.exists()) {
            appDir.mkdirs()
        }
        return appDir
    }

    override fun pickSavePath(defaultName: String): String? {
        return File(getAppPublicFolder(), defaultName).absolutePath
    }
    suspend fun openPdfFile(context: Context, filePath: String) {
        val file = File(filePath)
        if (!file.exists()) return

        // 1. Transformer le File en Uri sécurisée
        val uri: Uri = FileProvider.getUriForFile(
            context,
            "mg.dot.feufaro.fileprovider",
            file
        )

        val intent = Intent(Intent.ACTION_VIEW).apply {
            setDataAndType(uri, "application/pdf")
            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        }

        try {
            withContext(Dispatchers.Main) {
                Toast.makeText(context.applicationContext, "Fichier sauvegardé avec succès", Toast.LENGTH_LONG).show()
            }
            context.startActivity(intent)
        } catch (e: Exception) {
            withContext(Dispatchers.Main) {
                Toast.makeText(context.applicationContext, "Aucun lecteur PDF trouvé", Toast.LENGTH_SHORT).show()
            }
        }
    }
}