import ByteArrayOutputStream from "java.io.ByteArrayOutputStream";
import File from "java.io.File";
import FileOutputStream from "java.io.FileOutputStream";
import CompressFormat from "android.graphics.Bitmap.CompressFormat"
import Bitmap from "android.graphics.Bitmap";
import BitmapFactory from "android.graphics.BitmapFactory";
import URL from "java.net.URL";
import BufferedInputStream from "java.io.BufferedInputStream";
import HttpURLConnection from "java.net.HttpURLConnection";
import Manifest from "android.Manifest";
import PackageManager from "android.content.pm.PackageManager";
import ContextCompat from "androidx.core.content.ContextCompat";
import Environment from "android.os.Environment";

export default class Util {

	static getPackageName() : string {
		let context = UTSAndroid.getAppContext()!
		let packageManager = context.getPackageManager();
		let packageName = context.getPackageName();
		try {
			let applicationInfo = packageManager.getApplicationInfo(packageName, 0);
			let appName = packageManager.getApplicationLabel(applicationInfo).toString();
			return appName
		} catch (e) { }

		return 'MyApp'
	}

	static getPath(path ?: string, width : number, heitht : number, callback : (path : string | null) => void) {
		if (path == null || path == '') {
			callback(null)
		} else {
			if (this.isNetworkImage(path)) {
				this.getNetworkBitmap(path, (bmp : Bitmap | null) => {
					if (bmp != null) {
						let ls = path.split('/')
						let fileName = ls[ls.length - 1]
						let _path:string
						if (width > 0) {
							let thumbBmp = Bitmap.createScaledBitmap(bmp, width.toInt(), heitht.toInt(), true);
							_path = this.bmpToPath(thumbBmp, fileName) ?? ''
						} else {
							_path = this.bmpToPath(bmp, fileName) ?? ''
						}
						
						callback(`file://${_path}`)
					} else {
						callback(path)
					}
				})
			} else {
				let _path = UTSAndroid.getResourcePath(path)
				callback(`file://${_path}`)
			}
		}
	}

	static getBitmap(path ?: string, width : number, heitht : number, callback : (bitmap : Bitmap | null, bytes : ByteArray | null) => void) {
		if (path == null || path == '') {
			callback(null, null)
		} else {
			if (this.isNetworkImage(path)) {
				this.getNetworkBitmap(path, (bmp : Bitmap | null) => {
					if (bmp != null) {
						let thumbBmp = Bitmap.createScaledBitmap(bmp, width.toInt(), heitht.toInt(), true);
						callback(bmp, this.bmpToByteArray(thumbBmp, true))
					} else {
						callback(null, null)
					}
				})
			} else {
				try {
					let _path = UTSAndroid.getResourcePath(path)
					let bmp = BitmapFactory.decodeFile(_path)

					if (bmp != null) {
						let thumbBmp = Bitmap.createScaledBitmap(bmp, width.toInt(), heitht.toInt(), true);
						callback(bmp, this.bmpToByteArray(thumbBmp, true))
					} else {
						callback(null, null)
					}
				} catch (e) {
					callback(null, null)
				}
			}
		}
	}

	static getNetworkBitmap(path ?: string, callback : (bitmap : Bitmap | null) => void) {
		if (path == null) {
			callback(null)
		}

		UTSAndroid.getDispatcher("io").async(function (_) {
			if (!Thread.currentThread().name.contains("DefaultDispatcher")) {
				callback(null)
				return
			}

			try {
				let connection = new URL(path!).openConnection() as HttpURLConnection
				connection.connect()

				let inputStream = new BufferedInputStream(connection.inputStream)
				let bitmap = BitmapFactory.decodeStream(inputStream)

				inputStream.close()

				callback(bitmap)
			} catch (e) {
				console.error(e);
				callback(null)
			}
		}, null)
	}

	static bmpToByteArray(bmp : Bitmap, needRecycle : boolean) : ByteArray {
		let output = new ByteArrayOutputStream();

		bmp.compress(CompressFormat.PNG, 100, output);

		if (needRecycle) {
			bmp.recycle();
		}

		let result = output.toByteArray();

		try {
			output.close();
		} catch (e) {
			e.printStackTrace();
		}

		return result;
	}

	static bmpToPath(bitmap : Bitmap | null, fileName: string) : string | null {
		if(bitmap == null) {
			return null
		}
		
		if (ContextCompat.checkSelfPermission(UTSAndroid.getAppContext()!, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
			return null;
		}

		let directory = UTSAndroid.getAppContext()!.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
		let file = new File(directory, fileName);
		try {
			let outputStream = new FileOutputStream(file);

			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
			outputStream.flush();
			outputStream.close();
			
			return file.getAbsolutePath();
		} catch (e) {
			return null;
		}
	}

	static isNetworkImage(imagePath : String) : boolean {
		return imagePath.startsWith("http://") || imagePath.startsWith("https://")
	}
}