// eslint-disable-next-line @typescript-eslint/no-unused-vars
declare interface Number {

	/**
	 * 金額每三位數(千)加逗號, 並且補到小數點第2位
	 * 輸出 41,038,560.00
	 * @param precision 補到小數點第幾位
	 * @param isPadZero 是否要補零(預設FALSE)
	 * */
	ExFormatNumberWithComma(precision?: number, isPadZero?: boolean): string;

	/**
	 * 基本4位數(9,999-999B-T)
	 * */
	ExTransferToBMK(precision?: number, offset?: number): string;

	/**
	 * 數字轉字串, 頭補0
	 * @param size
	 */
	Pad(size: number): string;

	/**
	 * 四捨五入到小數點第X位 (同server計算規則)
	 * @param precision
	 */
	ExToNumRoundDecimal(precision: number): number;

	/**
	 * 無條件捨去到小數點第X位
	 * @param precision
	 */
	ExToNumFloorDecimal(precision: number): number;

	/**
	 * 無條件捨去強制保留X位小數，如：2，會在2後面補上00.即2.00
	 * @param precision 補到小數點第幾位
	 * @param isPadZero 是否要補零(預設FALSE)
	 */
	ExToStringFloorDecimal(precision: number, isPadZero?: boolean): string;

	/**
	 * 取整數)
	 */
	ExToInt(): number;

	/**
	 * 小數轉整數(支援科學符號)
	 */
	Float2Fixed(): number;

	/**
	 * 數字長度(支援科學符號)
	 */
	DigitLength(): number;

	target: number;


}

Number.prototype.ExFormatNumberWithComma || Object.defineProperty(Number.prototype, "ExFormatNumberWithComma", {
	enumerable: false,
	value: function (precision: number = 2, isPadZero: boolean = false) {

		// let arr = String(this).split('.');
		const arr = this.ExToStringFloorDecimal(precision, isPadZero).split(".");
		let num = arr[0], result = "";
		while (num.length > 3) {
			result = "," + num.slice(-3) + result;
			num = num.slice(0, num.length - 3);
		}
		if (num.length > 0) result = num + result;
		return arr[1] ? result + "." + arr[1] : result;
	}
});


Number.prototype.ExTransferToBMK || Object.defineProperty(Number.prototype, "ExTransferToBMK", {
	enumerable: false,
	value: function (precision: number = 2, offset: number = 0) {
		/** 千 */
		const MONEY_1K: number = 1000;
		/** 萬 */
		// let MONEY_10K: number = 10000;
		/** 十萬 */
		// let MONEY_100K: number = 100000;
		/** 百萬 */
		const MONEY_1M: number = 1000000;
		/** 千萬 */
		// let MONEY_10M: number = 10000000;
		/** 億 */
		// let MONEY_100M: number = 100000000;
		/** 十億 */
		const MONEY_1B: number = 1000000000;
		/** 百億 */
		// let MONEY_10B: number = 10000000000;
		/** 千億 */
		// let MONEY_100B: number = 100000000000;
		/** 兆 */
		// let MONEY_1T: number = 1000000000000;
		offset = Math.pow(10, offset);
		// if (this >= MONEY_1T * offset) {
		//     //(3)1,000T
		//     //1T~
		//     return (~~(this / MONEY_1T)).ExFormatNumberWithComma(0) + "T";
		// }
		if (this >= MONEY_1B * offset) {
			// 1,000B~900,000B
			// 1B~900B
			return (this / MONEY_1B).ExFormatNumberWithComma(3, false) + "B";
		} else if (this >= MONEY_1M * offset) {
			// 1,000M~900,000M
			// 1M~900M
			return (this / MONEY_1M).ExFormatNumberWithComma(3, false) + "M";
		} else if (this >= MONEY_1K * offset) {
			// 1,000K~900,000K
			// 1K~90K
			return (this / MONEY_1K).ExFormatNumberWithComma(3, false) + "K";
		} else {
			// 0~9,000,000
			// 0~9,000
			return this.ExFormatNumberWithComma(precision);
		}
	}
});
Number.prototype.Pad || Object.defineProperty(Number.prototype, "Pad", {
	enumerable: false,
	value: function (size: number) {
		let s = this + "";
		while (s.length < size) s = "0" + s;
		return s;
	}
});
Number.prototype.ExToNumRoundDecimal || Object.defineProperty(Number.prototype, "ExToNumRoundDecimal", {
	enumerable: false,
	value: function (precision: number) {
		return Math.round(Math.round(this * Math.pow(10, (precision || 0) + 1)) / 10) / Math.pow(10, (precision || 0));
	}
});
Number.prototype.ExToInt || Object.defineProperty(Number.prototype, "ExToInt", {
	enumerable: false,
	value: function () {
		return ~~this;
	}
});
Number.prototype.ExToNumFloorDecimal || Object.defineProperty(Number.prototype, "ExToNumFloorDecimal", {
	enumerable: false,
	value: function (precision: number) {
		const str = this.toPrecision(12);
		const dotPos = str.indexOf(".");
		return dotPos == -1 ? this : +`${ str.substr(0, dotPos + 1 + precision) }`;
	}
});
Number.prototype.ExToStringFloorDecimal || Object.defineProperty(Number.prototype, "ExToStringFloorDecimal", {
	enumerable: false,
	value: function (precision: number, isPadZero: boolean = false) {
		// 取小數點第X位
		const f = this.ExToNumFloorDecimal(precision);
		let s = f.toString();
		// 補0
		if (isPadZero) {
			let rs = s.indexOf(".");
			if (rs < 0) {
				rs = s.length;
				s += ".";
			}
			while (s.length <= rs + precision) {
				s += "0";
			}
		}
		return s;
	}
});
Number.prototype.Float2Fixed || Object.defineProperty(Number.prototype, "Float2Fixed", {
	enumerable: false,
	value: function () {
		if (this.toString().indexOf("e") === -1) {
			return Number(this.toString().replace(".", ""));
		}
		const dLen = this.DigitLength();
		return dLen > 0 ? +parseFloat((this * Math.pow(10, dLen)).toPrecision(12)) : this;
	}
});
Number.prototype.DigitLength || Object.defineProperty(Number.prototype, "DigitLength", {
	enumerable: false,
	value: function () {
		const eSplit = this.toString().split(/[eE]/);
		const len = (eSplit[0].split(".")[1] || "").length - (+(eSplit[1] || 0));
		return len > 0 ? len : 0;
	}
});
