package com.zxhy.hfilemanagermaster.knife

import android.content.Context
import android.os.Environment
import android.util.Log
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.data.file2MediaDataC
import java.io.File
import java.util.LinkedList
import java.util.Stack


fun traverseFolder(folder: File): ArrayList<File> {
    val fileList = arrayListOf<File>()
    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            fileList.addAll(traverseFolder(it))
        } else {
            fileList.add(it)
        }
    }
    return fileList
}

fun traverseLargeFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseLargeFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if (it.length() >= 10 * 1024 * 1024L) {
                onDo?.invoke(it)
            }
        }
    }
}

fun traverseLargeImage(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseLargeImage(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if (it.name.contains(".jpg") && it.length() >= 10 * 1024 * 1024L) {
                onDo?.invoke(it)
            }
        }
    }
}

fun traverseLargeVideo(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseLargeVideo(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if (it.name.contains(".mp4") && it.length() >= 10 * 1024 * 1024L) {
                onDo?.invoke(it)
            }
        }
    }
}


fun traverseEmptyFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseEmptyFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if (it.length() == 0L) {
                onDo?.invoke(it)
            }
        }
    }
}


fun traverseImageFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseImageFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if ((it.name.contains(".jpg")) or (it.name.contains(".png"))) {
                onDo?.invoke(it)
            }
        }
    }
}

fun traverseVideoFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseVideoFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if ((it.name.contains(".mp4")) or (it.name.contains(".av"))) {
                onDo?.invoke(it)
            }
        }
    }
}

fun traverseWordFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseWordFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if (it.name.contains(".txt")) {
                onDo?.invoke(it)
            }
        }
    }
}

fun traverseExcelFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseExcelFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if ((it.name.contains(".xls")) or (it.name.contains(".xlsx"))) {
                onDo?.invoke(it)
            }
        }
    }
}

fun traversePdfFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traversePdfFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if (it.name.contains(".pdf")) {
                onDo?.invoke(it)
            }
        }
    }
}

fun traversePptFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traversePptFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if ((it.name.contains(".ppt")) or (it.name.contains(".pptx"))) {
                onDo?.invoke(it)
            }
        }
    }
}

fun traverseAudioFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseAudioFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if (
                (it.name.contains(".mp3")) or
                (it.name.contains(".wav")) or
                (it.name.contains(".flac"))
            ) {
                onDo?.invoke(it)
            }
        }
    }
}

fun traverseApkFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseApkFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if ((it.name.contains(".apk"))) {
                onDo?.invoke(it)
            }
        }
    }
}

fun traverseZipFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseZipFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if ((it.name.contains(".zip"))) {
                onDo?.invoke(it)
            }
        }
    }
}

fun traverseLogFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseLogFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if ((it.name.contains("log"))) {
                onDo?.invoke(it)
            }
        }
    }
}

fun traverseDocumentFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {

    folder.listFiles()?.forEach {
        if (it.isDirectory) {
            traverseDocumentFolder(it) { file ->
                onDo?.invoke(file)
            }
        } else {
            if (
                (it.name.contains(".txt")) or
                (it.name.contains(".xls")) or
                (it.name.contains(".xlsx")) or
                (it.name.contains(".xlsx")) or
                (it.name.contains(".pdf")) or
                (it.name.contains(".ppt")) or
                (it.name.contains(".pptx"))
            ) {
                onDo?.invoke(it)
            }
        }
    }
}

//删除文件夹
fun deleteDirectory(dir: File): Boolean {
    val stackFiles = Stack<File>()
    stackFiles.push(dir)
    while (stackFiles.size > 0) {
        val currentFile = stackFiles.peek()
        val subFiles = currentFile.listFiles()

        for (i in subFiles!!.indices) {
            if (subFiles[i].isFile) {
                if (!subFiles[i].delete()) {
                    return false
                }
            } else {
                stackFiles.push(subFiles[i])
            }
        }
        if (currentFile === stackFiles.peek()) {
            if (!currentFile.delete()) {
                return false
            }
            stackFiles.pop()
        }
    }
    return true
}

fun largeFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {

    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseLargeFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun largeImage(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {

    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseLargeImage(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun largeVideo(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {

    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseLargeVideo(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun emptyFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {

    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseEmptyFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun imageFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {

    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseImageFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun videoFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {

    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseVideoFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun wordFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {

    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseWordFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun excelFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {
    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseExcelFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun pdfFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {
    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traversePdfFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun pptFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {
    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traversePptFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun audioFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {
    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseAudioFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun apkFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {
    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseApkFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun zipFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {
    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseZipFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun logFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {
    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseLogFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun documentFile(
    context: Context,
    onDoAction: (list: List<MediaDataC>) -> Unit,
    finishAction: (() -> Unit)? = null
) {
    try {
        Thread {
            val root = Environment.getExternalStorageDirectory()
            val tempList = arrayListOf<File>()

            traverseDocumentFolder(root) {
                tempList.add(it)
                if (tempList.size == 5) {
                    onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
                    tempList.clear()
                }
            }
            onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
            finishAction?.invoke()
        }.start()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}