package com.utopiaindustries.dialect;

import com.utopiaindustries.model.CurrencySymbol;
import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.engine.AttributeName;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractAttributeTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.standard.expression.IStandardExpression;
import org.thymeleaf.standard.expression.IStandardExpressionParser;
import org.thymeleaf.standard.expression.StandardExpressions;
import org.thymeleaf.templatemode.TemplateMode;

import java.text.NumberFormat;
import java.util.Locale;

// https://docs.oracle.com/javase/tutorial/i18n/format/numberFormat.html
// https://www.localeplanet.com/icu/en-PK/index.html
public class FormatNumberTagProcessor extends AbstractAttributeTagProcessor {
	private static final String ATTR_NAME = "formatnumber";
	private static final int PRECEDENCE = 100000;

	public FormatNumberTagProcessor( final String dialectPrefix ) {
		super(
				TemplateMode.HTML,
				dialectPrefix,
				null,
				false,
				ATTR_NAME,
				true,
				PRECEDENCE,
				true
		);
	}

	protected void doProcess( ITemplateContext iTemplateContext, IProcessableElementTag iProcessableElementTag, AttributeName attributeName, String attributeValue, IElementTagStructureHandler iElementTagStructureHandler ) {
		final IEngineConfiguration configuration = iTemplateContext.getConfiguration();
		final IStandardExpressionParser parser = StandardExpressions.getExpressionParser( configuration );
		final IStandardExpression expression = parser.parseExpression( iTemplateContext, attributeValue );
		final String attributeValueParsed = ( String ) expression.execute( iTemplateContext );
		// get arguments from comma separated list
		String[] args = attributeValueParsed.split( "," );
		double amount = Double.parseDouble( args[0] );
		String currencyCode = args[1];
		// create locale
		Locale locale = new Locale( CurrencySymbol.valueOf( currencyCode ).getLanguage(), CurrencySymbol.valueOf( currencyCode ).getLocation() );
		// formatted amount in the specified locale
		NumberFormat formatter = NumberFormat.getNumberInstance( locale );
		// check if decimals required
		int fractionDigits;
		if ( args.length == 3 ) {
			fractionDigits = Integer.parseInt( args[2] );
		} else {
			fractionDigits = 0;
		}
		formatter.setMaximumFractionDigits( fractionDigits );
		// if amount is less than zero, add brackets
		String formattedAmount = formatter.format( Math.abs( amount ) );
		if ( amount < 0 ) {
			formattedAmount = "(" + formattedAmount + ")";
		}
		// render the body
		iElementTagStructureHandler.setBody( formattedAmount, false );
	}
}
