package com.remax.visualnovel.widget.imagepicker.utils;

import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.ParcelFileDescriptor;

import com.remax.visualnovel.app.base.app.CommonApplicationProxy;
import com.remax.visualnovel.widget.imagepicker.bean.ImageItem;
import com.remax.visualnovel.widget.imagepicker.bean.MimeType;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class MediaUtils {


    public static String copyUriToLocalMedia(Context context, ImageItem imageItem, String path) {
        if (imageItem == null) {
            return null;
        }
        return copyUriToLocalMedia(context, imageItem.getUri(), path, imageItem.mimeType);
    }

    /**
     * 从相册中copy出文件并预处理 TODO 应该在异步线程中执行
     *
     * @param context
     * @param uri
     * @param path    文件保存路径
     * @return
     */
    public static String copyUriToLocalMedia(Context context, Uri uri, String path, String mimeType) {
        if (uri == null) {
            return null;
        }
        String filePath = "";
        try {
            if (MimeType.isImage(mimeType)) {
                StringBuilder timeStamp = new StringBuilder();
                timeStamp.append("aos");
                timeStamp.append(System.currentTimeMillis());
                for (int i = 0; i < 4; i++) {
                    timeStamp.append((int) (Math.random() * 10));
                }
                String postfix = "jpg";
                if (MimeType.isGif(mimeType)) {
                    postfix = "gif";
                }
                String filename = String.format("%s.%s", timeStamp, postfix);
                filePath = path + "/" + filename;
                File file = new File(filePath);
                copyFileToInternalStorage(context, uri, file);
            } else if (MimeType.isVideo(mimeType)) {
                String timeStamp = new SimpleDateFormat("yyyyMMddHHmmssSSS", Locale.getDefault()).format(new Date());
                String filename = String.format("VIDEO_%s.mp4", timeStamp);
                filePath = path + "/" + filename;
                File file = new File(filePath);
                copyFileToInternalStorage(context, uri, file);
            } else if (mimeType.startsWith("audio/mpeg")) {
                String timeStamp = new SimpleDateFormat("yyyyMMddHHmmssSSS", Locale.getDefault()).format(new Date());
                String filename = String.format("MP3_%s.mp3", timeStamp);
                filePath = path + "/" + filename;
                File file = new File(filePath);
                copyFileToInternalStorage(context, uri, file);
            }
        } catch (Exception ignored) {
        }
        return filePath;
    }

    /**
     * 复制文件到内部存储空间
     */
    public static void copyFileToInternalStorage(Context context, Uri uri, File destinationFile) {
        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            inputStream = context.getContentResolver().openInputStream(uri);
            outputStream = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) ? Files.newOutputStream(destinationFile.toPath()) : new FileOutputStream(destinationFile);

            byte[] buffer = new byte[4096];
            int bytesRead;
            while (inputStream !=null && (bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭流
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void copyPublicDirToPackageDir(Context context, Uri uri, File file) {
        InputStream is = null;
        OutputStream os = null;
        try {
            ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
            is = new FileInputStream(pfd.getFileDescriptor());
            os = new FileOutputStream(file);
            byte[] buf = new byte[2048];
            int len = 0;
            while ((len = is.read(buf)) != -1) {  // 循环从输入流读取 buffer字节
                os.write(buf, 0, len);        // 将读取的输入流写入到输出流
            }
            os.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            closeIO(os, is);
        }
    }

    /**
     * 关闭IO
     *
     * @param closeables closeable
     */
    public static void closeIO(Closeable... closeables) {
        if (closeables == null) {
            return;
        }
        try {
            for (Closeable closeable : closeables) {
                if (closeable != null) {
                    closeable.close();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String getExternalFilePath(Context context, String fileDir) {
        String dirPath = context.getExternalFilesDir(fileDir).getAbsolutePath();
        File file = new File(dirPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        return dirPath;
    }

    /**
     * 删除目录
     *
     * @param dirFile 目录
     * @return {@code true}: 删除成功<br>{@code false}: 删除失败
     */
    public static boolean deleteDir(File dirFile) {
        if (dirFile == null) {
            return false;
        }
        // 目录不存在返回true
        if (!dirFile.exists()) {
            return true;
        }
        // 不是目录返回false
        if (!dirFile.isDirectory()) {
            return false;
        }
        // 现在文件存在且是文件夹
        File[] files = dirFile.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isFile()) {
                    if (!deleteFile(file)) {
                        return false;
                    }
                } else if (file.isDirectory()) {
                    if (!deleteDir(file)) {
                        return false;
                    }
                }
            }
        }
        return dirFile.delete();
    }

    /**
     * 删除文件
     *
     * @param file 文件
     * @return {@code true}: 删除成功<br>{@code false}: 删除失败
     */
    public static boolean deleteFile(File file) {
        return file != null && (!file.exists() || file.isFile() && file.delete());
    }

    /**
     * 获取一个临时文件存储地址（保存的文件会在app下次启动时删除）
     *
     * @return filePath
     */
    public static String getTempFilePath() {
        String filePath;
        Context context = CommonApplicationProxy.INSTANCE.getApplication();
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) {
            //外部存储可用
            filePath = getExternalFilePath(context, "temp");
        } else {
            //外部存储不可用
            filePath = context.getDir("temp", Context.MODE_PRIVATE).getAbsolutePath();
            File file = new File(filePath);
            if (!file.exists()) {
                file.mkdirs();
            }
        }
        return filePath;
    }

    public static void cleanTempFile(Context context) {
        deleteDir(context.getExternalFilesDir("temp"));
        deleteDir(context.getDir("temp", Context.MODE_PRIVATE));
    }
}
