package com.test.basd.onecleanmaster.helps

import android.os.Environment
import android.provider.MediaStore
import android.text.TextUtils
import com.blankj.utilcode.util.FileUtils
import com.test.basd.onecleanmaster.bean.FileBean
import com.test.basd.onecleanmaster.bean.ImageDataBean
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.text.SimpleDateFormat
import java.util.Locale
import kotlin.random.Random

object FileHelps {
    var usedSize = 0L //已经用的
    var freeSize = 0L //剩余大小
    var systemSize = 0L //系统占用
    var allSize = 0L //所有大小

    init {
        val root = Environment.getExternalStorageDirectory()
        freeSize = FileUtils.getFsAvailableSize(root.absolutePath)
        allSize = FileUtils.getFsTotalSize(root.absolutePath)
        usedSize = allSize - freeSize
        systemSize = FileUtils.getFsTotalSize(Environment.getRootDirectory().absolutePath)
    }

    private val dateFormat by lazy {
        SimpleDateFormat("MMMM dd,yyyy", Locale.getDefault())
    }
    val fileList = mutableListOf<FileBean>()

    private fun initFileList() {
        if (fileList.isEmpty()) {
            initFileList(Environment.getExternalStorageDirectory())
        }
    }


    fun deleteFile(fileOrDirectory: File): Boolean {
        if (fileOrDirectory.isDirectory)
            fileOrDirectory.listFiles()?.forEach { child -> deleteFile(child) }

        return fileOrDirectory.delete()
    }

    fun getFileList(onUpdate: () -> Unit, onEnd: (() -> Unit)? = null) {
        MainScope().launch(Dispatchers.Main) {
            launch(Dispatchers.IO) {
                initFileList()
            }
            var emptyCount = 0
            var preSize = 0
            while (emptyCount < 12) {
                delay(Random.nextLong(400, 800))
                if (fileList.isNotEmpty()) {
                    if (fileList.size - preSize == 0) {
                        emptyCount++
                    } else {
                        emptyCount = 0
                        onUpdate()
                    }
                    preSize = fileList.size
                }

            }
            onEnd?.invoke()
        }
    }

    private fun initFileList(file: File) {
        if (file.isFile) {
            fileList.add(file.toBean())
        } else {
            file.listFiles()?.let {
                if (it.isEmpty()) {
                    fileList.add(file.toBean())
                } else {
                    for (i in it) {
                        initFileList(i)
                    }
                }
            }
        }
    }

    fun File.toBean() = FileBean(
        name = name,
        path = absolutePath,
        size = length(),
        isDir = isDirectory,
        type = if (TextUtils.isEmpty(
                FileUtils.getFileExtension(name).lowercase()
            )
        ) "unKnow" else FileUtils.getFileExtension(name).lowercase(),
        time = lastModified()
    )

    val similarImageList = mutableListOf<ImageDataBean>()
    fun getImageFiles(callback: () -> Unit) {
        MainScope().launch(Dispatchers.Main) {
            withContext(Dispatchers.IO) {
                val imageList = mutableListOf<String>()
                val query = BaseApplication.context.contentResolver.query(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    arrayOf(MediaStore.Files.FileColumns.DATA),
                    null,
                    null,
                    "${MediaStore.Files.FileColumns.DATE_MODIFIED} DESC"
                ) ?: return@withContext
                while (query.moveToNext()) {
                    imageList.add(query.getString(0))
                }
                query.close()
                val imageDataList = mutableListOf<ImageDataBean>()
                imageDataList.addAll(imageList.mapNotNull { ImageHelper.createImage(it) })
                imageDataList.sortBy { it.hashCode }

                similarImageList.clear()
                var index1 = 0
                var index2 = 1
                val similarItem = mutableListOf<ImageDataBean>()
                while (index2 < imageDataList.size) {
                    val first = imageDataList[index1]
                    val second = imageDataList[index2]
                    if (ImageHelper.similarCondition(first, second)) {
                        if (similarItem.indexOf(first) < 0) {
                            similarItem.add(first)
                        }
                        if (similarItem.indexOf(second) < 0) {
                            similarItem.add(second)
                        }
                    } else {
                        if (similarItem.size > 1) {
                            similarImageList.addAll(similarItem)
                        }
                        similarItem.clear()
                    }
                    index1++
                    index2++
                }
                if (similarItem.size > 1) {
                    similarImageList.addAll(similarItem)
                }
            }
            callback()
        }
    }




    val typeDateList = mutableListOf<Pair<String, MutableList<FileBean>>>()
    fun getTypeFiles(callback: () -> Unit) {
        MainScope().launch(Dispatchers.Main) {
            withContext(Dispatchers.IO) {
                val typeFiles = mutableListOf<String>()
                val query = BaseApplication.context.contentResolver.query(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    arrayOf(MediaStore.Files.FileColumns.DATA),
                    null,
                    null,
                    "${MediaStore.Files.FileColumns.DATE_MODIFIED} DESC"
                ) ?: return@withContext
                while (query.moveToNext()) {
                    typeFiles.add(query.getString(0))
                }
                query.close()
                typeDateList.clear()
                typeFiles.forEach {
                    val fileBean = File(it).toBean()
                    val dateString = dateFormat.format(fileBean.time)
                    if (typeDateList.lastOrNull()?.first != dateString) {
                        typeDateList.add(Pair(dateString, mutableListOf()))
                    }
                    typeDateList.lastOrNull()?.second?.add(fileBean)
                }
                callback()
            }
        }

    }
}