/***********************************************************************************************************
 * Name         : FormatUtils
 * Purpose      : Hold methods responsible for data formatting
 **********************************************************************************************************/

public with sharing class FormatUtils {
    public static final String FIELD_TYPE_CURRENCY = Schema.DisplayType.CURRENCY.toString();
    public static final String FIELD_TYPE_PERCENT = Schema.DisplayType.PERCENT.toString();
    public static final String FIELD_TYPE_BOOLEAN = Schema.DisplayType.BOOLEAN.toString();
    public static final String FIELD_TYPE_DATE = Schema.DisplayType.DATE.toString();
    public static final String FIELD_TYPE_DATETIME = Schema.DisplayType.DATETIME.toString();
    public static final String FIELD_TYPE_MULTIPICKLIST = Schema.DisplayType.MULTIPICKLIST.toString();
    public static final String FIELD_TYPE_NUMBER = Schema.DisplayType.INTEGER.toString();

    public static final List<String> NUMERIC_TYPES = new List<String>{
        Schema.DisplayType.DOUBLE.toString(),
        FIELD_TYPE_PERCENT,
        FIELD_TYPE_CURRENCY,
        Schema.DisplayType.INTEGER.toString()
    };

    /**
     * @description Formats fields based on their type so they can be displayed as Strings
     * @param sObj  SObject record
     * @param field field to format
     * @param fieldType field type
     */
    public static String formatFieldsToString(SObject sObj, String field, String fieldType) {
        Object value = sObj.get(field);
        if (value == null) {
            return '';
        }

        if (NUMERIC_TYPES.contains(fieldType)) {
            Decimal decimalValue = Decimal.valueOf(String.valueOf(value));
            String formattedValue = decimalValue.format();
            if (fieldType == FIELD_TYPE_CURRENCY) {
                String currencyIsoCode = String.valueOf(sObj.get(CurrencyUtils.CURRENCY_ISO_CODE));
                return String.valueOf(currencyIsoCode) + ' ' + formattedValue;
            }
            if (fieldType == FIELD_TYPE_PERCENT) {
                return decimalValue.setScale(1) + ' %';
            }
            return formattedValue;
        }
        if (fieldType == FIELD_TYPE_BOOLEAN) {
            return (Boolean) value ? 'Yes' : 'No';
        }
        if (fieldType == FIELD_TYPE_DATE) {
            return ((Date) value).format();
        }
        if (fieldType == FIELD_TYPE_DATETIME) {
            return ((Datetime) value).format();
        }
        if (fieldType == FIELD_TYPE_MULTIPICKLIST) {
            return String.valueOf(value).replace(';', ', ');
        }
        return String.valueOf(value);
    }

    /**
     * Formats a value based on its field type and currency ISO code.
     *
     * @param value The value to format (can be numeric, boolean, date, or string)
     * @param fieldType The type of the field (e.g., currency, percent, boolean, date)
     * @param currencyIsoCode The currency ISO code to prepend for currency fields
     * @return The formatted value as a string
     */
    public static String formatValue(Object value, String fieldType, String currencyIsoCode) {
        String result = '';
        if (value != null) {
            if (NUMERIC_TYPES.contains(fieldType)) {
                String formattedValue = Decimal.valueOf(String.valueOf(value)).format();
                if (fieldType == FIELD_TYPE_CURRENCY) {
                    result = currencyIsoCode + ' ' + formattedValue;
                } else {
                    result = fieldType == FIELD_TYPE_PERCENT
                        ? Decimal.valueOf(String.valueOf(value)).setScale(1) + ' %'
                        : formattedValue;
                }
            } else if (fieldType == FIELD_TYPE_BOOLEAN) {
                result = (Boolean) value ? 'Yes' : 'No';
            } else if (fieldType == FIELD_TYPE_DATE) {
                result = ((Date) value).format();
            } else {
                result = String.valueOf(value);
            }
        }
        return result;
    }
}
