package org.openbravo.process.poc;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Map;

import javax.enterprise.inject.Any;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import javax.servlet.ServletException;

import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.openbravo.advpaymentmngt.ProcessInvoiceHook;
import org.openbravo.advpaymentmngt.ad_actionbutton.ProcessInvoice;
import org.openbravo.client.application.process.BaseProcessActionHandler;
import org.openbravo.client.application.window.servlet.CalloutHttpServletResponse;
import org.openbravo.client.application.window.servlet.CalloutServletConfig;
import org.openbravo.client.kernel.RequestContext;
import org.openbravo.dal.core.DalUtil;
import org.openbravo.dal.service.OBDal;
import org.openbravo.erpCommon.utility.OBError;
import org.openbravo.model.common.invoice.Invoice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CompleteInvoice extends BaseProcessActionHandler {

  private static final Logger log = LoggerFactory.getLogger(CompleteInvoice.class);

  @Inject
  @Any
  private Instance<ProcessInvoiceHook> hooks;

  @Override
  protected JSONObject doExecute(Map<String, Object> parameters, String content) {
    JSONObject result = new JSONObject();
    JSONObject executionMessage = new JSONObject();
    String invoiceId = "";
    try {
      JSONObject info = new JSONObject(content);

      invoiceId = info.getString("invoiceId");
      completeInvoice(info);

      // process stores message in session
      OBError completionResult = (OBError) RequestContext.get().getSessionAttribute("263|MESSAGE");

      executionMessage.put("type", completionResult.getType().toLowerCase());
      executionMessage.put("title", completionResult.getTitle());
      executionMessage.put("txt", completionResult.getMessage());
    } catch (Exception e) {
      log.error("Error completing invoice {}", invoiceId, e);
      try {
        executionMessage.put("type", "error");
        executionMessage.put("title", e.getMessage());
      } catch (JSONException ignore) {
        log.error("Error completing invoice {}", invoiceId, ignore);
      }
    }

    try {
      result.put("msg", executionMessage);
    } catch (JSONException ignore) {
      log.error("Error completing invoice {}", invoiceId, ignore);
    }
    return result;
  }

  private void completeInvoice(JSONObject info) throws JSONException, ServletException,
      IOException, SecurityException, NoSuchFieldException, IllegalArgumentException,
      IllegalAccessException {
    String invoiceId = info.getString("invoiceId");

    // action is sent from client, to decide whether the logic should be in client or in server side
    String docAction = info.getString("docAction");

    Class<ProcessInvoice> processClass = ProcessInvoice.class;

    ProcessInvoice processInstance = new ProcessInvoice();
    CalloutServletConfig config = new CalloutServletConfig(processClass.getName(),
        RequestContext.getServletContext());
    Field h = processClass.getDeclaredField("hooks");
    h.setAccessible(true);
    h.set(processInstance, hooks);

    RequestContext rq = RequestContext.get();
    CalloutHttpServletResponse fakeResponse = new CalloutHttpServletResponse(rq.getResponse());
    Invoice invoice = OBDal.getInstance().get(Invoice.class, invoiceId);

    rq.setRequestParameter("Command", "SAVE_BUTTONDocAction111");
    rq.setRequestParameter("inpdocaction", docAction);
    rq.setRequestParameter("inpKey", invoiceId);

    rq.setRequestParameter("inpwindowId", "167");
    rq.setRequestParameter("inpTabId", "263");
    rq.setRequestParameter("inpadOrgId", (String) DalUtil.getId(invoice.getOrganization()));

    processInstance.init(config);
    processInstance.service(rq.getRequest(), fakeResponse);
  }
}
