package org.wntr.mdeditor

import android.annotation.SuppressLint
import android.content.Context
import android.net.Uri
import android.provider.OpenableColumns
import android.util.Log
import android.widget.Toast
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream

var thisFileUri: Uri? = null
var metaData = mdMeta()

fun checkURIResource(context: Context, uri: Uri?): Boolean {
    val cursor = context.contentResolver.query(uri!!, null, null, null, null)
    val doesExist = cursor != null && cursor.moveToFirst()
    cursor?.close()
    return doesExist
}

fun createFileFromStream(ins: InputStream, destination: File?) {
    try {
        FileOutputStream(destination).use { os ->
            val buffer = ByteArray(4096)
            var length: Int
            while (ins.read(buffer).also { length = it } > 0) {
                os.write(buffer, 0, length)
            }
            os.flush()
        }
    } catch (ex: java.lang.Exception) {
        Log.e("Save img tmp file", ex.message!!)
        ex.printStackTrace()
    }
}

fun createHtmlFile(context: Context, htmlString: String): File? {
    val TAG="share HTML"
    lateinit var htmlFile : File

    try {
        val storageDir = File(context.cacheDir, "html")
        storageDir.mkdir()
        htmlFile = File(storageDir.path + "/${getDisplayName(context,thisFileUri)
            .split(".")[0]}.html")
        if (htmlFile.exists()) htmlFile.delete()
        htmlFile.createNewFile()
    } catch (e: Exception) {
        Log.d(TAG, "Problem with accessing file\n${e.stackTraceToString()}")
        Toast.makeText(
            context,
            "Problem with accessing file\n$e",
            Toast.LENGTH_LONG
        ).show()
        return null
    }

    try {
        FileOutputStream(htmlFile).use {
            it.write(htmlString.toByteArray())
        }

    } catch (e: Exception) {
        Toast.makeText(
            context,
            "Error during writing.\n$e",
            Toast.LENGTH_LONG
        ).show()
        return null
    }
    Log.d(TAG, "File saved: ${htmlFile.toURI()}")
    Toast.makeText(
        context,
        "HTML output produced.",
        Toast.LENGTH_LONG
    ).show()

    return htmlFile
}

fun deleteCache(context: Context) {
    try {
        val dir = File(context.cacheDir, "html")
        deleteDir(dir)
        deleteDir(context.filesDir)
    } catch (e: java.lang.Exception) {
        e.printStackTrace()
    }
}

fun deleteDir(dir: File?): Boolean {
    return if (dir != null && dir.isDirectory) {
        val children = dir.list()
        for (i in children.indices) {
            val success = deleteDir(File(dir, children[i]))
            if (!success) {
                return false
            }
        }
        dir.delete()
    } else if (dir != null && dir.isFile) {
        dir.delete()
    } else {
        false
    }
}

@SuppressLint("Range")
fun getDisplayName(context: Context, uri: Uri?): String {
    //  via: https://stackoverflow.com/questions/5568874/how-to-extract-the-file-name-from-uri-returned-from-intent-action-get-content
    var result: String? = null;
    if (uri == null) return "hauntED.md"
    if (uri!!.getScheme().equals("content")) {
        val cursor = context.getContentResolver().query(uri!!, null, null, null, null);
        try {
            if (cursor != null && cursor.moveToFirst()) {
                result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
            }
        } finally {
            cursor?.close();
        }
    }
    if (result == null) {
        result = uri!!.getPath();
        val cut = result!!.lastIndexOf('/');
        if (cut != -1) {
            result = result.substring(cut + 1);
        }
    }
    return result;
}

@Throws(IOException::class)
fun getFile(context: Context, uri: Uri): File? {
    val destinationFilename =
        File(context.filesDir.path + File.separatorChar + queryName(context, uri))
    try {
        context.contentResolver.openInputStream(uri!!).use { ins ->
            createFileFromStream(
                ins!!,
                destinationFilename
            )
        }
    } catch (ex: java.lang.Exception) {
        Log.e("Save File", ex.message!!)
        ex.printStackTrace()
    }
    return destinationFilename
}

fun queryName(context: Context, uri: Uri): String? {
    val returnCursor = context.contentResolver.query(uri, null, null, null, null)!!
    val nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
    returnCursor.moveToFirst()
    val name = returnCursor.getString(nameIndex)
    returnCursor.close()
    return name
}

fun saveMetaToSharedPrefs(context: Context) {
    if (thisFileUri == null) return
    Log.d("saveMetaToSharedPrefs", "saving to shared prefs cursor: ${metaData.cursor} in file: ${thisFileUri}")
    context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
        .edit().apply {
            putString("lastFile", thisFileUri.toString())
            putString("cursor", metaData.cursor)
            apply()
        }
}

fun loadMetaFromSharedPrefs(context: Context): Boolean{
    val prefs = context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
    val uriString = prefs.getString("lastFile", "noLastFile")

    if (uriString == "noLastFile") {
        Log.i("loadMetaFromSharedPrefs","No lastfile saved")
        return false
    } else {
        thisFileUri = Uri.parse(uriString)
        metaData.cursor = prefs.getString("cursor", "nocursor") ?: "{ line: 0, ch: 0, sticky: null }"
        Log.i("loadMetaFromSharedPrefs","Loaded cursor: ${metaData.cursor}")
        return true
    }
}
