package com.tagmae.tsgame_erwang.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * Base64与图片互相转换工具类
 */
public class Base64ImageUtil {

    private static final String TAG = "Base64ImageUtil";

    /**
     * 将Base64编码的字符串转换为Bitmap
     *
     * @param base64String Base64编码的字符串（不包含前缀如"data:image/jpeg;base64,"）
     * @return 解码后的Bitmap，失败则返回null
     */
    public static Bitmap base64ToBitmap(String base64String) {
        if (TextUtils.isEmpty(base64String)) {
            Log.e(TAG, "Base64字符串为空");
            return null;
        }

        try {
            // 去除可能存在的图片前缀
            if (base64String.contains(",")) {
                base64String = base64String.split(",")[1];
            }

            byte[] decodedBytes = Base64.decode(base64String, Base64.DEFAULT);
            return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
        } catch (Exception e) {
            Log.e(TAG, "Base64转Bitmap出错: " + e.getMessage());
            return null;
        }
    }

    /**
     * 将Base64编码的字符串保存为图片文件
     *
     * @param context 上下文
     * @param base64String Base64编码的字符串
     * @param fileName 文件名，如果为null则自动生成
     * @return 保存的图片文件的Uri，失败则返回null
     */
    public static Uri base64ToImageFile(Context context, String base64String, String fileName) {
        Bitmap bitmap = base64ToBitmap(base64String);
        if (bitmap == null) {
            Log.e(TAG, "Base64转图片失败");
            return null;
        }

        return saveBitmapToFile(context, bitmap, fileName);
    }

    /**
     * 保存Bitmap到文件
     *
     * @param context 上下文
     * @param bitmap 要保存的Bitmap
     * @param fileName 文件名，为null则自动生成
     * @return 保存的图片Uri，失败则返回null
     */
    public static Uri saveBitmapToFile(Context context, Bitmap bitmap, String fileName) {
        // 创建保存的文件名
        if (TextUtils.isEmpty(fileName)) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault());
            fileName = "IMG_" + sdf.format(new Date()) + ".jpg";
        }

        // 判断存储状态
        File storageDir;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        } else {
            storageDir = context.getFilesDir();
        }

        if (!storageDir.exists()) {
            storageDir.mkdirs();
        }

        File imageFile = new File(storageDir, fileName);
        try (FileOutputStream fos = new FileOutputStream(imageFile)) {
            // 压缩图片到文件
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
            fos.flush();
            return Uri.fromFile(imageFile);
        } catch (IOException e) {
            Log.e(TAG, "保存图片出错: " + e.getMessage());
            return null;
        } finally {
            // 如果不再需要bitmap，释放内存
            if (!bitmap.isRecycled()) {
                bitmap.recycle();
            }
        }
    }

    /**
     * 将Bitmap转换为Base64编码的字符串
     *
     * @param bitmap 要转换的Bitmap
     * @param quality 压缩质量 (0-100)
     * @return Base64编码的字符串，转换失败则返回null
     */
    public static String bitmapToBase64(Bitmap bitmap, int quality) {
        if (bitmap == null) {
            return null;
        }

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
            byte[] bytes = baos.toByteArray();
            return Base64.encodeToString(bytes, Base64.DEFAULT);
        } catch (Exception e) {
            Log.e(TAG, "Bitmap转Base64出错: " + e.getMessage());
            return null;
        } finally {
            try {
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 检查Base64字符串大小
     *
     * @param base64String Base64编码的字符串
     * @return 字符串表示的近似大小
     */
    public static String getBase64Size(String base64String) {
        if (TextUtils.isEmpty(base64String)) {
            return "0 KB";
        }

        // 去除可能存在的前缀
        if (base64String.contains(",")) {
            base64String = base64String.split(",")[1];
        }

        // 计算原始大小 (Base64编码会将3字节数据编码为4个字符)
        float sizeInBytes = (float) (base64String.length() * 3) / 4;

        if (sizeInBytes < 1024) {
            return String.format(Locale.getDefault(), "%.2f B", sizeInBytes);
        } else if (sizeInBytes < 1024 * 1024) {
            return String.format(Locale.getDefault(), "%.2f KB", sizeInBytes / 1024);
        } else {
            return String.format(Locale.getDefault(), "%.2f MB", sizeInBytes / (1024 * 1024));
        }
    }

    /**
     * 压缩Base64编码的图片
     *
     * @param base64String 原始Base64字符串
     * @param maxSizeKB 目标大小（KB）
     * @return 压缩后的Base64字符串
     */
    public static String compressBase64Image(String base64String, int maxSizeKB) {
        if (TextUtils.isEmpty(base64String)) {
            return null;
        }

        // 转换为bitmap
        Bitmap bitmap = base64ToBitmap(base64String);
        if (bitmap == null) {
            return null;
        }

        // 初始质量为80%
        int quality = 80;
        String result = bitmapToBase64(bitmap, quality);

        // 如果已经小于最大大小，直接返回
        float currentSize = (result.length() * 3) / 4f / 1024f;  // KB
        if (currentSize <= maxSizeKB) {
            return result;
        }

        // 循环压缩
        while (currentSize > maxSizeKB && quality > 10) {
            // 每次降低10%质量
            quality -= 10;
            result = bitmapToBase64(bitmap, quality);
            currentSize = (result.length() * 3) / 4f / 1024f;
        }

        // 释放bitmap内存
        if (!bitmap.isRecycled()) {
            bitmap.recycle();
        }

        return result;
    }
}
