package cc.winboll.studio.powerbell.utils;

import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import cc.winboll.studio.libappbase.LogUtils;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
 * @Date 2025/11/19 20:52
 * @Describe 图片下载工具类（单例模式）
 * 功能：下载网络图片到缓存目录、清理过期文件、获取最新下载文件
 */
public class ImageDownloader {
	public static final String TAG = "ImageDownloader";
	// 单例实例
	private static ImageDownloader sInstance;
	// OkHttp 客户端（全局复用，提升性能）
	private OkHttpClient mOkHttpClient;
	// 缓存目录：/data/data/应用包名/cache/networkdownload
	private File mCacheDir;
	// 过期时间：7天（单位：毫秒），可按需调整
	private static final long EXPIRE_TIME = 7 * 24 * 3600 * 1000;

	/**
	 * 私有构造（单例模式禁止外部实例化）
	 * @param context 上下文（用于获取缓存目录）
	 */
	private ImageDownloader(Context context) {
		// 初始化 OkHttp 客户端（设置超时时间）
		mOkHttpClient = new OkHttpClient.Builder()
			.connectTimeout(10, TimeUnit.SECONDS)
			.readTimeout(15, TimeUnit.SECONDS)
			.writeTimeout(15, TimeUnit.SECONDS)
			.build();

		// 初始化缓存目录：networkdownload
		initCacheDir(context);
		// 初始化时清理过期文件
		clearExpiredFiles();
	}

	/**
	 * 单例获取方法（线程安全）
	 * @param context 上下文（建议使用 Application 上下文避免内存泄漏）
	 * @return 单例实例
	 */
	public static synchronized ImageDownloader getInstance(Context context) {
		if (sInstance == null) {
			// 使用 Application 上下文，防止 Activity 销毁导致的内存泄漏
			sInstance = new ImageDownloader(context.getApplicationContext());
		}
		return sInstance;
	}

	/**
	 * 初始化缓存目录：若不存在则创建
	 */
	private void initCacheDir(Context context) {
		// 获取应用内置缓存目录（无需权限）
		File cacheRoot = context.getCacheDir();
		mCacheDir = new File(cacheRoot, "networkdownload");

		// 若目录不存在则创建（包括父目录）
		if (!mCacheDir.exists()) {
			boolean isCreated = mCacheDir.mkdirs();
			if (isCreated) {
				LogUtils.d("ImageDownloader", "networkdownload 缓存目录创建成功：" + mCacheDir.getAbsolutePath());
			} else {
				LogUtils.e("ImageDownloader", "networkdownload 缓存目录创建失败");
			}
		} else {
			LogUtils.d("ImageDownloader", "networkdownload 缓存目录已存在：" + mCacheDir.getAbsolutePath());
		}
	}

	/**
	 * 清理过期文件（最后修改时间超过 EXPIRE_TIME 的文件）
	 */
	private void clearExpiredFiles() {
		if (mCacheDir == null || !mCacheDir.exists()) {
			return;
		}

		File[] files = mCacheDir.listFiles();
		if (files == null || files.length == 0) {
			LogUtils.d("ImageDownloader", "缓存目录无文件，无需清理");
			return;
		}

		long currentTime = System.currentTimeMillis();
		int deleteCount = 0;

		// 遍历所有文件，删除过期文件
		for (File file : files) {
			long lastModifyTime = file.lastModified();
			if (currentTime - lastModifyTime > EXPIRE_TIME) {
				if (file.delete()) {
					deleteCount++;
					LogUtils.d("ImageDownloader", "删除过期文件：" + file.getName());
				} else {
					LogUtils.e("ImageDownloader", "删除过期文件失败：" + file.getName());
				}
			}
		}

		LogUtils.d("ImageDownloader", "过期文件清理完成，共删除 " + deleteCount + " 个文件");
	}

	/**
	 * 下载网络图片到缓存目录
	 * @param imageUrl 图片网络链接
	 * @param callback 下载结果回调（成功/失败）
	 */
	public void downloadImage(final String imageUrl, final DownloadCallback callback) {
		// 校验参数
		if (TextUtils.isEmpty(imageUrl)) {
			if (callback != null) {
				callback.onFailure("图片链接为空");
			}
			return;
		}

		if (mCacheDir == null || !mCacheDir.exists()) {
			if (callback != null) {
				callback.onFailure("缓存目录不存在");
			}
			return;
		}

		// 构建 OkHttp 请求
		Request request = new Request.Builder()
			.url(imageUrl)
			.build();

		// 异步下载（避免阻塞主线程）
		mOkHttpClient.newCall(request).enqueue(new Callback() {
				@Override
				public void onFailure(Call call, IOException e) {
					// 下载失败，回调主线程
					if (callback != null) {
						callback.onFailure("下载失败：" + e.getMessage());
					}
					LogUtils.e("ImageDownloader", "图片下载失败：" + e.getMessage());
				}

				@Override
				public void onResponse(Call call, Response response) throws IOException {
					if (!response.isSuccessful()) {
						// 响应失败（如 404、500）
						if (callback != null) {
							callback.onFailure("响应失败：" + response.code());
						}
						LogUtils.e("ImageDownloader", "图片响应失败，状态码：" + response.code());
						return;
					}

					// 响应成功，写入文件
					InputStream inputStream = null;
					FileOutputStream outputStream = null;
					try {
						inputStream = response.body().byteStream();
						// 生成 UUID 唯一文件名（保留原文件后缀）
						String fileExtension = getFileExtension(imageUrl);
						String fileName = UUID.randomUUID().toString() + fileExtension;
						File imageFile = new File(mCacheDir, fileName);

						// 写入文件
						outputStream = new FileOutputStream(imageFile);
						byte[] buffer = new byte[1024];
						int len;
						while ((len = inputStream.read(buffer)) != -1) {
							outputStream.write(buffer, 0, len);
						}
						outputStream.flush();

						// 下载成功，回调主线程并返回文件路径
						if (callback != null) {
							callback.onSuccess(imageFile.getAbsolutePath());
						}
						LogUtils.d("ImageDownloader", "图片下载成功：" + imageFile.getAbsolutePath());

					} catch (IOException e) {
						if (callback != null) {
							callback.onFailure("文件写入失败：" + e.getMessage());
						}
						LogUtils.e("ImageDownloader", "图片写入失败：" + e.getMessage());
					} finally {
						// 关闭流（Java7 手动关闭，避免资源泄漏）
						if (inputStream != null) {
							try {
								inputStream.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
						if (outputStream != null) {
							try {
								outputStream.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
						// 关闭响应体
						if (response.body() != null) {
							response.body().close();
						}
					}
				}
			});
	}

	/**
	 * 获取 networkdownload 目录中最后下载的文件（按修改时间排序）
	 * @return 最后下载的文件路径（null 表示无文件）
	 */
	public String getLastDownloadedFile() {
		if (mCacheDir == null || !mCacheDir.exists()) {
			LogUtils.e("ImageDownloader", "缓存目录不存在");
			return null;
		}

		File[] files = mCacheDir.listFiles();
		if (files == null || files.length == 0) {
			LogUtils.d("ImageDownloader", "缓存目录无文件");
			return null;
		}

		// 按最后修改时间降序排序，取第一个即为最新文件
		File lastFile = files[0];
		for (File file : files) {
			if (file.lastModified() > lastFile.lastModified()) {
				lastFile = file;
			}
		}

		LogUtils.d("ImageDownloader", "最后下载的文件：" + lastFile.getAbsolutePath());
		return lastFile.getAbsolutePath();
	}

	/**
	 * 工具方法：从图片链接中提取文件后缀（如 .png、.jpg）
	 * @param imageUrl 图片链接
	 * @return 文件后缀（含点号，若无法提取则返回 .jpg）
	 */
	private String getFileExtension(String imageUrl) {
		if (TextUtils.isEmpty(imageUrl)) {
			return ".jpg";
		}

		int lastDotIndex = imageUrl.lastIndexOf(".");
		int lastSlashIndex = imageUrl.lastIndexOf("/");
		// 确保后缀在最后一个斜杠之后，且长度合理（1-5 个字符）
		if (lastDotIndex > lastSlashIndex && lastDotIndex < imageUrl.length() - 1) {
			String extension = imageUrl.substring(lastDotIndex);
			if (extension.length() <= 5) {
				return extension.toLowerCase(); // 统一转为小写
			}
		}

		// 无法提取后缀时，默认使用 .jpg
		return ".jpg";
	}

	/**
	 * 下载结果回调接口（Java7 接口实现）
	 */
	public interface DownloadCallback {
		/**
		 * 下载成功
		 * @param filePath 图片保存路径
		 */
		void onSuccess(String filePath);

		/**
		 * 下载失败
		 * @param errorMsg 失败原因
		 */
		void onFailure(String errorMsg);
	}
}

