package org.exoplatform.cs.portlet.quickticket;

import java.io.FileInputStream;
import java.util.*;

import javax.inject.Inject;
import javax.portlet.PortletMode;
import javax.portlet.PortletPreferences;
import juzu.*;
import juzu.bridge.portlet.JuzuPortlet;
import juzu.impl.bridge.spi.portlet.PortletRequestBridge;
import juzu.impl.request.Request;
import juzu.plugin.jackson.Jackson;
import juzu.request.RequestContext;
import juzu.template.Template;

import org.exoplatform.commons.file.model.FileItem;
import org.exoplatform.commons.juzu.ajax.Ajax;
import org.exoplatform.cs.dto.*;
import org.exoplatform.cs.portlet.common.CSControllerBase;
import org.exoplatform.cs.service.*;
import org.exoplatform.cs.service.util.SpacePageUtils;
import org.exoplatform.services.listener.ListenerService;
import org.exoplatform.services.log.*;
import org.exoplatform.services.organization.User;
import org.exoplatform.upload.*;
import org.json.JSONObject;

@SessionScoped
public class QuickTicketController extends CSControllerBase {
  private static Log    LOG                          = ExoLogger.getLogger(QuickTicketController.class);

  private static String SPACE_GROUP_ID               = "exo.cs.addon.spaceGroupId";

  private static String SPACE_GROUP_ID_DEFAULT_VALUE = "/spaces/exo_employees";

  @Inject
  TicketService         ticketService;

  @Inject
  CSSpaceService        csSpaceService;

  @Inject
  EnvironmentService    environmentService;

  @Inject
  ListenerService       listenerService;

  @Inject
  UploadService         uploadService;

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

  @Inject
  @Path("edit.gtmpl")
  Template              editTemplate;

  List<FileItem>        uploadedFile                 = new ArrayList<FileItem>();

  @View
  public Response.Content index(RequestContext requestContext) {
    Request request = Request.getCurrent();
    PortletRequestBridge bridge = (PortletRequestBridge) request.getBridge();
    PortletPreferences prefs = bridge.getPortletRequest().getPreferences();
    PortletMode mode = requestContext.getProperty(JuzuPortlet.PORTLET_MODE);
    String groupId = prefs.getValue(SPACE_GROUP_ID, SPACE_GROUP_ID_DEFAULT_VALUE);
    LOG.info("Group ID value is {}", groupId);
    if (PortletMode.EDIT.equals(mode)) {
      List<SpaceDTO> spaces = csSpaceService.getAllSpaces();
      Map<String, Object> parameters = new HashMap<>();
      parameters.put("selectedSpace", groupId);
      parameters.put("spaces", spaces);
      return editTemplate.with(parameters).ok();
    } else {
      List<String> errors = new ArrayList<>();
      if (groupId != null) {
        try {
          SpaceDTO space = csSpaceService.getSpace(groupId);
        } catch (Exception e) {
          LOG.error("Error retrieving space from group ID {}", groupId, e);
          errors.add("Please select a target customer space in the preferences of the portlet");
        }
        try {
          EnvironmentDTO environment = environmentService.getSpaceDefaultEnvironment(groupId);
          if (environment == null) {
            errors.add("Please create an environment for the selected space");
          }
        } catch (Exception e) {
          errors.add("Please create an environment for the selected space");
        }
      } else {
        errors.add("Please select a target customer space in the preferences of the portlet");

      }
      return indexTemplate.with().set("errors", errors).ok();
    }
  }

  @View
  public Response.View edit() {
    return QuickTicketController_.edit();
  }

  @Ajax
  @Resource(method = HttpMethod.POST)
  public Response saveTicket(@Jackson TicketDTO ticketDTO) {
    Request request = Request.getCurrent();
    PortletRequestBridge bridge = (PortletRequestBridge) request.getBridge();
    PortletPreferences prefs = bridge.getPortletRequest().getPreferences();
    ticketDTO.setEnvironmentId(0l); // fake Environment ID
    ticketDTO.setSeverity(IssueSeverity.SEVERITY_3);
    ticketDTO.setType(IssueType.INCIDENT);
    getFiles(ticketDTO.getUploads());
    String groupId = prefs.getValue(SPACE_GROUP_ID, SPACE_GROUP_ID_DEFAULT_VALUE);
    try {
      SpaceDTO space = csSpaceService.getSpace(groupId);
      EnvironmentDTO environment = environmentService.getSpaceDefaultEnvironment(groupId);
      if (environment == null) {
        throw new Exception("No Environment is configured for this space, please create one");
      }
      ticketDTO.setEnvironmentId(environment.getId());
      ticketDTO.setEnvironmentName(environment.getName());
      ticketDTO.setSpaceGroupId(groupId);
      ticketDTO.setFiles(uploadedFile);

      User user = getCurrentUser();
      String spaceLink = SpacePageUtils.getSpaceHomeURL(groupId, space.getName());
      ticketService.createTicket(ticketDTO, user, spaceLink);
      uploadedFile.clear();
      String ticketLink = spaceLink + "/forum/topic/" + ticketDTO.getId();
      ticketDTO.setLink(ticketLink);
      ticketService.updateTicketLink(ticketDTO, ticketLink);
      JSONObject ticketResponse = new JSONObject();
      ticketResponse.append("link", ticketDTO.getLink());
      ticketResponse.append("label", ticketDTO.getTitle());
      try {
        Map<String, String> gam = new HashMap<>();
        gam.put("ruleTitle", "openNewTribeFeedback");
        gam.put("senderId", user.getUserName());
        gam.put("receiverId", user.getUserName());
        gam.put("object", ticketLink);
        listenerService.broadcast("exo.gamification.generic.action", gam, "");
        LOG.info("Tribe Feedback Gamification event broadcast ");
      } catch (Exception e) {
        LOG.error("Cannot launch Tribe Feedback Gamification event" + e.getMessage(), e);
      }
      return Response.ok(ticketResponse.toString());
    } catch (Exception e) {
      LOG.error("Error when saving Task/Forum Topic", e);
      return Response.status(500);
    }
  }

  @Action
  @Route("updateSettings")
  public Response.View updateSettings(String spaceGroupId) throws Exception {
    Request request = Request.getCurrent();
    PortletRequestBridge bridge = (PortletRequestBridge) request.getBridge();
    PortletPreferences prefs = bridge.getPortletRequest().getPreferences();
    prefs.setValue(SPACE_GROUP_ID, spaceGroupId);
    prefs.store();
    return QuickTicketController_.index();
  }

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

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

  private void getFiles(String[] ids) {

    for (String id : ids) {
      UploadResource uploadResource = uploadService.getUploadResource(id);
      if (uploadResource != null) {

        try {
          FileItem fileItem = new FileItem(null,
                                           id,
                                           uploadResource.getMimeType(),
                                           "FORUM_ATTACHEMENTS_NAMESPACE",
                                           (long) uploadResource.getUploadedSize(),
                                           new Date(),
                                           getCurrentUser().getUserName(),
                                           false,
                                           new FileInputStream(uploadResource.getStoreLocation()));
          uploadedFile.add(fileItem);
        } catch (Exception e) {
          LOG.error("Error while getting attachment files", e);
        }

      }

    }
  }

}
