package com.enactor.pos.automation.peripherals;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.enactor.core.automation.AUT.AutomationException;

public class PrimaryPrinter {

	/**
	 * returns Transaction ID which display in test printer
	 *
	 * eg:-
	 *
	 * <code>
	 * <font face="monospace" size="12">               Enactor House
	 * <br>                1 Bluecoats
	 * <br>                  Hertford
	 * <br>               Hertfordshire
	 * <br>                  SG14 1PB
	 * <br>             Tel: 01992 500881
	 * <br>                  </font>
	 * <font face="monospace" size="24"><b>Sale</b></font>
	 * <font face="monospace" size="12">
	 * <br>-------------------------------------------
	 * <br>Salesperson:  Sarah Maroon
	 * <br>  Enactor-Bar Signature               £18.00
	 * <br>    £3 off of KAT VON D Eye Liner
	 * <br>  Enactor-Bar Signature               £18.00
	 * <br>    £3 off of KAT VON D Eye Liner
	 * <br></font>
	 * <font face="monospace" size="12"><b>Promotion Saving
	 * <br></b></font>
	 * <font face="monospace" size="12">  £3 off of KAT VON D Eye Liner       £6.00
	 * <br>-------------------------------------------
	 * <br>  </font>
	 * <font face="monospace" size="24"><b>TOTAL</b></font>
	 * <font face="monospace" size="12">                    </font>
	 * <font face="monospace" size="24"><b>£30.00</b></font>
	 * <font face="monospace" size="12">
	 * <br>  Cash UK                            £30.00
	 * <br>--------------------------------------------
	 * <br>           00010001000241810221024457
	 * <br>
	 * <br>      Thankyou for shopping at Enactor
	 * <br>22/10/18 12:33  Sarah Maroon  0001 0001 0024
	 * <br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	 * <br></font>
	 * <code>
	 *
	 * @param String
	 * @throws AutomationException
	 */
	public static String getTransactionId(String receiptText) throws AutomationException{
		String transactionId = null;
		String text = removeWhiteSpaces(receiptText);

		// extract the set of 26 digits from the receipt
		// this will give the transaction ID
		String pattern = "\\d{26}";
		Pattern p = Pattern.compile(pattern);
		Matcher m = p.matcher(text);
		if (m.find()) {
			transactionId = m.group();
		} else {
			throw new AutomationException(String.format("Could not find transaction id in '%s'", text));
		}

		return transactionId;
	}

	/**
	 * return Terminal ID display in test printer
	 *
	 * @param String
	 * @throws AutomationException
	 */
	public static String getTerminalId(String receiptText) throws AutomationException{
		String terminalId = null;
		String pattern = "(?<=<br>)([0-9].*?)(?=<br>)";
		Pattern p = Pattern.compile(pattern);
		Matcher m = p.matcher(receiptText);
		while(m.find()) {
			String[] ary = (m.group(1)).split(" ");
			terminalId = ary[ary.length - 2];
		}

		return terminalId;
	}

	/**
	 * return Terminal ID display in test printer
	 *
	 * @param String
	 * @throws AutomationException
	 */
	public static String getTransactionNumber(String receiptText) throws AutomationException{
		String terminalId = null;
		String pattern = "(?<=<br>)([0-9].*?)(?=<br>)";
		Pattern p = Pattern.compile(pattern);
		Matcher m = p.matcher(receiptText);
		while(m.find()) {
			String[] ary = (m.group(1)).split(" ");
			terminalId = ary[ary.length - 1];
		}

		return terminalId;
	}

	/**
	 * return Transaction details displayed in test printer
	 *
	 * @param String
	 * @throws AutomationException
	 */
	public static Map<String,String> getTransactionDetails(String receiptText) throws AutomationException {
		String text = removeWhiteSpaces(receiptText);
		Map<String,String> details = new HashMap<>();

		details.put("TRANSACTION_ID", getTransactionId(text));
		details.put("TERMINAL_NUMBER", getTerminalId(text));
		details.put("TRANSACTION_NUMBER", getTransactionNumber(text));

		return details;
	}

	/**
	 * return Report details displayed in test printer
	 *
	 * Eg: Receipt Report Text
	 * 	<html>
  	 *		<head>
     *
     *  	</head>
     *  	<body>
     *      	<font face="monospace" size="12">
     *      	<br>
     *      	<br>
     *      		</font><font face="monospace" size="12"><b><u>TENDER TOTALS REPORT</u></b></font><font face="monospace" size="12">
     *      		<br><br><br>Terminal: 1         Location: Enactor Store
     *      		<br>From:     24/04/19  To:       24/04/19
     *      		<br>
     *      		<br>
     *      		<br>    </font><font face="monospace" size="12"><b>No data for the specified criteria.</b></font><font face="monospace" size="12">
     *      		<br>
     *      		<br>
     *      		<br>       Report run at 4/26/19 10:41 AM<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br></font>
     *  	</body>
     *  </html>
	 *
	 * @param String
	 * @throws AutomationException
	 */
	public static Map<String, String> getReceiptReportDetails(String receiptText) throws AutomationException {
		Map<String, String> reportDetails = new HashMap<>();
		String receiptReportString = removeWhiteSpaces(receiptText);

		reportDetails.put("REPORT TITLE", getReportTitle(receiptReportString));
		reportDetails.put("TERMINAL", getTerminalNumber(receiptReportString));
		reportDetails.put("LOCATION", getLocation(receiptReportString));
		reportDetails.put("PERIOD FROM", getReportPeriodStartDate(receiptReportString));
		reportDetails.put("PERIOD TO", getReportPeriodEndDate(receiptReportString));
		reportDetails.put("REPORT DATE", getReportGenerateDate(receiptReportString));
		return reportDetails;
	}

	private static String getReportTitle(String reportText) throws AutomationException {
		return getMatchingText(reportText, "(?<=(<u>))(.*[A-Z])(?=</u>)").trim();
	}

	private static String getTerminalNumber(String reportText) throws AutomationException {
		return getMatchingText(reportText, "(?<=Terminal:).*(?=Location)").trim();
	}

	private static String getLocation(String reportText) throws AutomationException {
		return getMatchingText(reportText, "(?<=Location:.).*?(?=<)").trim();
	}

	private static String getReportPeriodStartDate(String reportText) throws AutomationException {
		return getMatchingText(reportText, "(?<=From:).*(?=To)").trim();
	}

	private static String getReportPeriodEndDate(String reportText) throws AutomationException {
		return getMatchingText(reportText, "(?<=To:).*?(?=<)").trim();
	}

	private static String getReportGenerateDate(String reportText) throws AutomationException {
		return getMatchingText(reportText, "(?<=Report run at).*?(?=<)").trim();
	}

	private static String getMatchingText(String text, String pattern) throws AutomationException {
		String match = null;
		Pattern p = Pattern.compile(pattern);
		Matcher m = p.matcher(text);
		while (m.find()) {
			match = m.group();
		}
		if (match == null) {
			throw new AutomationException("Could not find match for pattern " + pattern + " in report document. [Document] :" + text);
		}
		return match;
	}

	private static String removeWhiteSpaces(String text) {
		List<String> whiteSpaces = Arrays.asList("&#160;","&nbsp;");
		String strOutput = text;

		for(String whiteSpace : whiteSpaces) {
			strOutput = strOutput.replaceAll(whiteSpace, " ");
		}
		return  strOutput;
	}


}
