package rallyedto.battleedto.acresedto

import android.content.Context
import android.database.Cursor
import android.media.MediaScannerConnection
import android.net.Uri
import android.provider.MediaStore
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import rallyedto.policeedto.huntedto.FileBean
import rallyedto.talledto.blewedto.Musicaledto
import rallyedto.talledto.blewedto.Sketchedto.getFileExtension
import java.io.File
import java.io.IOException
import java.io.RandomAccessFile
import java.util.LinkedList


object Circulationedto {

    private val TAG = "FileHelp"

    fun CoroutineScope.loadFileByFilter(
        flow1: MutableSharedFlow<String>? = null,
        flow2: MutableSharedFlow<Pair<Int, String>>? = null,
        folder: File,
        filter: (file: File) -> Boolean,
        onDo: ((file: File) -> Unit)? = null,
        onFinish: (() -> Unit)? = null
    ) = launch(Dispatchers.IO) {
        delay(1000)
        var size = 0

        //添加第一层文件到链表
        val linkList = LinkedList<File>()
        val fileList = folder.listFiles()
        fileList?.forEach {
            if (it.isDirectory) {
                linkList.add(it)
            } else {
                val flag = filter(it)
                Musicaledto.logDebug(TAG, "$it flag=$flag")
                if (flag) {
                    onDo?.invoke(it)
                    size++
                    flow2?.emit(Pair(size, it.absolutePath))
                }
                flow1?.emit(it.absolutePath)
            }
        }

        //链表取文件
        var tempFile: File
        while (!linkList.isEmpty()) {
            tempFile = linkList.removeFirst()
            val tempFileList = tempFile.listFiles()
            tempFileList?.forEach {
                if (it.isDirectory) {
                    linkList.add(it)
                } else {
                    val flag = filter(it)
//                    Musicaledto.logDebug(TAG, "$it flag=$flag")
                    if (flag) {
                        onDo?.invoke(it)
                        size++
                        flow2?.emit(Pair(size, it.absolutePath))
                    }
                    flow1?.emit(it.absolutePath)
                }
            }
        }
        onFinish?.invoke()
    }

    fun readFileRange(filePath: String, start: Long, end: Long): ByteArray {
        var data = byteArrayOf()
        try {
            val file = RandomAccessFile(filePath, "r")
            file.seek(start)
            val length = end - start
            data = ByteArray(length.toInt())
            file.readFully(data)
            file.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return data
    }

    fun getDirFiles(
        folder: File,
    ): ArrayList<File> {
        val result = arrayListOf<File>()
        //添加第一层文件到链表
        val linkList = LinkedList<File>()
        folder.listFiles()?.forEach {
            if (it.isDirectory) {
                linkList.add(it)
            } else {
                result.add(it)
            }
        }

        //链表取文件
        var tempFile: File
        while (!linkList.isEmpty()) {
            tempFile = linkList.removeFirst()
            val tempFileList = tempFile.listFiles()
            tempFileList?.forEach {
                if (it.isDirectory) {
                    linkList.add(it)
                } else {
                    result.add(it)
                }
            }
        }
        return result
    }

    fun getFileFolder(file: File): List<File> {

        val set = HashSet<File>()
        //添加第一层文件到链表
        val linkList = LinkedList<File>()
        val fileList = file.listFiles()
        fileList?.forEach {
            if (it.isDirectory) {
                linkList.add(it)
                set.add(it)
            }
        }

        //链表取文件
        var tempFile: File
        while (!linkList.isEmpty()) {
            tempFile = linkList.removeFirst()
            val tempFileList = tempFile.listFiles()
            tempFileList?.forEach {
                if (it.isDirectory) {
                    linkList.add(it)
                    set.add(it)
                }
            }
        }
        return set.toList()
    }
    val fileList = mutableListOf<FileBean>()
    fun getFilesByType(context: Context, onEnd: (() -> Unit)? = null): List<FileBean> {
        fileList.clear()
        var c: Cursor? = null
        try {
            val mContentResolver = context.contentResolver
            c = mContentResolver.query(
                MediaStore.Files.getContentUri("external"),
                null,
                null,
                null,
                null
            )
            val columnIndexOrThrow_DATA =
                c!!.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA)
            val columnIndexOrThrow_SIZE = c.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE)
            while (c.moveToNext()) {
                val path = c.getString(columnIndexOrThrow_DATA)
                val position_do = path.lastIndexOf(".")
                if (position_do == -1) {
                    continue
                }
                val position_x = path.lastIndexOf(File.separator)
                if (position_x == -1) {
                    continue
                }
                val displayName = path.substring(position_x + 1, path.length)
                val size = c.getLong(columnIndexOrThrow_SIZE)
                val file = File(path)
                fileList.add(
                    FileBean(
                        displayName,
                        path,
                        size,
                        false,
                        getFileExtension(displayName),
                        file.lastModified(),
                        false
                    )
                )
            }
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            c?.close()
            onEnd?.invoke()
        }
        return fileList
    }
    fun updateMediaStore(context: Context?, filePath: MutableList<String>) {
        MediaScannerConnection.scanFile(
            context,
            filePath.toTypedArray(),
            null
        ) { path: String?, uri: Uri? -> }
    }
}