package com.axelor.apps.stock.web;

import com.axelor.apps.report.engine.ReportSettings;
import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.stock.db.StockProductionRequest;
import com.axelor.apps.stock.db.repo.StockMoveRepository;
import com.axelor.apps.stock.db.repo.StockProductionRequestRepository;
import com.axelor.apps.stock.exception.IExceptionMessage;
import com.axelor.apps.stock.service.stockmove.print.StockProductionRequestPrintService;
import com.axelor.common.ObjectUtils;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.repo.TraceBackRepository;
import com.axelor.exception.service.TraceBackService;
import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.axelor.meta.schema.actions.ActionView;
import com.axelor.rpc.ActionRequest;
import com.axelor.rpc.ActionResponse;
import com.axelor.rpc.Context;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import java.lang.invoke.MethodHandles;
import java.util.List;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class StockProductionRequestController {

  private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

  public void draft(ActionRequest request, ActionResponse response) {
    StockProductionRequest productionRequest =
        request.getContext().asType(StockProductionRequest.class);
    try {
      Beans.get(StockProductionRequestService.class)
          .draft(Beans.get(StockProductionRequestRepository.class).find(productionRequest.getId()));
      response.setReload(true);
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void plan(ActionRequest request, ActionResponse response) {
    StockProductionRequest productionRequest =
        request.getContext().asType(StockProductionRequest.class);
    try {
      Beans.get(StockProductionRequestService.class)
          .plan(Beans.get(StockProductionRequestRepository.class).find(productionRequest.getId()));
      response.setReload(true);
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void realize(ActionRequest request, ActionResponse response) {
    StockProductionRequest productionRequest =
        request.getContext().asType(StockProductionRequest.class);
    try {
      Beans.get(StockProductionRequestService.class)
          .realize(
              Beans.get(StockProductionRequestRepository.class).find(productionRequest.getId()));
      response.setReload(true);
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void cancel(ActionRequest request, ActionResponse response) {
    StockProductionRequest productionRequest =
        request.getContext().asType(StockProductionRequest.class);
    try {
      Beans.get(StockProductionRequestService.class)
          .cancel(
              Beans.get(StockProductionRequestRepository.class).find(productionRequest.getId()));
      response.setReload(true);
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void print(ActionRequest request, ActionResponse response) {

    Context context = request.getContext();
    String fileLink;
    String title;
    StockProductionRequestPrintService productionRequestPrintService =
        Beans.get(StockProductionRequestPrintService.class);

    try {
      if (!ObjectUtils.isEmpty(request.getContext().get("_ids"))) {
        @SuppressWarnings({"unchecked", "rawtypes"})
        List<Long> ids =
            Lists.transform(
                (List) request.getContext().get("_ids"),
                new Function<Object, Long>() {
                  @Nullable
                  @Override
                  public Long apply(@Nullable Object input) {
                    return Long.parseLong(input.toString());
                  }
                });
        fileLink = productionRequestPrintService.printStockProductionRequests(ids);
        title = I18n.get("Purchase requests");
      } else if (context.get("id") != null) {
        StockProductionRequest productionRequest =
            request.getContext().asType(StockProductionRequest.class);
        title = productionRequestPrintService.getFileName(productionRequest);
        fileLink =
            productionRequestPrintService.printStockProductionRequest(
                productionRequest, ReportSettings.FORMAT_PDF);
        logger.debug("Printing " + title);
      } else {
        throw new AxelorException(
            TraceBackRepository.CATEGORY_MISSING_FIELD,
            I18n.get(IExceptionMessage.INVENTORY_3_DATA_NULL_OR_EMPTY));
      }
      response.setView(ActionView.define(title).add("html", fileLink).map());
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void createStockMove(ActionRequest request, ActionResponse response) {

    StockProductionRequest productionRequest =
        request.getContext().asType(StockProductionRequest.class);

    try {
      if (productionRequest.getId() != null) {

        StockProductionRequestService productionRequestService =
            Beans.get(StockProductionRequestService.class);

        List<Long> stockMoveList =
            productionRequestService.createStocksMovesFromStockProductionRequest(
                Beans.get(StockProductionRequestRepository.class).find(productionRequest.getId()));

        if (stockMoveList != null && stockMoveList.size() == 1) {
          response.setView(
              ActionView.define(I18n.get("Stock move"))
                  .model(StockMove.class.getName())
                  .add("form", "stock-move-form")
                  .add("grid", "stock-move-grid")
                  .param("forceEdit", "true")
                  .domain("self.id = " + stockMoveList.get(0))
                  .context("_showRecord", String.valueOf(stockMoveList.get(0)))
                  .context("_userType", StockMoveRepository.USER_TYPE_SENDER)
                  .map());
        } else if (stockMoveList != null && stockMoveList.size() > 1) {
          response.setView(
              ActionView.define(I18n.get("Stock move"))
                  .model(StockMove.class.getName())
                  .add("grid", "stock-move-grid")
                  .add("form", "stock-move-form")
                  .domain("self.id in (" + Joiner.on(",").join(stockMoveList) + ")")
                  .context("_userType", StockMoveRepository.USER_TYPE_SENDER)
                  .map());
        } else {
          response.setFlash(I18n.get(IExceptionMessage.STOCK_MOVE_4));
        }
      }
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void generateReversion(ActionRequest request, ActionResponse response)
      throws AxelorException {
    StockProductionRequest productionRequestContext =
        request.getContext().asType(StockProductionRequest.class);
    StockProductionRequest productionRequest =
        Beans.get(StockProductionRequestRepository.class).find(productionRequestContext.getId());

    StockProductionRequestService productionRequestService =
        Beans.get(StockProductionRequestService.class);

    StockProductionRequest stockProductionRequest =
        productionRequestService.generateReversion(productionRequest);

    if (stockProductionRequest != null) {
      response.setView(
          ActionView.define(I18n.get("Stock production request"))
              .model(StockProductionRequest.class.getName())
              .add("form", "stock-production-request-form")
              .add("grid", "stock-production-request-grid")
              .param("forceEdit", "true")
              .domain("self.id = " + stockProductionRequest.getId())
              .context("_showRecord", String.valueOf(stockProductionRequest.getId()))
              .map());
    }
  }
}
