/**
 * Format number with thousand separators
 * @param value - Number to format
 * @param decimals - Number of decimal places (default: 0)
 * @param decimalSeparator - Decimal separator (default: ',')
 * @param thousandSeparator - Thousand separator (default: '.')
 * @returns Formatted number string
 * 
 * @example
 * numberFormat(1234567.89) // "1.234.567"
 * numberFormat(1234567.89, 2) // "1.234.567,89"
 * numberFormat(1234.5, 2, '.', ',') // "1,234.50"
 */
export function numberFormat(
    value: number | string | null | undefined,
    decimals: number = 0,
    decimalSeparator: string = ',',
    thousandSeparator: string = '.'
): string {
    if (value === null || value === undefined || value === '') {
        return '0';
    }

    const num = typeof value === 'string' ? parseFloat(value) : value;
    
    if (isNaN(num)) {
        return '0';
    }

    const fixedNum = num.toFixed(decimals);
    const parts = fixedNum.split('.');
    
    // Format integer part with thousand separator
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator);
    
    // Join with decimal separator if decimals exist
    if (decimals > 0 && parts[1]) {
        return parts.join(decimalSeparator);
    }
    
    return parts[0];
}

/**
 * Format number as currency (Indonesian Rupiah)
 * @param value - Number to format
 * @param decimals - Number of decimal places (default: 0)
 * @param prefix - Currency prefix (default: 'Rp ')
 * @returns Formatted currency string
 * 
 * @example
 * currencyFormat(1234567) // "Rp 1.234.567"
 * currencyFormat(1234567.89, 2) // "Rp 1.234.567,89"
 */
export function currencyFormat(
    value: number | string | null | undefined,
    decimals: number = 0,
    prefix: string = 'Rp '
): string {
    return prefix + numberFormat(value, decimals);
}

/**
 * Format number as percentage
 * @param value - Number to format (0-100 or 0-1)
 * @param decimals - Number of decimal places (default: 2)
 * @param isDecimal - Whether value is in decimal form (0-1) or percentage form (0-100)
 * @returns Formatted percentage string
 * 
 * @example
 * percentageFormat(45.5) // "45,50%"
 * percentageFormat(0.455, 2, true) // "45,50%"
 */
export function percentageFormat(
    value: number | string | null | undefined,
    decimals: number = 2,
    isDecimal: boolean = false
): string {
    if (value === null || value === undefined || value === '') {
        return '0%';
    }

    const num = typeof value === 'string' ? parseFloat(value) : value;
    
    if (isNaN(num)) {
        return '0%';
    }

    const percentage = isDecimal ? num * 100 : num;
    return numberFormat(percentage, decimals) + '%';
}

/**
 * Format file size
 * @param bytes - File size in bytes
 * @param decimals - Number of decimal places (default: 2)
 * @returns Formatted file size string
 * 
 * @example
 * fileSizeFormat(1024) // "1,00 KB"
 * fileSizeFormat(1048576) // "1,00 MB"
 */
export function fileSizeFormat(
    bytes: number | string | null | undefined,
    decimals: number = 2
): string {
    if (bytes === null || bytes === undefined || bytes === '') {
        return '0 Bytes';
    }

    const num = typeof bytes === 'string' ? parseFloat(bytes) : bytes;
    
    if (num === 0) return '0 Bytes';
    if (isNaN(num)) return '0 Bytes';

    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
    const i = Math.floor(Math.log(Math.abs(num)) / Math.log(k));
    
    return numberFormat(num / Math.pow(k, i), decimals) + ' ' + sizes[i];
}

/**
 * Abbreviate large numbers
 * @param value - Number to abbreviate
 * @param decimals - Number of decimal places (default: 1)
 * @returns Abbreviated number string
 * 
 * @example
 * abbreviateNumber(1234) // "1,2 K"
 * abbreviateNumber(1234567) // "1,2 M"
 * abbreviateNumber(1234567890) // "1,2 B"
 */
export function abbreviateNumber(
    value: number | string | null | undefined,
    decimals: number = 1
): string {
    if (value === null || value === undefined || value === '') {
        return '0';
    }

    const num = typeof value === 'string' ? parseFloat(value) : value;
    
    if (isNaN(num)) {
        return '0';
    }

    if (Math.abs(num) < 1000) {
        return numberFormat(num, 0);
    }

    const units = ['K', 'M', 'B', 'T'];
    const unit = Math.floor((Math.abs(num).toString().length - 1) / 3);
    const unitValue = Math.pow(1000, unit);
    const shortValue = num / unitValue;

    return numberFormat(shortValue, decimals) + ' ' + units[unit - 1];
}

/**
 * Parse formatted number string back to number
 * @param value - Formatted number string
 * @param decimalSeparator - Decimal separator used in the string
 * @param thousandSeparator - Thousand separator used in the string
 * @returns Parsed number
 * 
 * @example
 * parseNumber("1.234.567,89") // 1234567.89
 * parseNumber("1,234.50", '.', ',') // 1234.50
 */
export function parseNumber(
    value: string | null | undefined,
    decimalSeparator: string = ',',
    thousandSeparator: string = '.'
): number {
    if (!value) return 0;

    // Remove thousand separators and replace decimal separator with dot
    const cleanValue = value
        .replace(new RegExp('\\' + thousandSeparator, 'g'), '')
        .replace(decimalSeparator, '.');
    
    const num = parseFloat(cleanValue);
    return isNaN(num) ? 0 : num;
}

/**
 * Format phone number to Indonesian format
 * @param value - Phone number to format
 * @returns Formatted phone number
 * 
 * @example
 * phoneFormat("081234567890") // "0812-3456-7890"
 * phoneFormat("628123456789") // "62-812-3456-7890"
 */
export function phoneFormat(value: string | null | undefined): string {
    if (!value) return '';
    
    const cleaned = value.replace(/\D/g, '');
    
    if (cleaned.startsWith('62')) {
        // International format
        const match = cleaned.match(/^(\d{2})(\d{3})(\d{4})(\d+)$/);
        if (match) {
            return `${match[1]}-${match[2]}-${match[3]}-${match[4]}`;
        }
    } else if (cleaned.startsWith('0')) {
        // Local format
        const match = cleaned.match(/^(\d{4})(\d{4})(\d+)$/);
        if (match) {
            return `${match[1]}-${match[2]}-${match[3]}`;
        }
    }
    
    return cleaned;
}

/**
 * Capitalize first letter of each word
 * @param value - String to capitalize
 * @returns Capitalized string
 * 
 * @example
 * capitalize("hello world") // "Hello World"
 */
export function capitalize(value: string | null | undefined): string {
    if (!value) return '';
    
    return value
        .toLowerCase()
        .split(' ')
        .map(word => word.charAt(0).toUpperCase() + word.slice(1))
        .join(' ');
}

/**
 * Truncate string with ellipsis
 * @param value - String to truncate
 * @param length - Maximum length
 * @param suffix - Suffix to add (default: '...')
 * @returns Truncated string
 * 
 * @example
 * truncate("Hello World", 8) // "Hello..."
 */
export function truncate(
    value: string | null | undefined,
    length: number,
    suffix: string = '...'
): string {
    if (!value) return '';
    if (value.length <= length) return value;
    
    return value.substring(0, length) + suffix;
}
