package cc.winboll.studio.powerbell.utils;

/**
 * @Author ZhanGSKen<zhangsken@qq.com>
 * @Date 2024/06/28 04:23:04
 * @Describe UriUtil
 */
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import androidx.core.content.FileProvider;
import cc.winboll.studio.libappbase.LogUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class UriUtils {

    public static final String TAG = "UriUtil";

    /**
     * 获取真实路径
     *
     * @param context
     */
    public static String getFilePathFromUri(Context context, Uri uri) {
        if (uri == null) {
            return null;
        }
        switch (uri.getScheme()) {
            case ContentResolver.SCHEME_CONTENT:
                //Android7.0之后的uri content:// URI
                return getFilePathFromContentUri(context, uri);
            case ContentResolver.SCHEME_FILE:
            default:
                //Android7.0之前的uri file://
                return new File(uri.getPath()).getAbsolutePath();
        }
    }

    /**
     * 从uri获取path
     *
     * @param uri content://media/external/file/109009
     *            <p>
     *            FileProvider适配
     *            content://com.tencent.mobileqq.fileprovider/external_files/storage/emulated/0/Tencent/QQfile_recv/
     *            content://com.tencent.mm.external.fileprovider/external/tencent/MicroMsg/Download/
     */
    private static String getFilePathFromContentUri(Context context, Uri uri) {
        if (null == uri) return null;
        String data = null;

        String[] filePathColumn = {MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DISPLAY_NAME};
        Cursor cursor = context.getContentResolver().query(uri, filePathColumn, null, null, null);
        if (null != cursor) {
            if (cursor.moveToFirst()) {
                int index = cursor.getColumnIndex(MediaStore.MediaColumns.DATA);
                if (index > -1) {
                    data = cursor.getString(index);
                } else {
                    int nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
                    String fileName = cursor.getString(nameIndex);
                    data = getPathFromInputStreamUri(context, uri, fileName);
                }
            }
            cursor.close();
        }
        return data;
    }

    /**
     * 用流拷贝文件一份到自己APP私有目录下
     *
     * @param context
     * @param uri
     * @param fileName
     */
    private static String getPathFromInputStreamUri(Context context, Uri uri, String fileName) {
        InputStream inputStream = null;
        String filePath = null;

        if (uri.getAuthority() != null) {
            try {
                inputStream = context.getContentResolver().openInputStream(uri);
                File file = createTemporalFileFrom(context, inputStream, fileName);
                filePath = file.getPath();

            } catch (Exception e) {
            } finally {
                try {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                } catch (Exception e) {
                }
            }
        }

        return filePath;
    }
	
	public static Uri getUriForFile(Context context, String filePath) {
		// 1. 打印传入的文件路径
		LogUtils.d(TAG, "getUriForFile -> 传入路径：" + filePath);
		if (filePath == null || filePath.isEmpty()) {
			LogUtils.e(TAG, "getUriForFile -> 传入路径为空");
			return null;
		}

		File file = new File(filePath);
		// 2. 打印File对象的绝对路径和存在性
		LogUtils.d(TAG, "getUriForFile -> 文件绝对路径：" + file.getAbsolutePath());
		LogUtils.d(TAG, "getUriForFile -> 文件是否存在：" + file.exists());
		LogUtils.d(TAG, "getUriForFile -> 是否为目录：" + file.isDirectory());

		// 3. 合法性校验
		if (!file.exists() || file.isDirectory()) {
			LogUtils.e(TAG, "getUriForFile -> 非法路径：文件不存在或为目录");
			return null;
		}

		// 4. 校验路径是否在配置的合法目录内
		String appFilesDir = context.getExternalFilesDir(null) != null ? context.getExternalFilesDir(null).getAbsolutePath() : "null";
		String publicPicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/PowerBell/";
		String internalFilesDir = context.getFilesDir().getAbsolutePath();
		String cacheDir = context.getCacheDir().getAbsolutePath();

		String absolutePath = file.getAbsolutePath();
		boolean isInConfigDir = absolutePath.startsWith(appFilesDir)
            || absolutePath.startsWith(publicPicDir)
            || absolutePath.startsWith(internalFilesDir)
            || absolutePath.startsWith(cacheDir);
		LogUtils.d(TAG, "getUriForFile -> 路径是否在配置目录内：" + isInConfigDir);
		if (!isInConfigDir) {
			LogUtils.w(TAG, "getUriForFile -> 路径不在FileProvider配置范围内，可能导致异常");
			// 非强制拦截，保留原有逻辑，仅警告
		}

		return getUriForFile(context, file);
	}

	public static Uri getUriForFile(Context context, File file) {
		if (context == null) {
			LogUtils.e(TAG, "getUriForFile -> Context为空");
			return null;
		}
		if (file == null) {
			LogUtils.e(TAG, "getUriForFile -> File对象为空");
			return null;
		}

		// 1. 二次校验文件状态
		LogUtils.d(TAG, "getUriForFile(File) -> 文件路径：" + file.getAbsolutePath());
		if (!file.exists() || file.isDirectory()) {
			LogUtils.e(TAG, "getUriForFile(File) -> 文件不存在或为目录");
			return null;
		}

		// 2. 版本判断与Uri生成
		if (Build.VERSION.SDK_INT >= 24) {
			LogUtils.d(TAG, "getUriForFile -> Android 7.0+，使用FileProvider生成Uri");
			try {
				String authority = context.getPackageName() + ".fileprovider";
				LogUtils.d(TAG, "getUriForFile -> FileProvider authority：" + authority);
				Uri uri = FileProvider.getUriForFile(context, authority, file);
				LogUtils.d(TAG, "getUriForFile -> 生成Content Uri成功：" + uri.toString());
				return uri;
			} catch (IllegalArgumentException e) {
				LogUtils.e(TAG, "getUriForFile -> FileProvider生成Uri失败：路径未配置或权限不足", e);
				return null;
			}
		} else {
			LogUtils.d(TAG, "getUriForFile -> Android 7.0以下，使用Uri.fromFile生成Uri");
			Uri uri = Uri.fromFile(file);
			LogUtils.d(TAG, "getUriForFile -> 生成File Uri成功：" + uri.toString());
			return uri;
		}
	}
	
    private static File createTemporalFileFrom(Context context, InputStream inputStream, String fileName)
    throws IOException {
        File targetFile = null;

        if (inputStream != null) {
            int read;
            byte[] buffer = new byte[8 * 1024];
            //自己定义拷贝文件路径
            targetFile = new File(context.getExternalCacheDir(), fileName);
            if (targetFile.exists()) {
                targetFile.delete();
            }
            OutputStream outputStream = new FileOutputStream(targetFile);

            while ((read = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, read);
            }
            outputStream.flush();

            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return targetFile;
    }


}
