package com.zxhy.fastfilemanagerpro

import android.content.Context
import android.os.Environment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.zxhy.fastfilemanagerpro.kokodata.KoFileDatako
import com.zxhy.fastfilemanagerpro.kokodata.KoFileDatako.Companion.koFileDatako
import com.zxhy.fastfilemanagerpro.kokotools.HelperTraverse
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import java.io.File
import java.util.Stack
import kotlin.reflect.KFunction1

abstract class CommonViewModel : ViewModel() {

    /**
     * 只删除文件列表
     */
    fun deleteFiles(files: List<File>, finishAction: () -> Unit) =
        viewModelScope.launch(Dispatchers.IO) {
            runCatching {
                files.forEach {
                    if (it.exists()) {
                        it.delete()
                    }
                }
            }
            finishAction.invoke()
        }

    fun deleteFileOrDir(files: List<File>, finishAction: () -> Unit) =
        viewModelScope.launch(Dispatchers.IO) {
            runCatching {
                files.forEach {
                    if (it.exists()) {
                        if (it.isFile) it.delete() else deleteDirectory(it)
                    }
                }
            }
            finishAction.invoke()
        }

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

            if (subFiles != null) {
                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
    }

    /**
     * 复制文件夹
     * @param source 原文件夹
     * @param target 目标文件夹
     */
    fun copyDirectory(source: File, target: File) {
        try {
            if (source.isDirectory) {
                if (!target.exists()) target.mkdir()

                source.list()?.map { sub ->
                    copyDirectory(File(source, sub), File(target, sub))
                }
            } else {
                source.copyTo(target, overwrite = true)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    fun loadFile(
        context: Context,
        filter: (file: File) -> Boolean,
        onDo: (list: List<KoFileDatako>) -> Unit,
        onFinish: (list: List<KoFileDatako>) -> Unit
    ) {

        viewModelScope.launch(Dispatchers.IO) {
            val root = Environment.getExternalStorageDirectory()
            val resultList = arrayListOf<KoFileDatako>()
            var firstSend = false

            HelperTraverse.linkedLisTraverseFolder(root) { file ->
                if (filter(file)) {
                    resultList.add(file.koFileDatako(context))
                    if (resultList.size == 20 && !firstSend) {
                        onDo.invoke(resultList)
                        resultList.clear()
                        firstSend = true
                    }
                }
            }
            onFinish.invoke(resultList)
        }

    }

    fun loadAllFile(
        context: Context,
        filter: (file: File) -> Boolean,
        onFinish: (list: List<KoFileDatako>) -> Unit
    ) {

        viewModelScope.launch(Dispatchers.IO) {
            val root = Environment.getExternalStorageDirectory()
            val resultList = arrayListOf<KoFileDatako>()

            HelperTraverse.linkedLisTraverseFolder(root) { file ->
                if (filter(file)) {
                    resultList.add(file.koFileDatako(context))
                }
            }
            onFinish.invoke(resultList)
        }

    }
}