package com.bjzc.bhzhgd.utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Point;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.KeyEvent;

import com.bjzc.bhzhgd.R;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.FutureTarget;
import com.bumptech.glide.request.target.Target;
import com.zhihu.matisse.MimeType;
import com.zhihu.matisse.filter.Filter;
import com.zhihu.matisse.internal.entity.IncapableCause;
import com.zhihu.matisse.internal.entity.Item;
import com.zhihu.matisse.internal.utils.PhotoMetadataUtils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;

import androidx.annotation.RequiresApi;


public class CompressImageUtils {
    public static class BitmapUtils {
        /**
         * 获取图片大小
         */
        public static List<Integer> getImageSize(String path) {
            List<Integer> size = new ArrayList<>();
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            newOpts.inJustDecodeBounds = true;
            Bitmap bitmap = BitmapFactory.decodeFile(path, newOpts);
            newOpts.inJustDecodeBounds = false;
            size.add(newOpts.outWidth);
            size.add(newOpts.outHeight);
            return size;
        }

        /**
         * bitmap保存成Image
         *
         * @param name
         * @param bm
         * @return 保存的文件绝对路径
         */
        public static String saveBitmap(String name, Bitmap bm) {

            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                // 创建一个文件夹对象，赋值为外部存储器的目录
                File sdcardDir = Environment.getExternalStorageDirectory();
                //得到一个路径，内容是sdcard的文件夹路径和名字
                String path = sdcardDir.getPath() + "/CompressImages";
                File path1 = new File(path);
                if (!path1.exists()) {
                    //若不存在，创建目录，可以在应用启动的时候创建
                    path1.mkdirs();
                }
                File image = new File(path, name);
                if (image.exists()) {
                    image.delete();
                }
                try {
                    image.createNewFile();
                    FileOutputStream saveImgOut = new FileOutputStream(image);
                    // compress - 压缩的意思
                    bm.compress(Bitmap.CompressFormat.JPEG, 75, saveImgOut);
                    //存储完成后需要清除相关的进程
                    saveImgOut.flush();
                    saveImgOut.close();
                    return image.getAbsolutePath();
                } catch (Exception ex) {
                    ex.printStackTrace();
                    return null;
                }
            }
            return null;
        }

        /**
         * bitmap保存成Image
         *
         * @return 保存的文件绝对路径
         */
        public static String getFilePath() {

            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                // 创建一个文件夹对象，赋值为外部存储器的目录
                File sdcardDir = Environment.getExternalStorageDirectory();
                //得到一个路径，内容是sdcard的文件夹路径和名字
                String path = sdcardDir.getPath() + "/CompressImages";
                File path1 = new File(path);
                if (!path1.exists()) {
                    //若不存在，创建目录，可以在应用启动的时候创建
                    path1.mkdirs();
                }
                return path;
            }
            return null;
        }

        public static String saveBitmapNoCom(String name, Bitmap bm) {

            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                // 创建一个文件夹对象，赋值为外部存储器的目录
                File sdcardDir = Environment.getExternalStorageDirectory();
                //得到一个路径，内容是sdcard的文件夹路径和名字
                String path = sdcardDir.getPath() + "/CompressImages";
                File path1 = new File(path);
                if (!path1.exists()) {
                    //若不存在，创建目录，可以在应用启动的时候创建
                    path1.mkdirs();
                }
                File image = new File(path, name);
                if (image.exists()) {
                    image.delete();
                }
                try {
                    image.createNewFile();
                    FileOutputStream saveImgOut = new FileOutputStream(image);
                    // compress - 压缩的意思
                    bm.compress(Bitmap.CompressFormat.JPEG, 100, saveImgOut);

                    //存储完成后需要清除相关的进程
                    saveImgOut.flush();
                    saveImgOut.close();
                    return image.getAbsolutePath();
                } catch (Exception ex) {
                    ex.printStackTrace();
                    return null;
                }
            }
            return null;
        }

        public static String saveCopyImagesToUploadDir(String srcPath, String name) {

            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                // 创建一个文件夹对象，赋值为外部存储器的目录
                File sdcardDir = Environment.getExternalStorageDirectory();
                //得到一个路径，内容是sdcard的文件夹路径和名字
                String path = sdcardDir.getPath() + "/CompressImages";
                File path1 = new File(path);
                if (!path1.exists()) {
                    //若不存在，创建目录，可以在应用启动的时候创建
                    path1.mkdirs();
                }
                File image = new File(path, name);
                if (image.exists()) {
                    image.delete();
                }
                FileInputStream fs = null;
                FileOutputStream saveImgOut = null;
                try {
                    fs = new FileInputStream(new File(srcPath));
                    ;
                    image.createNewFile();
                    saveImgOut = new FileOutputStream(image);
                    int len = 0;
                    byte[] bytes = new byte[1024];
                    while ((len = fs.read(bytes)) != -1) {
                        saveImgOut.write(bytes, 0, len);
                    }
                    //存储完成后需要清除相关的进程
                    saveImgOut.flush();
                    saveImgOut.close();
                    fs.close();
                    return image.getAbsolutePath();
                } catch (Exception ex) {
                    ex.printStackTrace();
                    return null;
                } finally {
                    try {
                        if (fs != null) {
                            fs.close();
                        }
                        if (saveImgOut != null) {
                            saveImgOut.close();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }

        /**
         * 质量压缩，一直到小于maxsize
         *
         * @param image
         * @param maxSize
         * @return
         */
        public static Bitmap qualityCompressImage(Bitmap image, int maxSize) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            //质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
            if (image == null) {
                return null;
            }
            image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            int options = 100;
            //循环判断如果压缩后图片是否大于300kb,大于继续压缩
            while (baos.toByteArray().length / 1024 > maxSize) {
                //重置baos即清空baos
                baos.reset();
                //这里压缩options%，把压缩后的数据存放到baos中
                image.compress(Bitmap.CompressFormat.JPEG, options, baos);
                options -= 10;//每次都减少10
                if (options < 0) {
                    break;
                }
            }
            //把压缩后的数据baos存放到ByteArrayInputStream中
            ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
            //把ByteArrayInputStream数据生成图片
            return BitmapFactory.decodeStream(isBm);
        }

        /**
         * 获取压缩后的图片，先尺寸压缩再进行质量压缩
         *
         * @param srcPath
         * @param maxSize
         * @param outputName
         * @return
         */
        public static String getCompressImage(Context context, String srcPath, int maxSize, String outputName) {

            if (getFileSize(new File(srcPath)) / 1024 < maxSize) {
                return srcPath;
            }
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            //开始读入图片，此时把options.inJustDecodeBounds 设回true了
            newOpts.inJustDecodeBounds = true;
            //此时返回bm为空
            Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);

            newOpts.inJustDecodeBounds = false;
            int w = newOpts.outWidth;
            int h = newOpts.outHeight;
            //现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
            DisplayMetrics dm = context.getResources().getDisplayMetrics();
            int hh, ww;
            if (getFileSize(new File(srcPath)) / 1024 > maxSize) {
                if (w >= 3000 && h >= 3000) {
                    if (w >= h) {
                        hh = 2500;
                        ww = 2501;
                    } else {
                        hh = 2500;
                        ww = 2500;
                    }
                } else {
                    hh = dm.heightPixels;
                    ww = dm.widthPixels;
                }
            } else {
                hh = h;
                ww = w;
            }

            //        float hh = 800f;//这里设置高度为800f
            //        float ww = 480f;//这里设置宽度为480f
            //缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
            int be = 1;//be=1表示不缩放
            if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
                be = Math.round((float) newOpts.outWidth / ww);
            } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
                be = Math.round((float) newOpts.outHeight / hh);
            }
            if (be <= 0) {
                be = 1;
            }


            newOpts.inSampleSize = be;//设置缩放比例
            //重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
            bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
            int degree = readPictureDegree(srcPath);
            bitmap = rotateBitmap(bitmap, degree);
            bitmap = qualityCompressImage(bitmap, maxSize);//压缩好比例大小后再进行质量压缩
            String path = saveBitmap(outputName, bitmap);;

            if (bitmap != null) {
                bitmap.recycle();
            }
            return path;
        }

        /**
         * 获取图片旋转角度
         *
         * @param srcPath
         * @return
         */
        private static int readPictureDegree(String srcPath) {
            int degree = 0;
            try {
                ExifInterface exifInterface = new ExifInterface(srcPath);
                int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
                switch (orientation) {
                    case ExifInterface.ORIENTATION_ROTATE_90:
                        degree = 90;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_180:
                        degree = 180;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_270:
                        degree = 270;
                        break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return degree;
        }

        //处理图片旋转
        private static Bitmap rotateBitmap(Bitmap bitmap, int rotate) {
            if (bitmap == null)
                return null;

            int w = bitmap.getWidth();
            int h = bitmap.getHeight();

            // Setting post rotate to 90
            Matrix mtx = new Matrix();
            mtx.postRotate(rotate);
            return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
        }

        /**
         * 获取指定文件大小
         */
        public static long getFileSize(File file) {
            long size = 0;
            if (file.exists()) {
                FileInputStream fis = null;
                try {
                    fis = new FileInputStream(file);
                    size = fis.available();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
            }
            return size;
        }

        /**
         * Glide 获得图片缓存路径
         */
        public static String getImagePath(Context context, String imgUrl) {
            String path = null;
            FutureTarget<File> future = Glide.with(context)
                    .load(imgUrl)
                    .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
            try {
                File cacheFile = future.get();
                path = cacheFile.getAbsolutePath();
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
            return path;
        }
    }

    public static class ImageCompressTask extends AsyncTask<String, Integer, String> {
        private final CompressListener compressListener;
        @SuppressLint("StaticFieldLeak")
        private Context context;

        public ImageCompressTask(Context context, CompressListener listener) {
            compressListener = listener;
            this.context = context;
        }

        @Override
        protected String doInBackground(String... strings) {
            String imagePath = strings[0];
            String outputName = strings[1];
            return BitmapUtils.getCompressImage(context, imagePath, 1024, outputName);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            if (compressListener != null) {
                compressListener.onProgressUpdate(values);
            }
        }

        @Override
        protected void onPostExecute(String path) {
            if (compressListener != null) {
                compressListener.Success(path);
            }
        }

        public static interface CompressListener {
            void Success(String imagePath);

            void onProgressUpdate(Integer... values);
        }
    }

    public static class FileUtil {
        /**
         * uri获取path
         *
         * @param context
         * @param contentUri
         * @return
         */
        public static String getFilePathFromURI(Context context, Uri contentUri) {
            File rootDataDir = context.getExternalFilesDir(null);
            File tmpDir = new File(rootDataDir + File.separator + "tempPic" + File.separator);
            if (!tmpDir.exists()) {
                tmpDir.mkdir();
            }
            String fileName = getFileName(contentUri);
            if (!TextUtils.isEmpty(fileName)) {
                String path = "";
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    path = getPath(context, contentUri);
                    if (TextUtils.isEmpty(path)) {
                        File copyFile = new File(rootDataDir + File.separator + "tempPic" + File.separator + fileName);
                        copyFile(context, contentUri, copyFile);
                        path = copyFile.getAbsolutePath();
                    }
                } else {
                    File copyFile = new File(rootDataDir + File.separator + "tempPic" + File.separator + fileName);
                    copyFile(context, contentUri, copyFile);
                    path = copyFile.getAbsolutePath();
                }
                return path;
            }
            return null;
        }


        @SuppressLint("Range")
        @RequiresApi(api = Build.VERSION_CODES.O)
        private static String getPath(Context context, Uri uri) {
            String path = "";
            Cursor cursor = null;
            try {
                cursor = context.getContentResolver().query(uri, null, null, null);

                if (cursor == null) {
                    return null;
                }
                if (cursor.moveToFirst()) {
                    path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
                }
                cursor.close();
            } catch (Exception e) {
                return "";
            }

            return path;
        }


        /**
         * uri获取文件名
         *
         * @param uri
         * @return
         */
        public static String getFileName(Uri uri) {
            if (uri == null) return null;
            String fileName = null;
            String path = uri.getPath();
            int cut = path.lastIndexOf('/');
            if (cut != -1) {
                fileName = path.substring(cut + 1);
            }
            return fileName;
        }

        /**
         * 通过uri拷贝文件
         *
         * @param context
         * @param srcUri
         * @param dstFile
         */
        public static void copyFile(Context context, Uri srcUri, File dstFile) {
            try {
                InputStream inputStream = context.getContentResolver().openInputStream(srcUri);
                if (inputStream == null) return;
                OutputStream outputStream = new FileOutputStream(dstFile);
                copyStream(inputStream, outputStream);
                inputStream.close();
                outputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * stream拷贝
         *
         * @param input
         * @param output
         * @return
         * @throws Exception
         * @throws IOException
         */
        public static int copyStream(InputStream input, OutputStream output) throws Exception, IOException {
            final int BUFFER_SIZE = 1024 * 2;
            byte[] buffer = new byte[BUFFER_SIZE];
            BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE);
            BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE);
            int count = 0, n = 0;
            try {
                while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
                    out.write(buffer, 0, n);
                    count += n;
                }
                out.flush();
            } finally {
                try {
                    out.close();
                } catch (IOException e) {
                }
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
            return count;
        }

        public static void clearTempPicture(Context context) {
            File rootDataDir = context.getExternalFilesDir(null);
            File picDir = new File(rootDataDir + File.separator + "tempPic/");
            if (picDir.exists() && picDir.isDirectory()) {
                for (File file : picDir.listFiles()) {
                    file.delete();
                }
            }
        }

        public static void copyFile(String oldPath, String newPath) {
            try {
                int bytesum = 0;
                int byteread = 0;
                File oldfile = new File(oldPath);
                if (oldfile.exists()) { //文件存在时
                    InputStream inStream = new FileInputStream(oldPath); //读入原文件
                    FileOutputStream fs = new FileOutputStream(newPath);
                    byte[] buffer = new byte[1444];
                    int length;
                    while ((byteread = inStream.read(buffer)) != -1) {
                        bytesum += byteread; //字节数 文件大小
                        System.out.println(bytesum);
                        fs.write(buffer, 0, byteread);
                    }
                    inStream.close();
                }
            } catch (Exception e) {
                System.out.println("复制单个文件操作出错");
                e.printStackTrace();

            }

        }

        /**
         * Glide 获得图片缓存路径
         */
        public static String getImagePath(Context context, String imgUrl) {
            String path = null;
            FutureTarget<File> future = Glide.with(context)
                    .load(imgUrl)
                    .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
            try {
                File cacheFile = future.get();
                path = cacheFile.getAbsolutePath();
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
            return path;
        }
    }

    public static class GifSizeFilter extends Filter {

        private int mMinWidth;
        private int mMinHeight;
        private int mMaxSize;

        public GifSizeFilter(int minWidth, int minHeight, int maxSizeInBytes) {
            mMinWidth = minWidth;
            mMinHeight = minHeight;
            mMaxSize = maxSizeInBytes;
        }

        @Override
        public Set<MimeType> constraintTypes() {
            return MimeType.ofAll();
        }

        @Override
        public IncapableCause filter(Context context, Item item) {
            if (!needFiltering(context, item))
                return null;

            Point size = PhotoMetadataUtils.getBitmapBound(context.getContentResolver(), item.getContentUri());
            if (size.x < mMinWidth || size.y < mMinHeight || item.size > mMaxSize) {
                return new IncapableCause(IncapableCause.DIALOG, "压缩后，当前图片大小：" + String.valueOf(PhotoMetadataUtils.getSizeInMB(mMaxSize)));
            }
            return null;
        }

    }

    public static class BusinessUtils {

        /*
         * 抽取打开相册选择图片公共代码部分，发帖，详情，下载图片部分代码
         * content类型的uri获取图片路径的方法
         * */
        public static String getImagePath(Activity activity, Uri uri, String selection) {
            String[] filePathColumn = {MediaStore.MediaColumns.DATA};
            String path = null;
            Cursor cursor = activity.getContentResolver().query(uri, filePathColumn, selection, null, null);
            if (cursor != null) {
                if (cursor.moveToFirst()) {
                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    path = cursor.getString(columnIndex);

                }
                cursor.close();
            }
            return path;
        }

    }

    public static class LoadingDialog {
        private static AlertDialog alertDialog;

        public static void showDialog(Activity activity) {
            alertDialog = new AlertDialog.Builder(activity, R.style.TransparentDialog).create();
            alertDialog.getWindow().setDimAmount(0);
            alertDialog.setCancelable(false);
            alertDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_SEARCH || keyCode == KeyEvent.KEYCODE_BACK)
                        return true;
                    return false;
                }
            });
            alertDialog.show();
            alertDialog.setContentView(R.layout.loading_alert);
            alertDialog.setCanceledOnTouchOutside(false);
        }

        public static void dismissDialog() {
            if (null != alertDialog && alertDialog.isShowing()) {
                alertDialog.dismiss();
            }
        }

    }
}
