package com.prime.sony.ecommerce.util;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
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.StoreServiceException;
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 StoreServiceException {
		log.info("==>MailService.mailsending()");
	

		try {
			Date jobEndDate = new Date();
			SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
	    	String jobEndTime = format.format(jobEndDate.getTime());
			
	    	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)));
			
			boolean isLoadService=false;
			String manualDataloasersubject="";

			if(resultMap!=null && resultMap.get("isLoadService")!=null  
					&& resultMap.get("isLoadService").equals("true")){				
				isLoadService=true;
				manualDataloasersubject="MANUAL DATA LOAD ";
			}
			
			
			String subject=email.getEnv()+ manualDataloasersubject+"JOB WITH FAILED RECORDS - ECOMMERCE_STORES to Salesforce Feed";
			
            String body="The feed from ECOMMERCE_STORES 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>Success records count : " + resultMap.get("SuccessCount")
					+"</br></br>" + "Update records count : "+resultMap.get("UpsertCount")
					+ "</br>Failure records count : " + resultMap.get("FailureCount")
					+ "</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 StoreServiceException(e.getMessage(), e.getCause(), null);
		}
		log.info("<==MailService.mailsending()");
	}

	public void sentJobExecutionMail(Map<String, String> resultMap,BatchStatus status, String endDate, String hms) throws StoreServiceException {
		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_STORES in Snowflake to "
						+ "the corresponding Salesforce object";
			}
		}

		try {
			
			if (status.equals(BatchStatus.STARTED)) {
			    subject=(email.getEnv()+manualDataloasersubject+"JOB STARTED - ECOMMERCE_STORES to Salesforce Feed");
				body=("The feed from ECOMMERCE_STORES in Snowflake to the corresponding "
						+ "Salesforce object started at: "+endDate);
			} else if (status.equals(BatchStatus.COMPLETED)) {
				subject=email.getEnv()+"JOB COMPLETED - ECOMMERCE_STORES to Salesforce Feed";
				body="The feed from ECOMMERCE_STORES in Snowflake to the corresponding "
						+ "Salesforce object completed at: "+endDate
						+".</br></br>Run Time: "+hms+".";
				
			} else if (status.equals(BatchStatus.FAILED)) {
				subject=email.getEnv()+"JOB FAILED - ECOMMERCE_STORES to Salesforce Feed";
				
				body = "The feed from ECOMMERCE_STORES 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 StoreServiceException(e.getMessage(), e.getCause(), null);
		}
		log.info("<==MailService.sentJobExecutionMail()");

	}

}
