package com.prime.sony.ecommerce.util;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.BatchStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClientBuilder;
import com.amazonaws.services.simpleemail.model.Body;
import com.amazonaws.services.simpleemail.model.Content;
import com.amazonaws.services.simpleemail.model.Destination;
import com.amazonaws.services.simpleemail.model.Message;
import com.amazonaws.services.simpleemail.model.SendEmailRequest;
import com.prime.sony.ecommerce.exceptions.OrderServiceException;
import com.prime.sony.ecommerce.model.Email;
import com.prime.sony.ecommerce.model.ExceptionMessage;

@Component
public class MailService {

	private static final Logger log = LoggerFactory.getLogger(MailService.class);

	@Autowired
	private ExceptionMessage exceptionMessage;

	@Autowired
	private Email email;

	private static AmazonSimpleEmailService emailService;

	public MailService(@Value("${aws.region}") String region) {
		try {
			emailService = AmazonSimpleEmailServiceClientBuilder.standard().withRegion(region).build();

		} catch (Exception ex) {
			System.out.println("AmazonSimpleEmailService failed to build. Error message: " + ex.getMessage());
		}
	}

	public void processEmail(String subject, String body) throws Exception {

		if (email.getEnv().equalsIgnoreCase("dev_")) {
			body = body + "</br></br> dev version:" + email.getVersion();
			// SKIPPING EMAIL FROM DEV ENVIRONMENT
        	System.out.println("Skipping email send in DEV");
        	return;
		}

		String[] toEmailList = email.getTo().split(",");

		SendEmailRequest request = new SendEmailRequest()
				.withDestination(new Destination().withToAddresses(toEmailList))
				.withMessage(new Message()
						.withBody(new Body().withHtml(new Content().withCharset("UTF-8").withData(body))
								.withText(new Content().withCharset("UTF-8").withData("")))
						.withSubject(new Content().withCharset("UTF-8").withData(subject)))
				.withSource(email.getFrom());

		emailService.sendEmail(request);
		System.out.println("Email sent!");
	}

	public void mailsending(Map<String, String> resultMap, String jobId, String batchIds, Date jobStartDate)
			throws OrderServiceException {
		log.info("==>MailService.mailsending()");

		try {
			Date jobEndDate = new Date();
			SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
//	    	String jobStartTime = format.format(jobStartDate.getTime());
			String jobEndTime = format.format(jobEndDate.getTime());
			boolean isLoadService = false;
			String manualDataloasersubject = "";
			if (resultMap != null && resultMap.get("isLoadService") != null
					&& resultMap.get("isLoadService").equals("true")) {
				isLoadService = true;
				manualDataloasersubject = "MANUAL DATA LOAD ";
			}

			long millis = jobEndDate.getTime() - jobStartDate.getTime();
			String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
					TimeUnit.MILLISECONDS.toMinutes(millis)
							- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
					TimeUnit.MILLISECONDS.toSeconds(millis)
							- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));

			String subject = (email.getEnv() + manualDataloasersubject
					+ "JOB WITH FAILED RECORDS - ECOMMERCE_ORDERS to Salesforce Feed");

			String body = ("The feed from ECOMMERCE_ORDERS In Snowflake to the corresponding Salesforce object completed but with failed records. "
					+ "</br>" + "Completed: " + jobEndTime + "</br>" + "Run Time: " + hms + "</br>" + "Job ID: " + jobId
					+ "</br>" + "Batch ID: " + batchIds + "</br></br>" + "Success records count : "
					+ resultMap.get("SuccessCount") + "</br></br>" + "Update records count : "
					+ resultMap.get("UpsertCount") + "</br>" + "Failure records count : "
					+ resultMap.get("FailureCount") + "</br></br></br>"
					+ "Please contact your Salesforce Engineering team for support.  Job and Batch ID can be used to reference the error log table in Snowflake.");

			processEmail(subject, body);

		} catch (Exception e) {
			log.error("==>Exception at MailService.mailsending()", e);
			throw new OrderServiceException(e.getMessage(), e.getCause(), null);
		}
		log.info("<==MailService.mailsending()");
	}

	public void sentJobExecutionMail(Map<String, String> resultMap, BatchStatus status, String endDate, String hms)
			throws OrderServiceException {
		log.info("==>MailService.sentJobExecutionMail()");

		String subject = "";
		String body = "";

		String successCount = "";
		String upsertCount = "";
		String failureCount = "";
		String jobID = "";
		String batchID = "";
		String snowflakeRecordCount = "";
		String nodataFound = "";
		boolean nodata = false;
		boolean isLoadService = false;
		String manualDataloasersubject = "";
		if (resultMap != null) {

			if (resultMap.get("isLoadService") != null && resultMap.get("isLoadService").equals("true")) {
				isLoadService = true;
				manualDataloasersubject = "MANUAL DATA LOAD ";
			}

			nodata = (resultMap.get("NODATA") != null && resultMap.get("NODATA").equals("true")) ? true : false;
			if (!nodata) {
				successCount = resultMap.get("SuccessCount") != null ? resultMap.get("SuccessCount") : "";
				failureCount = resultMap.get("FailureCount") != null ? resultMap.get("FailureCount") : "";
				upsertCount = resultMap.get("UpsertCount") != null ? resultMap.get("UpsertCount") : "";
				jobID = resultMap.get("JobID") != null ? resultMap.get("JobID") : "";
				batchID = resultMap.get("BatchIDs") != null ? resultMap.get("BatchIDs") : "";
				snowflakeRecordCount = resultMap.get("SnowflakeRecordscount") != null
						? resultMap.get("SnowflakeRecordscount")
						: "";
			} else {
				nodataFound = "No records found to feed from ECOMMERCE_ORDERS in Snowflake to "
						+ "the corresponding Salesforce object";
			}
		}

		try {

			if (status.equals(BatchStatus.STARTED)) {
				subject = (email.getEnv() + manualDataloasersubject
						+ "JOB STARTED - ECOMMERCE_ORDERS to Salesforce Feed");
				body = ("The feed from ECOMMERCE_ORDERS in Snowflake to the corresponding "
						+ "Salesforce object started at: " + endDate);

			} else if (status.equals(BatchStatus.COMPLETED)) {
				subject = (email.getEnv() + manualDataloasersubject
						+ "JOB COMPLETED - ECOMMERCE_ORDERS to Salesforce Feed");
				body = ("The feed from ECOMMERCE_ORDERS in Snowflake to the corresponding "
						+ "Salesforce object completed at: " + endDate + ".</br></br>Run Time: " + hms + ".");

			} else if (status.equals(BatchStatus.FAILED)) {
				subject = (email.getEnv() + manualDataloasersubject
						+ "JOB FAILED - ECOMMERCE_ORDERS to Salesforce Feed");

				body = "The feed from ECOMMERCE_ORDERS in Snowflake to the corresponding "
						+ "Salesforce object <u>FAILED</u> at: " + endDate + ".</br></br> Run Time: " + hms;
			}

			if (!status.equals(BatchStatus.STARTED)) {
				if (null != exceptionMessage.getServiceExceptionMessage()) {
					body = body + ".</br></br> Error : " + exceptionMessage.getServiceExceptionMessage();
				}
				if (nodataFound.equals("")) {
					body = body + "</br>" + "Job ID: " + jobID + "</br>" + "Batch ID: " + batchID + "</br>"
							+ "Snowflake records count: " + snowflakeRecordCount + "</br>" + "Insert records count : "
							+ successCount + "</br>" + "Update records count : " + upsertCount + "</br>"
							+ "Failure records count : " + failureCount + "</br></br></br>"
							+ "Please contact your Salesforce Engineering team for support.  Job and Batch ID can be used to reference the error log table in Snowflake.";

				} else {
					body = body + "</br></br>" + nodataFound;
				}

			}

			processEmail(subject, body);
		} catch (Exception e) {
			log.info("==> Exception at MailService.sentJobExecutionMail()", e);
			throw new OrderServiceException(e.getMessage(), e.getCause(), null);
		}
		log.info("<==MailService.sentJobExecutionMail()");

	}

}
