package eu.dnetlib.data.claims.handler;

import eu.dnetlib.data.claims.entity.Notification;
import eu.dnetlib.data.claims.sql.SQLStoreException;
import eu.dnetlib.data.claims.sql.SqlDAO;
import eu.dnetlib.data.claims.utils.QueryGenerator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

public class NotificationHandler {
    SqlDAO sqlDAO = null;
    QueryGenerator queryGenerator = null;

    private static final Logger logger = LogManager.getLogger(NotificationHandler.class);

    @Autowired
    private String targetHour;
    @Autowired
    private String targetMinute;
    @Autowired
    private String targetSecond;
    @Autowired
    private String defaultFrequencyInHours;

    public String buildAndInsertNotification(String openaireId, String userMail, int frequency, boolean notify) throws Exception, SQLStoreException {
        String id = null;

        logger.info("Trying to create a notification {openaireId:"+openaireId+", userMail:"+userMail+", frequency:"+frequency+", notify:"+notify+"}");
        Notification notification = buildNotification(openaireId, userMail, frequency, notify);

        id = saveNotification(notification);

        return id;
    }

    private Notification buildNotification(String openaireId, String userMail, int frequency, boolean notify) {
        Notification notification = new Notification();
        notification.setOpenaireId(openaireId);
        notification.setUserMail(userMail);

        Date dateNow = new Date();

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,Integer.parseInt(targetHour));
        calendar.set(Calendar.MINUTE,Integer.parseInt(targetMinute));
        calendar.set(Calendar.SECOND,Integer.parseInt(targetSecond));
        Date dateTodayAtTargetHour = calendar.getTime();

        if(dateNow.after(dateTodayAtTargetHour)) {
            //calendar.add(Calendar.SECOND,1);
            notification.setDate(calendar.getTime());
        } else {
            calendar.add(Calendar.HOUR_OF_DAY, -Integer.parseInt(defaultFrequencyInHours));
            //calendar.add(Calendar.SECOND, 1);
            notification.setDate(calendar.getTime());
        }
        
        notification.setFrequency(frequency);
        notification.setNotify(notify);

        return notification;
    }

    private String saveNotification(Notification notification) throws SQLStoreException, SQLException {
        logger.info("Saving notification...");
        String id = null;
        ArrayList<Object> params = new ArrayList<>();
        String query = generateSaveQueryForNotification(notification, params);
        ResultSet rs = sqlDAO.executePreparedQuery(query, params);
        if(rs.next()) {
            id = rs.getString(1);
        }
        rs.close();
        return id;
    }

    private String  generateSaveQueryForNotification(Notification notification, ArrayList<Object> params){
        String query= null;
        query = queryGenerator.generateInsertNotificationQuery(notification.getDate(), notification.getOpenaireId(), notification.getUserMail(), notification.getFrequency(), notification.isNotify(), params);
        return query;
    }

    public boolean updateNotificationPreferences(String openaireId, String userMail, int frequency, boolean notify) throws SQLStoreException, SQLException, Exception {
        logger.info("Updating notification...");
        ArrayList<Object> params = new ArrayList<>();
        //Date date = new Date();
        String query = queryGenerator.generateUpdateNotificationPreferences(openaireId, userMail, frequency, notify, params);
        //ResultSet rs = sqlDAO.executeUpdateQuery(query, params);
        return sqlDAO.executeUpdateQuery(query, params);
    }

    public boolean updateNotificationLastInteractionDate(String openaireId, String userMail, Date date) throws SQLStoreException, SQLException, Exception {
        logger.info("Updating notification...");
        ArrayList<Object> params = new ArrayList<>();
        String query = queryGenerator.generateUpdateNotificationLastInteractionDate(openaireId, userMail, date, params);
        return sqlDAO.executeUpdateQuery(query, params);
    }

    public SqlDAO getSqlDAO() {
        return sqlDAO;
    }
    public void setSqlDAO(SqlDAO sqlDAO) {
        this.sqlDAO = sqlDAO;
    }

    public QueryGenerator getQueryGenerator() {
        return queryGenerator;
    }
    public void setQueryGenerator(QueryGenerator queryGenerator) {
        this.queryGenerator = queryGenerator;
    }
}
