package org.exoplatform.cs.job;

import org.exoplatform.commons.api.notification.NotificationContext;
import org.exoplatform.commons.api.notification.model.PluginKey;
import org.exoplatform.commons.notification.impl.NotificationContextImpl;
import org.exoplatform.container.ExoContainer;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.cs.dao.TopicDAO;
import org.exoplatform.cs.dto.TicketDTO;
import org.exoplatform.cs.entity.StatLogEntity;
import org.exoplatform.cs.entity.TopicEntity;
import org.exoplatform.cs.integration.notification.CSReminderPlugin;
import org.exoplatform.cs.integration.notification.CSSLAReminderPlugin;
import org.exoplatform.cs.service.CSConstants;
import org.exoplatform.cs.service.StatsService;
import org.exoplatform.cs.service.TicketService;
import org.exoplatform.cs.service.util.CSUtils;
import org.exoplatform.services.listener.ListenerService;
import org.exoplatform.services.organization.User;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.time.LocalDate;
import java.time.Period;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by eXo Platform SAS.
 *
 * @author Ali Hamdi 
 * @since 23/08/17 17:39
 */

public class AutoAssignJob implements Job {
  private static final Logger LOG = LoggerFactory.getLogger(AutoAssignJob.class);


  @Override
  public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    ExoContainer containerContext = ExoContainerContext.getCurrentContainer();
    TicketService ticketService = containerContext.getComponentInstanceOfType(TicketService.class);
    TopicDAO topicDAO = containerContext.getComponentInstanceOfType(TopicDAO.class);
    ListenerService listenerService = containerContext.getComponentInstanceOfType(ListenerService.class);
    List<TopicEntity> tickets = topicDAO.getNotAssignedTickets();
    Calendar calendar = Calendar.getInstance();
    for (TopicEntity ticket : tickets) {
      if (ticket.getAutoAssignDate() != null && ticket.getAutoAssignDate().before(calendar)) {

        if (ticket.getAssignee() == null) {
          try {
            Map<String, Integer> usersMap = new HashMap<>();
            for (User user : CSUtils.getSupportAutoAssignees()) {
              usersMap.put(user.getUserName(), 0);
            }
            List<Object[]> results = new ArrayList<>();
            results = topicDAO.countUnresolvedTicketsGroupdByAssignee();
            String assignee = "";
            int ticketNumber = 5000;
            for (int i = 0; i < results.size(); i++) {
              Object[] arr = results.get(i);
              if ((String) arr[0] != null) {
                if (usersMap.containsKey((String) arr[0])) {
                  usersMap.put((String) arr[0], ((Long) arr[1]).intValue());
                }
              }
            }
            for (Map.Entry<String, Integer> entry : usersMap.entrySet()) {
              if (entry.getValue().intValue() == 0) {
                assignee = entry.getKey();
                break;
              }
            }
            if (assignee.equals("")) {
              for (Map.Entry<String, Integer> entry : usersMap.entrySet()) {
                if (entry.getValue().intValue() < ticketNumber) {
                  assignee = entry.getKey();
                }
              }
            }
            ticket.setAssignee(assignee);
            topicDAO.update(ticket);
            Map<String, String> changes = new HashMap<>();
            changes.put(CSConstants.OLD_ASSIGNEE, null);
            changes.put(CSConstants.NEW_ASSIGNEE, assignee);
            changes.put(CSConstants.USERID, "support");
            listenerService.broadcast(CSConstants.TICKET_UPDATED, ticket, changes);
            LOG.info("Ticket {} has been assigned to {}", ticket.getId(), assignee);
          } catch (Exception e) {
            e.printStackTrace();
          }

        }
      }
    }

      List<User> users = CSUtils.getSupportMembers();
    if(users.size()>0){
      String listString = users.stream().map(User::getUserName).collect(Collectors.joining(","));
    calendar = Calendar.getInstance();
    tickets = topicDAO.findTicketsForSLAReminder(calendar);
    for (TopicEntity ticket : tickets) {
      if (ticket.getFirstWarningDate() != null && ticket.getFirstWarningDate().before(calendar)) {

          try {
            Duration period = Duration.between( ticket.getFirstWarningDate().toInstant(), calendar.toInstant());

            long different = ticket.getLastWarningDate().getTime().getTime() - calendar.getTime().getTime();

            long secondsInMilli = 1000;
            long minutesInMilli = secondsInMilli * 60;
            long hoursInMilli = minutesInMilli * 60;
            long daysInMilli = hoursInMilli * 24;

            long elapsedDays = different / daysInMilli;
            different = different % daysInMilli;

            long elapsedHours = different / hoursInMilli;
            different = different % hoursInMilli;

            long elapsedMinutes = different / minutesInMilli;
            different = different % minutesInMilli;

            long elapsedSeconds = different / secondsInMilli;

            String days = Long.toString(elapsedDays);
            String hours = Long.toString(elapsedHours);
            String minuts = Long.toString(elapsedMinutes);
            NotificationContext ctx = NotificationContextImpl.cloneInstance().append(CSSLAReminderPlugin.TICKET, ticket).append(CSSLAReminderPlugin.DAYS, days).append(CSSLAReminderPlugin.HOURS, hours).append(CSSLAReminderPlugin.MINUTES, minuts).append(CSSLAReminderPlugin.RECEIVERS, listString);
            ctx.getNotificationExecutor().with(ctx.makeCommand(PluginKey.key(CSSLAReminderPlugin.ID))).execute(ctx);
            LOG.info("Notification: Ticket {} SLA warning", ticket.getId());
          } catch (Exception e) {
            e.printStackTrace();
          }

      }
    }
    }

    LOG.info("Auto Assignement finished");

  }
}
