package kr.co.compcarecompany.Util;

import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import android.webkit.MimeTypeMap;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import kr.co.compcarecompany.MyApplication;

public class FileUploadHelper {
    private static FileUploadHelper instance;

    public static FileUploadHelper getInstance() {
        if (instance == null) {
            instance = new FileUploadHelper();
        }

        return instance;
    }

    private String mPackageName;
    private String mTempStorageFolder;

    public FileUploadHelper() {
        mPackageName = "Compcare";
        mTempStorageFolder = Environment.getExternalStorageDirectory() + "/DCIM/" + mPackageName;
    }

    public void deleteTemp() {
        File storageDir = new File(mTempStorageFolder);
        if (storageDir.exists()) {
            File[] fileList = storageDir.listFiles();
            if(fileList != null) {
                for (File file : fileList) {
                    if (file != null && !file.isDirectory()) {
                        file.delete();
                    }
                }
            }
        }
    }

    public String getFileType(Context context, File file) {
        ContentResolver cR = context.getContentResolver();
        MimeTypeMap mime = MimeTypeMap.getSingleton();
        Uri uri = Uri.fromFile(file);
        return mime.getExtensionFromMimeType(cR.getType(uri));
    }

    //타입가저오기 */* 형태
    public String getFileType(String file_path) {
        String type = null;
        String extension = MimeTypeMap.getFileExtensionFromUrl(file_path);
        if (extension != null) {
            type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
        }
        Log.i("type", type == null ? "type is null" : type);
        return type;
    }

    //이미지파일 생성
    public File createImageFile(Context context) throws IOException {
        // Create an image file name

        String timeStamp = new SimpleDateFormat("HHmmss").format(new Date());
        String imageFileName = mPackageName + "_" + timeStamp + "_";
        File storageDir = new File(mTempStorageFolder);
        if (!storageDir.exists()) {
            storageDir.mkdirs();
        }
        File image = File.createTempFile(
                imageFileName,
                ".jpg",
                storageDir
        );
        Log.i("createImageFile", image.getPath());
        return image;
    }

    public File getResizeFile(Uri uri) {
        Context context = MyApplication.context;
        BitmapFactory.Options option = new BitmapFactory.Options();
        option.inJustDecodeBounds = true;

        try (InputStream inputStream = context.getContentResolver().openInputStream(uri)) {
            // 이미지 정보 읽기 (inJustDecodeBounds = true)
            BitmapFactory.decodeStream(inputStream, null, option);
        } catch (IOException e) {
            Log.e("getResizeFile", "Failed to decode bounds", e);
            return null;
        }

        int imageWidth = option.outWidth;
        int imageHeight = option.outHeight;

        int width = 720;
        int height = 405;

        // 세로 이미지일 경우 가로/세로 크기 스왑
        if (imageHeight > imageWidth) {
            int tmp = width;
            width = height;
            height = tmp;
        }

        int size = 1;
        int MAX_IMAGE_SIZE = 800;
        if (option.outHeight > MAX_IMAGE_SIZE || option.outWidth > MAX_IMAGE_SIZE) {
            size = (int) Math.pow(2, (int) Math.round(Math.log(MAX_IMAGE_SIZE / (double) Math.max(option.outHeight, option.outWidth)) / Math.log(0.5)));
        }

        option.inJustDecodeBounds = false;
        option.inSampleSize = size;

        Bitmap bitmap = null;

        try (InputStream inputStream = context.getContentResolver().openInputStream(uri)) {
            // Bitmap 생성
            bitmap = BitmapFactory.decodeStream(inputStream, null, option);
        } catch (IOException e) {
            Log.e("getResizeFile", "Failed to decode bitmap", e);
            return null;
        }

        // Exif 정보를 읽어서 회전 처리
        int degree = getExifOrientationFromUri(context, uri);
        bitmap = getRotatedBitmap(bitmap, degree);

        // Bitmap 리사이즈 처리
        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight());
        Log.i("imageWidth= " + bitmap.getWidth(), "imageHeight = " + bitmap.getHeight());

        File file = null;
        OutputStream out = null;
        try {
            file = createImageFile(context); // 새 파일 생성
            out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); // Bitmap 저장
            out.flush();
            out.close();
            bitmap.recycle(); // 메모리 해제
        } catch (IOException e) {
            Log.e("getResizeFile", "Failed to save resized file", e);
        }

        return file;
    }

    private Bitmap getRotatedBitmap(Bitmap bitmap, int degrees) {
        if (degrees != 0 && bitmap != null) {
            Matrix m = new Matrix();
            m.setRotate(degrees, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);

            try {
                Bitmap b2 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);

                if (bitmap != b2) {
                    bitmap.recycle();
                    bitmap = b2;
                }
            } catch (OutOfMemoryError e) {
                // 메모리 부족에러시, 원본을 반환
            }
        }

        return bitmap;
    }

    private int getExifOrientationFromUri(Context context, Uri uri) {
        int degree = 0;

        try (InputStream inputStream = context.getContentResolver().openInputStream(uri)) {
            if (inputStream != null) {
                ExifInterface exif = new ExifInterface(inputStream);
                int orientation = exif.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) {
            Log.e("getExifOrientation", "Failed to read Exif data", e);
        }

        return degree;
    }
}
