package com.example.myimagepicker.repository

import android.content.Context
import android.graphics.BitmapFactory
import android.os.Environment
import android.util.Log
import com.example.gengmei_flutter_plugin.utils.MyUtil.Companion.getFileFullName
import com.example.gengmei_flutter_plugin.utils.MyUtil.Companion.getFileName
import com.example.gengmei_flutter_plugin.utils.MyUtil.Companion.getImageCacheDir
import com.example.myimagepicker.bean.MediaFile
import com.example.myimagepicker.bean.MediaFolder
import com.example.myimagepicker.luban.Luban
import com.example.myimagepicker.repository.local.ImageScanner
import io.reactivex.Observable
import io.reactivex.ObservableOnSubscribe
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import java.io.File
import java.util.*
import java.util.concurrent.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap

/**
 * Created by lsy
 * on 2019/3/27
 */
class ImageRespository {

    private val globalThreadPool = ThreadPoolExecutor(0, 15
            , 30, TimeUnit.SECONDS, LinkedBlockingDeque());

    val recordImageListMap = ArrayList<HashMap<String, Any>>()
    var finishOneTask = false
    val fileDir = Environment.getExternalStorageDirectory().absolutePath + "/GMAlbum/.album";


    //: HashMap<String, ArrayList<HashMap<String, Any>>>

    fun scanPhoneImage(context: Context): Observable<HashMap<String, ArrayList<HashMap<String, Any>>>> {
        val file = File(fileDir);
        if (!file.exists()) {
            file.mkdirs();
        }
        if (!recordImageListMap.isEmpty() && finishOneTask) {
            return Observable.just(toMap(context, recordImageListMap))
                    .subscribeOn(Schedulers.computation()).observeOn(AndroidSchedulers.mainThread())
        }
        return Observable.create(ObservableOnSubscribe<HashMap<String, ArrayList<HashMap<String, Any>>>> {
            it.onNext(getFinalMap(context, ImageScanner(context).queryMedia()))
        }).subscribeOn(Schedulers.computation()).observeOn(AndroidSchedulers.mainThread())
    }

    fun savePreviewImg(context: Context, listener: savePreviewListener) {
        val needSize = recordImageListMap.size;
        var currentSize = 0;
        var letSize = 10
        var noPathSize = 0;
        recordImageListMap.forEach {
            val any = it["path"]
            val realPath = it["realPath"] as String
            if (any == null) {
                globalThreadPool.execute {
                    //getImageCacheDir(context, Luban.DEFAULT_DISK_CACHE_DIR)!!.absolutePath
                    val get = Luban.with(context).setTargetDir(fileDir)
                            .setName(getFileName(realPath)!!)
                            .get(realPath);
                    it["path"] = get.absolutePath;
                    synchronized(this) {
                        currentSize++;
                        noPathSize++;
                        Log.e("lsy", "${noPathSize}  ${currentSize}  ${needSize}")
                        if (currentSize == needSize) {
                            //FINISH
                            listener.onSuccess(toMap(context, recordImageListMap))
                        } else {
                            if (noPathSize > letSize) {
                                letSize += 15
                                listener.onSuccess(toMap(context, recordImageListMap))
                            }
                        }
                    }
                }
            } else {
                synchronized(this) {
                    currentSize++;
                    Log.e("lsy", "HAVE PATH ${noPathSize}  ${currentSize}  ${needSize}")
                    if (currentSize == needSize) {
                        //FINISH
                        listener.onSuccess(toMap(context, recordImageListMap))
                    }
                }
            }
        }
    }

    interface savePreviewListener {
        fun onSuccess(data: HashMap<String, ArrayList<HashMap<String, Any>>>)
    }

    // val currentTimeMillis = System.currentTimeMillis();
    //        Thread {
    //            val queryMedia = ImageScanner(context).queryMedia()
    //            val needSize = queryMedia.size
    //            val newList = ArrayList<MediaFile>();
    //            val dir = getImageCacheDir(context, Luban.DEFAULT_DISK_CACHE_DIR)!!.absolutePath;
    //            queryMedia.forEach {
    //                val path = it.realPath!!
    //                val tempFilePngExists = File(dir + "/" + getFileName(path)!! + ".png").exists()
    //                val tempFileJpgExists = File(dir + "/" + getFileName(path)!! + ".jpg").exists();
    //                val tempFileJpegExists = File(dir + "/" + getFileName(path)!! + ".jpeg").exists()
    //
    //                if (it.size > 1024 * 1024 && !tempFilePngExists
    //                        && !tempFileJpgExists && !tempFileJpegExists) {
    //                    globalThreadPool.execute {
    //                        val get = Luban.with(context).setTargetDir(getImageCacheDir(context, Luban.DEFAULT_DISK_CACHE_DIR)!!.absolutePath)
    //                                .setName(getFileName(path)!!)
    //                                .get(path);
    //                        //                Log.e("lsy"," ${getFileFullName(path)!!}");
    //                        it.path = get.absolutePath
    //                        Log.e("lsy", "  ${get.absolutePath} ")
    //                        synchronized(this) {
    //                            newList.add(it);
    //                            Log.e("lsy", " ${newList.size} ${needSize}")
    //                            if (newList.size == needSize) {
    //                                //OKK
    //                                Log.e("lsy", "  TIME  ${System.currentTimeMillis() - currentTimeMillis}")
    //                            }
    //                        }
    //                    }
    //                } else {
    //                    synchronized(this) {
    //                        newList.add(it);
    //                        Log.e("lsy", " ${newList.size} ${needSize}")
    //                        if (newList.size == needSize) {
    //                            //OKK
    //                            Log.e("lsy", "  TIME  ${System.currentTimeMillis() - currentTimeMillis}")
    //                        }
    //                    }
    //                }
    //            }
    //        }.start()

    fun getFinalMap(context: Context, imageList: ArrayList<MediaFile>): HashMap<String, ArrayList<HashMap<String, Any>>> {
        val imageListMap = ArrayList<HashMap<String, Any>>();
        imageList.forEach {
            val itemMap = HashMap<String, Any>()
            it.folderName?.run {
                itemMap.put("folderName", this)
            }
            it.path?.run {
                itemMap.put("path", this)
            }
            it.size?.run {
                itemMap.put("size", this)
            }
            it.realPath?.run {
                itemMap.put("realPath", this)
            }
            imageListMap.add(itemMap)
        }
        synchronized(this) {
            recordImageListMap.clear()
            recordImageListMap.addAll(imageListMap)
            finishOneTask = true
        }
        //            imageList.clear();
        return toMap(context, imageListMap);
    }

    private fun toMap(context: Context, imageListMap: ArrayList<HashMap<String, Any>>): HashMap<String, ArrayList<HashMap<String, Any>>> {
        val finalList = HashMap<String, ArrayList<HashMap<String, Any>>>()
        imageListMap.forEach {
            it["folderName"]?.run {
                if (finalList[this] == null) {
                    finalList[this as String] = ArrayList<HashMap<String, Any>>()
                    if (it["path"] == null) {
                        val realPath = it["realPath"] as String
                        val get = Luban.with(context).setTargetDir(
                                fileDir
//                                getImageCacheDir(context, Luban.DEFAULT_DISK_CACHE_DIR)!!.absolutePath
                        )
                                .setName(getFileName(realPath)!!)
                                .get(realPath);
                        it["path"] = get.absolutePath
                        Log.e("lsy", "封面照片 ${get.absolutePath}");
                    }
                    finalList[this]!!.add(it);
                } else {
                    finalList[this as String]!!.add(it);
                }
            }
        }
        finalList["IsGengmeiAlbumAllImages"] = imageListMap;
        return finalList;
    }


    companion object {
        private var instance: ImageRespository? = null
        const val TAG: String = "Image_Picker"

        fun getInstance(): ImageRespository {
            if (instance == null) {
                synchronized(ImageRespository::class.java) {
                    if (instance == null) {
                        instance = ImageRespository();
                    }
                }
            }
            return instance!!
        }
    }
}