package com.ux.video.file.filerecovery.utils

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.icu.text.SimpleDateFormat
import android.icu.util.Calendar
import android.media.MediaMetadataRetriever
import android.os.Environment
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.webkit.MimeTypeMap
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import com.ux.video.file.filerecovery.R
import com.ux.video.file.filerecovery.db.ResultDataFiles
import com.ux.video.file.filerecovery.utils.ScanManager.getVideoResolution
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.util.Date
import java.util.Locale

object Common {

    val itemSpacing = 10
    val horizontalSpacing = 16

    val KEY_SCAN_TYPE = "key_scan_type"
    val KEY_FILE_TYPE = "key_file_type"




    val rootDir = Environment.getExternalStorageDirectory()
    val dateFormat = SimpleDateFormat("MMMM d,yyyy", Locale.ENGLISH)
    val chineseFormat = SimpleDateFormat("yyyy-MM-dd", Locale.CHINESE)
    val itemDateFormat = SimpleDateFormat("MM-dd", Locale.CHINESE)
    val recoveryPhotoDir = "MyAllRecovery/Photo"

    /**
     * 默认按照日期分类，将最新的排前面 降序
     */
    fun getSortByDayNewToOldInit(list: List<ResultDataFiles>): List<Pair<String, List<ResultDataFiles>>> {
        val grouped = list.groupBy {
            dateFormat.format(Date(it.lastModified))
        }
        val parentData: List<Pair<String, List<ResultDataFiles>>> = grouped
            .map { it.key to it.value }
            .sortedByDescending { dateFormat.parse(it.first)?.time ?: 0L }
        return parentData
    }

    fun getSortByDayNewToOld(
        list: List<Pair<String, List<ResultDataFiles>>>
    ): List<Pair<String, List<ResultDataFiles>>> {
        return list.sortedByDescending { pair ->
            dateFormat.parse(pair.first)?.time ?: 0L
        }
    }


    /**
     * 按照日期排序， 时间最早的排前面 升序
     *
     */
    fun getSortByDayOldToNew(list: List<Pair<String, List<ResultDataFiles>>>) =
        list.sortedBy { dateFormat.parse(it.first)?.time ?: 0L }

    /**
     *  按照文件大小排序，将最大的排前面 降序
     */
    fun getSortBySizeBigToSmall(list: List<ResultDataFiles>) = list.sortedByDescending {
        it.size
    }

    /**
     *  按照文件大小排序，将最小的排前面 升序
     */
    fun getSortBySizeSmallToBig(list: List<ResultDataFiles>) = list.sortedBy {
        it.size
    }


    fun searchByName(
        data: List<Pair<String, List<ResultDataFiles>>>,
        keyword: String
    ): List<Pair<String, List<ResultDataFiles>>> {
        if (keyword.isBlank()) return data

        return data.mapNotNull { (key, files) ->
            val filtered = files.filter { it.name.contains(keyword, ignoreCase = true) }
            if (filtered.isNotEmpty()) key to filtered else null
        }
    }

    fun searchByNameList(
        list: List<ResultDataFiles>,
        keyword: String
    ): List<ResultDataFiles> {
        if (keyword.isBlank()) return list
        return list.filter { it.name.contains(keyword, ignoreCase = true) }
    }


    /**
     * 格式化文件大小显示
     */
    fun formatFileSize(context: Context, size: Long): String {
        if (size < 1024) {
            return "$size B"
        }

        val kb = size / 1024.0
        if (kb < 1024) {
            return String.format(Locale.CHINA, context.getString(R.string.size_kb), kb)
        }

        val mb = kb / 1024.0
        if (mb < 1024) {
            return String.format(Locale.CHINA, context.getString(R.string.size_mb), mb)
        }

        val gb = mb / 1024.0
        return String.format(Locale.CHINA, context.getString(R.string.size_gb), gb)
    }


    /**
     *
     * @param months  筛选months月之内的数据
     */
    fun filterWithinOneMonthByDay(
        grouped: List<Pair<String, List<ResultDataFiles>>>, months: Int
    ): List<Pair<String, List<ResultDataFiles>>> {
        val today = Calendar.getInstance()
        val oneMonthAgo = Calendar.getInstance().apply {
            add(Calendar.MONTH, -months) // 1 个月前
        }

        return grouped.filter { (dayStr, _) ->
            val day = dateFormat.parse(dayStr)
            day != null && !day.before(oneMonthAgo.time) && !day.after(today.time)
        }
    }

    /**
     * @param months  筛选months月之内的数据
     */
    fun filterWithinOneMonth(list: List<ResultDataFiles>, months: Int): List<ResultDataFiles> {
        val today = Calendar.getInstance()
        val oneMonthAgo = Calendar.getInstance().apply {
            add(Calendar.MONTH, -months)
        }

        return list.filter {
            val cal = Calendar.getInstance().apply { timeInMillis = it.lastModified }
            !cal.before(oneMonthAgo) && !cal.after(today)
        }
    }

    /**
     *  设置全部子View的选中
     */

    fun setItemSelect(view: View, selected: Boolean) {
        view.isSelected = selected
        if (view is ViewGroup) {
            for (i in 0 until view.childCount) {
                val child = view.getChildAt(i)
                setItemSelect(child, selected)
            }
        }
    }


    /**
     * @param list  筛选后的显示的数据
     * @param selected  实际选中的数据集合
     * @return 显示的选中数量和选中集合
     */
    fun checkSelectListContainDate(
        list: List<Pair<String, List<ResultDataFiles>>>,
        selected: Set<ResultDataFiles>
    ): Pair<Int, MutableSet<ResultDataFiles>> {
        val currentSelected = mutableSetOf<ResultDataFiles>()

        val totalSelectedCount = list.sumOf { pair ->
            pair.second.count {
                val isSelected = it in selected
                if (isSelected) currentSelected.add(it)
                isSelected
            }
        }

        showLog("-------totalSelectedCount = $totalSelectedCount   currentSelected=${currentSelected.size}")
        return totalSelectedCount to currentSelected
    }

    suspend fun checkSelectListContainDateAsync(
        list: List<Pair<String, List<ResultDataFiles>>>,
        selected: Set<ResultDataFiles>
    ): Pair<Int, MutableSet<ResultDataFiles>> = withContext(Dispatchers.Default) {
        val currentSelected = mutableSetOf<ResultDataFiles>()
        var totalSelectedCount = 0

        // 高效遍历外层 + 内层列表
        for (pair in list) {
            for (file in pair.second) {
                if (file in selected) {
                    totalSelectedCount++
                    currentSelected.add(file)
                }
            }
        }

        totalSelectedCount to currentSelected
    }


//    fun checkSelectListContainSize(
//        list: List<ResultPhotosFiles>,
//        selected: Set<String>
//    ): Pair<Int, MutableSet<String>> {
//        val currentSelected = mutableSetOf<String>()
//        val totalSelectedCount = list.count {
//            val isSelected = it.path in selected
//            if (isSelected) currentSelected.add(it.path.toString())
//            isSelected
//        }
//        showLog("-------totalSelectedCount 222=${totalSelectedCount}")
//        return totalSelectedCount to currentSelected
//    }


    suspend fun checkSelectListContainSize(
        list: List<ResultDataFiles>,
        selected: Set<ResultDataFiles>
    ): Pair<Int, MutableSet<ResultDataFiles>> = withContext(Dispatchers.Default) {
        val currentSelected = mutableSetOf<ResultDataFiles>()
        var totalSelectedCount = 0

        // 高效遍历外层 + 内层列表
        for (pair in list) {
            if (pair in selected) {
                totalSelectedCount++
                currentSelected.add(pair)
            }
        }
        totalSelectedCount to currentSelected
    }





    fun removeSelectedFromList(
        list: List<Pair<String, List<ResultDataFiles>>>,
        selectedLiveData: Set<ResultDataFiles>
    ): List<Pair<String, List<ResultDataFiles>>> {
        return list.mapNotNull { (key, files) ->
            val filtered = files.filterNot { it in selectedLiveData }
            if (filtered.isNotEmpty()) key to filtered else null
        }
    }

    fun removeSelectedFromSizeList(
        list: List<ResultDataFiles>,
        selectedLiveData: Set<ResultDataFiles>
    ): List<ResultDataFiles> {
        return list.filterNot { it in selectedLiveData }
    }


    fun getMediaDuration(filePath: String): Long {
        val retriever = MediaMetadataRetriever()
        return try {
            retriever.setDataSource(filePath)
            val durationStr =
                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
            durationStr?.toLongOrNull() ?: 0L // 单位：毫秒
        } catch (e: Exception) {
            e.printStackTrace()
            0L
        } finally {
            retriever.release()
        }
    }


    @SuppressLint("DefaultLocale")
    fun formatDuration(ms: Long): String {
        val totalSeconds = ms / 1000
        val hours = totalSeconds / 3600
        val minutes = (totalSeconds % 3600) / 60
        val seconds = totalSeconds % 60

        return if (hours > 0) {
            String.format("%02d:%02d:%02d", hours, minutes, seconds)
        } else {
            String.format("%02d:%02d", minutes, seconds)
        }
    }

    fun getFileMIME(file: File): String {
        val ext = file.extension.lowercase()
        val mimeTypeFromExtension = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext)

        val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext) ?: return "unknown"
        return mime
        return when {
            mime.startsWith("image/") -> "image"
            mime.startsWith("video/") -> "video"
            mime.startsWith("audio/") -> "audio"
            mime.startsWith("text/") -> "document"
            mime == "application/pdf" -> "document"
            mime.startsWith("application/vnd.openxmlformats") -> "document"
            mime.startsWith("application/ms") -> "document"
            mime == "application/zip" ||
                    mime == "application/x-rar-compressed" ||
                    mime == "application/x-7z-compressed" -> "archive"

            else -> "other"
        }
    }

    val customMimeMap = mapOf(
        "xapk" to "application/zip",
        // 可以继续添加其他自定义扩展名
    )

    fun getMimeTypeParts(file: File): String {
        val extension = file.extension.lowercase()
        val mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
            ?: customMimeMap[extension]
        showLog("-----------ext=$extension  mimeType=${mimeType}")
        return if (mimeType != null && mimeType.contains("/")) {
            val parts = mimeType.split("/")
            val mainType = parts[0]
            val subType = parts.getOrNull(1)
            "$mainType/$subType"
        } else {
            "unknown"
        }

    }

    fun getFileIconRes(file: File): Int {
        val ext = file.extension.lowercase()

        return when (ext) {
            "doc", "docx" -> R.drawable.icon_doc
            "xls", "xlsx" -> R.drawable.icon_xls
            "ppt", "pptx" -> R.drawable.icon_ppt
            "pdf" -> R.drawable.icon_pdf
            "txt" -> R.drawable.icon_txt
            "apk", "xapk" -> R.drawable.icon_apk
            else -> R.drawable.icon_unknow
        }
    }

    fun getFormatDate(time: Long): String {
        return dateFormat.format(Date(time))
    }

    fun getItemMonthDay(time: Long): String {
        return itemDateFormat.format(time)
    }

    fun getChineseFormatDate(date: Date): String {
        return chineseFormat.format(date)
    }

    fun getDateFromFormat(dateStr: String): Date? {
        return chineseFormat.parse(dateStr)

    }

    fun getColorInt(context: Context, colorId: Int): Int {
        return ContextCompat.getColor(context, colorId)
    }

    fun showLog(msg: String) {
        Log.d("============", msg)
    }


    fun shareSingleFile(context: Context, file: File, fileType: FileType) {
        val uri = FileProvider.getUriForFile(
            context,
            "${context.packageName}.fileprovider", // 与 Manifest 保持一致
            file
        )

        val intent = Intent(Intent.ACTION_SEND).apply {
            type = getMediaFileStr(fileType)
            putExtra(Intent.EXTRA_STREAM, uri)
            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        }
        context.startActivity(Intent.createChooser(intent, "分享文件"))
    }

    fun shareMultipleFiles(context: Context, files: List<File>, fileType: FileType) {
        val uris = files.map {
            FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", it)
        }

        val intent = Intent(Intent.ACTION_SEND_MULTIPLE).apply {
            type = getMediaFileStr(fileType)
            putParcelableArrayListExtra(Intent.EXTRA_STREAM, ArrayList(uris))
            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        }

        context.startActivity(Intent.createChooser(intent, "分享多个文件"))
    }

    fun getResolution(type: FileType, file: File): String {
        return when (type) {
            FileType.PHOTO -> {
                getImageSize(file).run {
                    "$first*$second"
                }
            }

            FileType.VIDEO -> getVideoResolution(file.path).run {
                "$first*$second"
            }

            else -> ""
        }
    }

    private fun getMediaFileStr(fileType: FileType): String {
        return when (fileType) {
            FileType.PHOTO -> "image/*"
            FileType.VIDEO -> "video/*"
            FileType.AUDIO -> "audio/*"
            FileType.DOCUMENT -> "application/*"
        }
    }

    private fun getImageSize(file: File): Pair<Int, Int> {
        val options = BitmapFactory.Options()
        options.inJustDecodeBounds = true
        BitmapFactory.decodeFile(file.absolutePath, options)
        val width = options.outWidth
        val height = options.outHeight
        return Pair(width, height)
    }

    fun shareApp(context: Context) {
        val appPackageName = context.packageName
        val shareIntent = Intent(Intent.ACTION_SEND).apply {
            type = "text/plain"
            putExtra(
                Intent.EXTRA_TEXT,
                "I recommend a useful app：\nhttps://play.google.com/store/apps/details?id=$appPackageName"
            )
        }
        context.startActivity(
            Intent.createChooser(shareIntent, "分享应用")
        )
    }

    fun getScanType(scanType: ScanType) {
        when (scanType) {
            ScanType.ALL_PHOTO -> {}
            ScanType.DELETED_PHOTO -> {}
            ScanType.ALL_VIDEO -> {}
            ScanType.DELETED_VIDEO -> {}
            ScanType.ALL_AUDIO -> {}
            ScanType.DELETED_AUDIO -> {}
            ScanType.ALL_DOCUMENT -> {}
            ScanType.DELETED_DOCUMENT -> {}

        }

    }
    fun switchFileType(fileType: FileType,onPhoto:()-> Unit,onVideo:()-> Unit,onAudio:()-> Unit,onDocument:()-> Unit){
        when (fileType) {
            FileType.PHOTO -> {onPhoto()}
            FileType.VIDEO -> {onVideo()}
            FileType.AUDIO -> {onAudio()}
            FileType.DOCUMENT -> {onDocument()}
        }
    }

    fun getScanType1(scanType: ScanType) {
        when (scanType) {
            ScanType.ALL_PHOTO, ScanType.DELETED_PHOTO -> {}
            ScanType.ALL_VIDEO, ScanType.DELETED_VIDEO -> {}
            ScanType.ALL_AUDIO, ScanType.DELETED_AUDIO -> {}
            ScanType.ALL_DOCUMENT, ScanType.DELETED_DOCUMENT -> {}
        }

    }


}