import bigDecimal from 'js-big-decimal';
import { Address, CommonUtils } from 'libnexa-ts';

/** Maximum value for a 64-bit signed integer */
export const MAX_INT64: bigint = 9223372036854775807n;

/**
 * Get the current Unix timestamp in seconds
 * 
 * @returns Current timestamp as number of seconds since Unix epoch
 * 
 * @example
 * ```typescript
 * const now = currentTimestamp();
 * console.log('Current time:', now);
 * ```
 */
export function currentTimestamp() {
    return Math.floor(Date.now() / 1000);
}

/**
 * Check if a value is null, undefined, or empty
 * 
 * @param arg - The value to check
 * @returns true if the value is null, undefined, empty string, or empty array
 * 
 * @example
 * ```typescript
 * isNullOrEmpty(''); // true
 * isNullOrEmpty([]); // true
 * isNullOrEmpty(null); // true
 * isNullOrEmpty('hello'); // false
 * ```
 */
export function isNullOrEmpty(arg?: string | any[] | null): arg is undefined | [] | null | '' {
    return !arg || arg.length === 0;
}

/**
 * Parse an amount with decimal places and format it for display
 * 
 * Converts a raw amount to a human-readable format by dividing by 10^decimals
 * and removing trailing zeros.
 * 
 * @param amount - The raw amount to parse
 * @param decimals - Number of decimal places
 * @returns Formatted amount string
 * 
 * @example
 * ```typescript
 * parseAmountWithDecimals(1000000, 6); // '1'
 * parseAmountWithDecimals(1500000, 6); // '1.5'
 * parseAmountWithDecimals(1000000n, 6); // '1'
 * ```
 */
export function parseAmountWithDecimals(amount: string | number | bigint, decimals: number) {
    let val = new bigDecimal(amount).divide(new bigDecimal(Math.pow(10, decimals)), decimals).getPrettyValue();
    if (val.match(/\./)) {
        val = val.replace(/\.?0+$/, '');
    }
    return val;
}

/**
 * Convert a decimal amount to raw integer format
 * 
 * Multiplies the amount by 10^decimals to get the raw integer representation
 * used in transactions.
 * 
 * @param amount - The decimal amount to convert
 * @param decimals - Number of decimal places
 * @returns Raw amount as string
 * 
 * @example
 * ```typescript
 * getRawAmount('1.5', 6); // '1500000'
 * getRawAmount(1.5, 6); // '1500000'
 * ```
 */
export function getRawAmount(amount: string | number | bigint, decimals: number) {
    return new bigDecimal(amount).multiply(new bigDecimal(Math.pow(10, decimals))).getValue();
}

/**
 * Get the buffer representation of an address
 * 
 * @param address - The address string (hex or Nexa address format)
 * @returns Buffer containing the address data
 * 
 * @example
 * ```typescript
 * const buffer = getAddressBuffer('nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc');
 * const hexBuffer = getAddressBuffer('a1b2c3d4e5f6');
 * ```
 */
export function getAddressBuffer(address: string) {
    if (CommonUtils.isHexa(address)) {
        return Buffer.from(address, 'hex') ;
    }
    return Address.fromString(address).data;
}

/**
 * Convert a token ID to hex format
 * 
 * @param token - The token ID (hex string or Nexa address format)
 * @returns Token ID in hex format
 * 
 * @example
 * ```typescript
 * const hexId = tokenIdToHex('nexatest:tq8r37lcjlqazz7vuvug84q2ev50573hesrnxkv9y6hvhhl5k5qqqnmyf79mx');
 * const hexId2 = tokenIdToHex('a1b2c3d4e5f6'); // already hex, returns as-is
 * ```
 */
export function tokenIdToHex(token: string) {
    if (CommonUtils.isHexa(token)) {
        return token;
    }
    return getAddressBuffer(token).toString('hex');
}


