package org.exoplatform.cs.portlet.ticketAdministration;

import juzu.HttpMethod;
import juzu.MimeType;
import juzu.Path;
import juzu.Resource;
import juzu.Response;
import juzu.View;
import juzu.impl.common.JSON;
import juzu.plugin.jackson.Jackson;
import juzu.template.Template;
import org.exoplatform.commons.juzu.ajax.Ajax;
import org.exoplatform.cs.dto.IssueSeverity;
import org.exoplatform.cs.dto.IssueType;
import org.exoplatform.cs.dto.SpaceDTO;
import org.exoplatform.cs.dto.TicketDTO;
import org.exoplatform.cs.entity.SpaceEntity;
import org.exoplatform.cs.service.CSSpaceService;
import org.exoplatform.cs.service.util.CSUtils;
import org.exoplatform.cs.portlet.common.CSControllerBase;
import org.exoplatform.cs.service.TicketService;
import org.exoplatform.cs.service.tickets.FlowState;
import org.exoplatform.cs.service.tickets.TicketStatusFlowService;
import org.exoplatform.portal.application.PortalRequestContext;
import org.exoplatform.portal.mop.SiteType;
import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.organization.User;
import org.exoplatform.services.security.ConversationState;
import org.exoplatform.services.security.Identity;
import org.exoplatform.social.core.space.model.Space;

import javax.inject.Inject;


import java.util.*;


/**
 * Created by exo on 8/3/16.
 */
public class TicketAdministrationController extends CSControllerBase {
  private static Log  LOG = ExoLogger.getLogger(TicketAdministrationController.class);


  @Inject
  TicketService       ticketService;


  @Inject
  TicketStatusFlowService ticketStatusFlowService;

  @Inject
  CSSpaceService spaceService;

  @Inject
  @Path("index.gtmpl")
  Template            indexTmpl;

  @View
  public Response.Content index() {
    return indexTmpl.ok();
  }

  @Ajax
  @Resource
  @MimeType.JSON
  @Jackson
  public List<TicketDTO> getAllTickets(String filter, String selectedSpace, String selectedStatus) {
    try {
      Calendar from = Calendar.getInstance();
      from.add(Calendar.DATE, -7);
      if(filter.equals("allassignedtickets")){
        return ticketService.getAssignedTickets(getCurrentUser().getUserName(), selectedSpace, true, selectedStatus);
      } else if(filter.equals("allmytickets")){
        return ticketService.getMyTickets(getCurrentUser().getUserName(), selectedSpace, true, selectedStatus);
      } else if (filter.equals("allopentickets"))  {
        return ticketService.getTickets(selectedSpace, false, selectedStatus);
      } else if(filter.equals("alltickets")) {
        return ticketService.getTickets(selectedSpace, true, selectedStatus);
      }else if(filter.equals("assignedopentickets")) {
        return ticketService.getAssignedTickets(getCurrentUser().getUserName(),selectedSpace,false, selectedStatus);
      }else if(filter.equals("lastUpdated")) {
        return ticketService.getUpdatedTickets(selectedStatus,selectedSpace, from, Calendar.getInstance());
      }else if(filter.equals("lastCreated")) {
        return ticketService.getCreatedTickets(selectedSpace,from, Calendar.getInstance());
      }
      return ticketService.getMyTickets(getCurrentUser().getUserName(),selectedSpace,false, selectedStatus);
    } catch (Throwable e) {
      LOG.error("Exception when retrieving tickets" + e);
      return null;
    }
  }

  @Ajax
  @Resource
  @MimeType.JSON
  @Jackson
  public Response getBundle(String locale) {
      return super.getBundle(new Locale(locale));
  }

  @Ajax
  @Resource(method = HttpMethod.POST)
  @MimeType.JSON
  @Jackson
  public TicketDTO saveTicket(@Jackson TicketDTO ticketDTO) throws Exception {
    try {
      return ticketService.updateTicket(ticketDTO, getCurrentUser());
    } catch (Exception e) {
      LOG.error("Error when updating ticket", e);
      throw e;
    }
  }

  /**
   * This service will return the names of all support team members
   * @param ticketDTO
   * @return
   */
  @Ajax
  @Resource(method = HttpMethod.POST)
  @MimeType.JSON
  @Jackson
  public List<User> getSupportUsernames(@Jackson TicketDTO ticketDTO) {
    try {
      return CSUtils.getSupportMembers();
    } catch (Throwable e) {
      LOG.error("Can't retrieve the list of support engineers " + e);
      return null;
    }
  }

  /**
   * this method will return the list of severities
   * @return List of ticket severity
   */
  @Ajax
  @Resource(method = HttpMethod.POST)
  @MimeType.JSON
  @Jackson
  public List<String> getSeverities(@Jackson TicketDTO ticketDTO) {
      List<String> severities = new ArrayList<>();
      if(ticketDTO.getType().equals(IssueType.INCIDENT)){
        severities.add(IssueSeverity.SEVERITY_1.name());
        severities.add(IssueSeverity.SEVERITY_2.name());
        severities.add(IssueSeverity.SEVERITY_3.name());
      } else if(ticketDTO.getType().equals(IssueType.INFORMATION)) {
        severities.add(IssueSeverity.SEVERITY_4.name());
      }
      return severities;
  }

  /**
   * this method returns the static list of ticket types
   *
   * @return
   */
  @Ajax
  @Resource(method = HttpMethod.POST)
  @MimeType.JSON
  @Jackson
  public List<String> getTicketTypes() {
      List<String> ticketTypes = new ArrayList<>();
      ticketTypes.add(IssueType.INCIDENT.name());
      ticketTypes.add(IssueType.INFORMATION.name());
      return ticketTypes;
  }


  /**
   * this method returns the application Context
   *
   * @return
   */

  @Ajax
  @juzu.Resource
  @MimeType.JSON
  @Jackson
  public Response getContext() {
    try {
      JSON data = new JSON();
      String currentSpace=getCurrentSpaceId();
      if(currentSpace == null) data.set("currentSpace", "");
      else{
        data.set("currentSpace", currentSpace);
        SpaceDTO spaceDTO = spaceService.getSpace(currentSpace);
        data.set("currentSpaceIncidentFlow", spaceDTO.getIncidentFlow());
        data.set("currentSpaceInformationFlow", spaceDTO.getInformationFlow());
      }

      data.set("canManage",CSUtils.canManage());
      return Response.ok(data.toString());
    } catch (Exception e) {
      LOG.error("error while getting context", e);
      return Response.status(500);
    }
  }

  /**
   * this method returns the static list of ticket types
   *
   * @return
   */
  @Ajax
  @Resource(method = HttpMethod.GET )
  @MimeType.JSON
  @Jackson
  public Map<String, List<FlowState>> loadStatuses() {
    return ticketStatusFlowService.getAllStatuses();
  }

  /**
   * this method returns the list of customer spaces
   *
   * @return
   */
  @Ajax
  @Resource(method = HttpMethod.GET )
  @MimeType.JSON
  @Jackson
  public List<SpaceDTO> getSpaces() {
    return spaceService.getAllSpaces();
  }

  @Ajax
  @Resource(method = HttpMethod.POST)
  @MimeType.JSON
  @Jackson
  public String deleteTicket(@Jackson TicketDTO ticket) {
    ticketService.deleteTicket(ticket);
    return "OK";
  }

  public String getCurrentSpaceId() {
    String spaceGroupId = null;
    PortalRequestContext requestContext = Util.getPortalRequestContext();
    if (requestContext != null) {
      if (requestContext.getSiteType().equals(SiteType.GROUP) && requestContext.getSiteName().startsWith("/spaces")) {
        spaceGroupId = requestContext.getSiteName();
      }
    }
    return spaceGroupId;
  }


  @Override
  public Log getLogger() {
    return LOG;
  }
}