/********************************************************************************
 * Copyright (c) 2018 Mettenmeier GmbH 
 *
 * See the NOTICE file(s) distributed with this work for additional 
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0 
 ********************************************************************************/
package org.eclipse.openk.sp.mail;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.Properties;

import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.apache.log4j.Logger;
import org.eclipse.openk.common.Globals;
import org.eclipse.openk.sp.db.model.StandbyGroup;
import org.eclipse.openk.sp.db.model.StandbyScheduleBody;
import org.eclipse.openk.sp.db.model.User;
import org.eclipse.openk.sp.dto.planning.StandbyScheduleActionDto;
import org.eclipse.openk.sp.exceptions.SpException;
import org.eclipse.openk.sp.util.DateHelper;
import org.eclipse.openk.sp.util.FileHelper;
import org.eclipse.openk.sp.util.SpMsg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(rollbackFor = Exception.class)
public class MailRequest {

	/** Logger. */
	private Logger logger = Logger.getLogger(MailRequest.class);

	private static String testHost = "test.de";

	@Autowired
	private FileHelper fileHelper;

	@Autowired
	MailGenerator mailGenerator;

	/**
	 * Method to generate HTML Mail body. reports
	 * 
	 * @param planRequest
	 * @return
	 * @throws IOException
	 */
	public String generateHTML(String templateFile, Object... obj) throws IOException {

		logger.info("resource: " + templateFile);

		InputStream is = fileHelper.loadFileFromResource(templateFile);

		String newHtmlBody = null;
		if (is != null) {

			String htmlBody = FileHelper.getTextFromInputStream(is, StandardCharsets.UTF_8);

			newHtmlBody = MessageFormat.format(htmlBody, obj);

		}
		return newHtmlBody;

	}

	public HtmlEmail moveMessage1(StandbyScheduleActionDto actionDto, StandbyScheduleBody standbyBody,
			StandbyGroup targetGroup) {
		// Read config bundle for mail setting up mail
		HtmlEmail email = null;
		String template = "/mail/move_message.html";
		String subject = "Ihre Bereitschaft wurde verschoben";
		logger.info("moveMessage1() - start");

		try {
			Properties property = init(actionDto);

			if (property == null) {
				logger.info("no properties found");
				return null;
			} else {
				logger.info("properties found");
			}

			String link = property.getProperty(Globals.LINK_DASHBOARD);
			logger.info("read link from properties: " + link);

			String strSBFrom = DateHelper.convertToLocalString(standbyBody.getValidFrom(), null);
			String strSBTo = DateHelper.convertToLocalString(standbyBody.getValidTo(), null);
			String strAcFrom = DateHelper.convertToLocalString(actionDto.getValidFrom(), null);
			String strAcTo = DateHelper.convertToLocalString(actionDto.getValidTo(), null);

			String body = generateHTML(template, standbyBody.getStandbyGroup().getTitle(), strSBFrom, strSBTo,
					targetGroup.getTitle(), strAcFrom, strAcTo, link);

			email = calcMail(subject, standbyBody.getUser().getBusinessContactData().getEmail(), property, body);

			logger.info("recipients: " + email.getToAddresses());

			// send the email
			send(email);

			logger.info("mail was sended!");

		} catch (Exception e) {
			logger.info(e.getMessage(), e);
		}

		return email;
	}

	private void send(HtmlEmail email) throws EmailException {
		try {
			// send the email
			email.send();
		} catch (Exception e) {
			logger.info(e.getMessage(), e);
		}
	}

	public HtmlEmail replaceMessage1(StandbyScheduleActionDto actionDto, User oldUser, User newUser,
			StandbyGroup standbyGroup) {
		// Read config bundle for mail setting up mail
		HtmlEmail email = null;
		String template = "/mail/replace_message1.html";
		String subject = "Ihre Bereitschaft entfällt";
		logger.info("replaceMessage1() - start");

		try {
			Properties property = init(actionDto);

			if (property == null) {
				return null;
			}

			String userName = newUser.getFirstname() + " " + newUser.getLastname();
			String link = property.getProperty(Globals.LINK_DASHBOARD);
			String strAcFrom = DateHelper.convertToLocalString(actionDto.getValidFrom(), null);
			String strAcTo = DateHelper.convertToLocalString(actionDto.getValidTo(), null);

			String body = generateHTML(template, standbyGroup.getTitle(), strAcFrom, strAcTo,
					new String(userName.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8), link);

			email = calcMail(subject, oldUser.getBusinessContactData().getEmail(), property, body);

			logger.info("recipients: " + email.getToAddresses());

			// send the email
			send(email);

			logger.info("mail was sended!");

		} catch (Exception e) {
			logger.info(e.getMessage(), e);
		}

		return email;
	}

	public HtmlEmail replaceMessage2(StandbyScheduleActionDto actionDto, User oldUser, User newUser,
			StandbyGroup standbyGroup) {
		// Read config bundle for mail setting up mail
		HtmlEmail email = null;
		String template = "/mail/replace_message2.html";
		String subject = "Sie haben neue Bereitschaften erhalten";
		logger.info("replaceMessage2() - start");

		try {

			Properties property = init(actionDto);

			if (property == null) {
				return null;
			}

			String userName = oldUser.getFirstname() + " " + oldUser.getLastname();
			String link = property.getProperty(Globals.LINK_DASHBOARD);
			String strAcFrom = DateHelper.convertToLocalString(actionDto.getValidFrom(), null);
			String strAcTo = DateHelper.convertToLocalString(actionDto.getValidTo(), null);

			String body = generateHTML(template, standbyGroup.getTitle(),
					new String(userName.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8), strAcFrom, strAcTo,
					link);

			email = calcMail(subject, newUser.getBusinessContactData().getEmail(), property, body);

			logger.info("recipients: " + email.getToAddresses());

			// send the email
			send(email);

			logger.info("mail was sended!");

		} catch (Exception e) {
			logger.info(e.getMessage(), e);
		}

		return email;
	}

	public Properties init(StandbyScheduleActionDto actionDto) throws IOException {

		if (actionDto.getStatusId() == null
				|| actionDto.getStatusId().longValue() != SpMsg.STATUS_CLOSED_PLANNING.longValue()) {
			return null;
		}

		Properties property = fileHelper.loadPropertiesFromResource(Globals.APP_PROP_FILE_NAME);
		logger.info("read mail properties");

		String smtpActivated = property.getProperty(Globals.SMTP_ACTIVE);
		if (!Boolean.parseBoolean(smtpActivated)) {
			logger.info("mailing is deactivated");
			return null;
		}

		return property;

	}

	public HtmlEmail calcMail(String subject, String userMail, Properties properties, String body) throws SpException {

		String mailAddress = userMail;

		if (mailAddress == null || mailAddress.equals("") || mailAddress.contains(testHost)) {
			mailAddress = properties.getProperty(Globals.SMTP_BACKUP_RECIPIENT);
		}
		// sender
		String sendersName = properties.getProperty(Globals.SMTP_MAIL_SENDER_NAME);
		String sendersMail = properties.getProperty(Globals.SMTP_MAIL_SENDER_EMAIL);
		return mailGenerator.generateMail(null, mailAddress, sendersName, sendersMail, subject, body, properties);

	}

}
