package com.tofly.ghrq_route.common.util.file;

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;

import androidx.core.content.FileProvider;

import com.tofly.ghrq_route.R;
import com.tofly.ghrq_route.base.C;
import com.tofly.ghrq_route.module.trouble.domain.TroublePictureBean;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;

import static com.mgq.base.utils.filepath.FilePath.isDownloadsDocument;
import static com.mgq.base.utils.filepath.FilePath.isExternalStorageDocument;
import static com.mgq.base.utils.filepath.FilePath.isMediaDocument;

/**
 * sdCard以及文件的管理工具类
 * Created by zombiexq on 2016/6/15.
 */
public class FileUtil {
    private static String TAG = FileUtil.class.getSimpleName();


    private static double MB = 1024 * 1024;
    private static double FREE_SD_SPACE_NEEDED_TO_CACHE = 10;
    private static double IMAGE_EXPIRE_TIME = 10;

    public static boolean SDState(){
        String state = Environment.getExternalStorageState();
        if (state.equals(Environment.MEDIA_MOUNTED))
            return true;
        else
            return false;
    }

    /**
     * 获取一个随机文件名(包含SDK路径+文件名)
     * @param extension 后缀名 如：.jpg
     * @return
     */
    public static String getFilePathRandom(String extension){
        return tempFileDir()+RandFileName(extension);
    }

    public static String getExtension(String filename){
        if(filename!=null) {
            return filename.substring(filename.lastIndexOf(".") + 1);
        }else
            return "";

    }

    /**
     * 根据所给路径，生成相应的目录
     * @param path
     */
    public static boolean makeDirs(String path){
        boolean bRet = true;
        File dir = new File(path);
        if (!dir.exists()){
            bRet = dir.mkdirs();
        }
        return bRet;
    }

    /**
     * 通过所给的文件名，生成相应的文件
     * @param path
     * @return
     */
    public static boolean createFileByPath(String path){
        boolean bRet = false;
        File filePath = new File(path);
        if(!filePath.exists()){
            try {
                bRet = filePath.createNewFile();
            }catch (IOException e){

            }
        }
        return bRet;
    }

    /**
     * 系统根目录
     * @return
     */
    public static String sdRootDir() {
        File file = null;
        if (SDState()) {
            file = Environment.getExternalStorageDirectory();// 获取SDCard目录
        }else {
            file = new File("/storage/sdcard1");
        }
        if (file != null) {
            return file.getPath();
        }

        return null;
    }

    /**
     * 临时文件路径
     * @return
     */
    public static String tempFileDir() {

        if (SDState()) {
            String dir = C.dir.temp;
            makeDirs(dir);
            return dir;
        } else {
            return null;
        }
    }

    public static boolean fileExists(String filePath){
        File file = new File(filePath);
        return file.exists();
    }

    /**
     * image文件路径
     * @return
     */
    public static String imageFileDir() {

        if (SDState()) {
            String dir = C.dir.images;
            makeDirs(dir);
            return dir;
        } else {
            return null;
        }
    }
    /**
     *  通过时间命名文件
     * @param extension
     * @return
     */
    public static String RandFileName(String extension) {
        // 设置日期格式
        SimpleDateFormat df = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
        return df.format(new Date()) + extension;
    }

    public static Bitmap getImage(String fileName) {
        // check image file exists
        String realFileName = C.dir.images + fileName;
        File file = new File(realFileName);
        if (!file.exists()) {
            return null;
        }
        // get original image
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(realFileName, options);
    }

   /* public static Bitmap getSample(String fileName) {
        // check image file exists
        String realFileName = C.dir.faces + "/" + fileName;
        File file = new File(realFileName);
        if (!file.exists()) {
            return null;
        }
        // get original size
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(realFileName, options);
        int zoom = (int) (options.outHeight / (float) 50);
        if (zoom < 0) zoom = 1;
        // get resized image
        options.inSampleSize = zoom;
        options.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeFile(realFileName, options);
        return bitmap;
    }*/

    public static boolean saveImage(Bitmap bitmap, String fileName, boolean isTemp) {
        return saveImage(bitmap, fileName, isTemp, null);
    }

    public static boolean saveImage(Bitmap bitmap, String fileName, boolean isTemp, String[] outPath) {
        if (bitmap == null) {
            Log.w(TAG, " trying to save null bitmap");
            return false;
        }
        // 判断sdcard上的空间
        if (FREE_SD_SPACE_NEEDED_TO_CACHE > getFreeSpace()) {
            Log.w(TAG, "Low free space onsd, do not cache");
            return false;
        }
        // 不存在则创建目录
        String rootPath = isTemp ? C.dir.temp : C.dir.images;
        File dir = new File(rootPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        // 保存图片
        try {
            String realFileName = rootPath + fileName;
            File file = new File(realFileName);
            file.createNewFile();
            OutputStream outStream = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
            outStream.flush();
            outStream.close();
            Log.i(TAG, "Image saved");
            if (outPath != null) {
                outPath[0] = realFileName;
            }
            return true;
        } catch (FileNotFoundException e) {
            Log.w(TAG, "FileNotFoundException");
            return false;
        } catch (IOException e) {
            Log.w(TAG, "IOException");
            return false;
        }
    }

    public static void saveImageAsync(Bitmap bitmap, TroublePictureBean pictureBean) {
        Thread thread = new Thread(() -> {
            String[] outPath = new String[1];
            boolean isOk = FileUtil.saveImage(bitmap, pictureBean.getFile(), false, outPath);
            if (isOk) {
                String localPath = outPath[0];
                if (localPath != null && FileUtil.fileExists(localPath)) {
                    pictureBean.setFilepath(localPath);
                }
            }
        });
        thread.start();
    }

    protected static void updateTime(String fileName) {
        File file = new File(fileName);
        long newModifiedTime = System.currentTimeMillis();
        file.setLastModified(newModifiedTime);
    }

    /**
     * 计算sdcard上的剩余空间
     *
     * @return
     */
    public static int getFreeSpace() {
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
        double sdFreeMB = ((double) stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;
        return (int) sdFreeMB;
    }

    public static void removeExpiredCache(String dirPath, String filename) {
        File file = new File(dirPath, filename);
        if (System.currentTimeMillis() - file.lastModified() > IMAGE_EXPIRE_TIME) {
            Log.i(TAG, "Clear some expiredcache files ");
            file.delete();
        }
    }

    public static void removeCache(String dirPath) {
        File dir = new File(dirPath);
        File[] files = dir.listFiles();
        if (files == null) {
            return;
        }
        if (FREE_SD_SPACE_NEEDED_TO_CACHE > getFreeSpace()) {
            int removeFactor = (int) ((0.4 * files.length) + 1);
            Arrays.sort(files, new FileLastModifSort());
            Log.i(TAG, "Clear some expiredcache files ");
            for (int i = 0; i < removeFactor; i++) {
                files[i].delete();
            }

        }

    }

    private static class FileLastModifSort implements Comparator<File> {
        @Override
        public int compare(File arg0, File arg1) {
            if (arg0.lastModified() > arg1.lastModified()) {
                return 1;
            } else if (arg0.lastModified() == arg1.lastModified()) {
                return 0;
            } else {
                return -1;
            }
        }
    }

    /**
     * 确认发布时间是否在下载时间之后
     *
     * @param updateTime   服务器更新数据的时间
     * @param downloadTime 本地数据下载的时间
     * @return 服务器是否有更新
     */
    public static boolean getTimeDifferent(String updateTime, String downloadTime) {
        boolean isAfter = false;
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date updateDate = df.parse(updateTime);
            Date downloadDate = df.parse(downloadTime);
            isAfter = updateDate.after(downloadDate);
        } catch (ParseException e) {

        }catch (NullPointerException e){

        }
        return isAfter;
    }
    //用来定义存储空间显示格式
    public static String[] fileSize(long size){
        String s="";
        if(size>1024){
            s="KB";
            size/=1024;
            if(size>1024){
                s="MB";
                size/=1024;
            }
        }
        DecimalFormat df=new DecimalFormat();
        df.setGroupingSize(3);
        String[] result=new String[3];
        result[0]=df.format(size);
        result[1]=s;
        return result;
    }

    /**
     * 删除路径指向的文件
     *
     * @param filePath 文件的名称
     * @return true删除成功，false删除失败
     */
    public static boolean deleteFile(String filePath) {
        if (filePath == null || filePath.isEmpty())
            return false;

        File file = new File(filePath);
        if (file.exists() && file.isFile()) {
            return file.delete();
        }
        return false;
    }

    /**
     * 对外接口  获取uri对应的路径
     */
    @SuppressLint({"Recycle", "ObsoleteSdkInt"})
    public static String getPath(Context context, Uri uri) {
        String filePath = null;
        if ("file".equalsIgnoreCase(uri.getScheme())) {
            filePath = uri.getPath();
            return filePath;
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {//4.4以后
                filePath = getFilePath(context, uri);
            } else {//4.4以下下系统调用方法
                String[] projection = {"_data"};
                Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
                if (cursor != null && cursor.moveToFirst()) {
                    int column_index = cursor.getColumnIndexOrThrow("_data");
                    filePath = cursor.getString(column_index);
                }
            }
            return filePath;
        }
        return null;
    }

    /**
     * 专为Android4.4设计的从Uri获取文件绝对路径，以前的方法已不好使
     */
    @SuppressLint("NewApi")
    private static String getFilePath(final Context context, final Uri uri) {
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {
                final String id = DocumentsContract.getDocumentId(uri);
                if (!TextUtils.isEmpty(id)) {
                    if (id.startsWith("raw:")) {
                        return id.replaceFirst("raw:", "");
                    }
                }
                try {
                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                    return getDataColumn(context, contentUri, null, null);
                }catch (NumberFormatException e) {
                    return null;
                }
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }else if ("document".equals(type)) {
                    contentUri = MediaStore.Files.getContentUri("external");
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{split[1]};
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            uri.getPath();
        }
        return null;
    }

    public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        Cursor cursor = null;
        String column = MediaStore.Images.Media.DATA;
        String[] projection = {column};
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    public static String getFileProviderName(Context context){
        return context.getString(R.string.app_file_provider);
    }

    public static Uri getUri(Context context, File file) {
        String authorites = getFileProviderName(context);
        return getUri(context, authorites, file);
    }

    public static Uri getUri(Context context, String authorites, File file) {
        Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //设置7.0以上共享文件，分享路径定义在xml/file_paths.xml
            uri = FileProvider.getUriForFile(context, authorites, file);
        } else {
            // 7.0以下,共享文件
            uri = Uri.fromFile(file);
        }
        return uri;
    }

    public static boolean isFileTypeAudio(String fileName){
        boolean isAudio = false;
        String filetype = MimeUtil.getMimeType(fileName);
        if (filetype != null && !filetype.isEmpty()){
            isAudio = filetype.startsWith("audio");
        }
        return isAudio;
    }

    public static boolean isFileTypeVideo(String fileName){
        boolean isVideo = false;
        String filetype = MimeUtil.getMimeType(fileName);
        if (filetype != null && !filetype.isEmpty()){
            isVideo = filetype.startsWith("video");
        }
        return isVideo;
    }

    public static boolean isFileTypeImage(String fileName){
        boolean isImage = false;
        String filetype = MimeUtil.getMimeType(fileName);
        if (filetype != null && !filetype.isEmpty()){
            isImage = filetype.startsWith("image");
        }
        return isImage;
    }
}


