package org.exoplatform.cs.portlet.quickticket;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;


import javax.inject.Inject;

import javax.portlet.PortletMode;
import javax.portlet.PortletPreferences;
import javax.portlet.ReadOnlyException;
import javax.portlet.ValidatorException;
import juzu.Action;
import juzu.HttpMethod;
import juzu.MimeType;
import juzu.Path;
import juzu.Resource;
import juzu.Response;
import juzu.Route;
import juzu.SessionScoped;
import juzu.View;
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.apache.commons.fileupload.FileItem;

import org.exoplatform.commons.juzu.ajax.Ajax;
import org.exoplatform.cs.dao.EnvironmentDAO;
import org.exoplatform.cs.dto.EnvironmentDTO;
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.portlet.common.CSControllerBase;
import org.exoplatform.cs.service.CSSpaceService;
import org.exoplatform.cs.service.EnvironmentService;
import org.exoplatform.cs.service.TicketService;
import org.exoplatform.cs.service.util.SpacePageUtils;
import org.exoplatform.forum.service.ForumService;
import org.exoplatform.services.listener.ListenerService;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.organization.OrganizationService;
import org.exoplatform.services.organization.User;
import org.exoplatform.task.service.TaskService;
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
  @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);
    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
  public Response.Content prepareImportFile(FileItem file1, FileItem file2, FileItem file3) throws IOException {
    try {
      List<FileItem> fileItems = Arrays.asList(new FileItem[] { file1, file2, file3 });
      uploadedFile.clear();
      for (FileItem fileItem : fileItems) {
        if (fileItem == null) {
          continue;
        }
        if (fileItem.getSize() == 0) {
          return Response.content(500, getResourceBundle().getString("cs.emptyFile"));
        }
        uploadedFile.add(fileItem);
        LOG.info("File imported '{}' with size {} ", fileItem.getName(), fileItem.getSize());
      }
      return Response.ok().content("OK");
    } catch (Throwable e) {
      LOG.error(e);
      return Response.content(500, getResourceBundle().getString("cs.error"));
    }
  }

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

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

}
