/*
 * Axelor Business Solutions
 *
 * Copyright (C) 2019 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.axelor.apps.stock.web;

import com.axelor.apps.base.db.Product;
import com.axelor.apps.base.db.repo.ProductRepository;
import com.axelor.apps.stock.db.Inventory;
import com.axelor.apps.stock.db.InventoryLine;
import com.axelor.apps.stock.db.StockLocationLine;
import com.axelor.apps.stock.db.TrackingNumber;
import com.axelor.apps.stock.db.repo.InventoryLineRepository;
import com.axelor.apps.stock.db.repo.InventoryRepository;
import com.axelor.apps.stock.db.repo.TrackingNumberRepository;
import com.axelor.apps.stock.service.InventoryLineService;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.repo.TraceBackRepository;
import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.axelor.rpc.ActionRequest;
import com.axelor.rpc.ActionResponse;
import com.axelor.rpc.Context;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.math.BigDecimal;
import java.util.Map;

@Singleton
public class InventoryLineController {

  @Inject private ProductRepository productRepository;
  private TrackingNumberRepository trackingNumberRepository;
  private InventoryLineRepository inventoryLineRepository;
  private InventoryRepository inventoryRepository;

  private Product mProduct;

  public void updateInventoryLine(ActionRequest request, ActionResponse response)
      throws AxelorException {

    InventoryLine inventoryLine = request.getContext().asType(InventoryLine.class);
    Inventory inventory =
        request.getContext().getParent() != null
            ? request.getContext().getParent().asType(Inventory.class)
            : inventoryLine.getInventory();
    inventoryLine =
        Beans.get(InventoryLineService.class).updateInventoryLine(inventoryLine, inventory);
    response.setValue("rack", inventoryLine.getRack());
    response.setValue("currentQty", inventoryLine.getCurrentQty());
  }

  public void compute(ActionRequest request, ActionResponse response) {
    InventoryLine inventoryLine = request.getContext().asType(InventoryLine.class);
    Inventory inventory =
        request.getContext().getParent() != null
            ? request.getContext().getParent().asType(Inventory.class)
            : inventoryLine.getInventory();
    inventoryLine = Beans.get(InventoryLineService.class).compute(inventoryLine, inventory);
    response.setValues(inventoryLine);
  }

  public void setProdut(ActionRequest request, ActionResponse response) {
    Context context = request.getContext();

    if (mProduct != null) {
      System.out.println("************* set product");
      Long id = ((Inventory) context.get("inventory")).getId();
      Inventory inventory = Beans.get(InventoryRepository.class).find(id);

      System.out.println("*******" + mProduct.getId().toString());

      StockLocationLine sll =
          inventory
              .getStockLocation()
              .getStockLocationLineList()
              .stream()
              .filter(
                  t -> {
                    System.out.println(
                        mProduct.getId().toString()
                            + " || "
                            + t.getProduct().getId().toString()
                            + " ******* "
                            + (mProduct.getId().longValue() == t.getProduct().getId().longValue()));
                    return (t.getProduct().getId().longValue() == mProduct.getId().longValue());
                  })
              .findFirst()
              .orElse(null);

      BigDecimal currentQty = BigDecimal.ZERO;
      if (sll != null) {
        System.out.println("ssl" + sll.toString());
        currentQty = sll.getCurrentQty();
      }
      response.setValue("product", mProduct);
      response.setValue("unit", mProduct.getUnit());
      response.setValue("currentQty", currentQty);
    }
  }

  public void setFromParameter(ActionRequest request, ActionResponse response) {

    InventoryLine inventoryLine = request.getContext().asType(InventoryLine.class);

    Map<String, Object> requestData = request.getData();
    final Map<String, Object> jsonContextValues = (Map<String, Object>) requestData.get("context");
    Long id = Long.valueOf(jsonContextValues.get("vv").toString());

    System.out.println("setFromParameter ****************" + id.toString());

    Product product = Beans.get(ProductRepository.class).find(id);

    System.out.println("setFromParameter ****************" + product.toString());

    response.setValue("product", product);
  }

  public void setInventaire(ActionRequest request, ActionResponse response) {
    Context context = request.getContext();
    Long stockLocationId =
        new Long((Integer) ((Map) request.getContext().get("stockLocation")).get("id"));
    Inventory inventory =
        Beans.get(InventoryRepository.class)
            .all()
            .filter("self.stockLocation.id = ?1", stockLocationId)
            .order("-createdOn")
            .fetchOne();

    String code = context.get("productHolder").toString();

    Product product = productRepository.findByCode(code);

    if (product != null) {
      response.setValue("product", product);
      response.setValue("unit", product.getUnit());
      response.setValue("inventory", inventory);
      // response.setView(
      //   ActionView.define("Inventory lines")
      //       .model(InventoryLine.class.getName())
      //       .add("form", "inventory-reports-wizard-form2")
      //       .param("show-toolbar", "false")
      //       .param("show-confirm", "false")
      //       .param("popup-save", "false")
      //       .param("show-toolbar","false")
      //       .param("popup", "true")
      //       .param("forceEdit", "true")
      //       .context("_product", product)
      //       .context("_unit", product.getUnit())
      //       .context("_inventory", inventory)
      //       .context("_showRecord", inventoryLine.getId())
      //       .map());
    } else {
      String strWithoutSlash = String.join("%", code.split("/"));
      String strWithoutDash = String.join("%", strWithoutSlash.split("_"));
      product =
          productRepository.all().filter("self.code like '" + strWithoutDash + "'").fetchOne();
      response.setValue("product", product);
      response.setValue("unit", product.getUnit());
      response.setValue("inventory", inventory);
      // response.setFlash("Veuillez contacter votre administrateur");
    }
  }

  public void setInventoryLine(ActionRequest request, ActionResponse response)
      throws AxelorException {
    Context context = request.getContext();

    Inventory inventory = ((Inventory) context.get("inventory"));
    // Long stockLocationId =  new Long((Integer) ((Map)
    // request.getContext().get("inventory")).get("id"));
    // Long trackingNumberId =  new Long((Integer) ((Map)
    // request.getContext().get("trackingNumber")).get("id"));
    TrackingNumber trackingNumber = ((TrackingNumber) context.get("trackingNumber"));
    Product product = ((Product) context.get("product"));

    // Inventory inventory = Beans.get(InventoryRepository.class).find(stockLocationId);
    // TrackingNumber   trackingNumber =
    // Beans.get(TrackingNumberRepository.class).find(trackingNumberId);

    System.out.println(inventory.toString());
    System.out.println(trackingNumber);
    System.out.println(product.toString());

    // Product product = productRepository.find(productId);
    // Inventory inventory = inventoryRepository.find(inventoryId);
    // TrackingNumber trackingNumber = trackingNumberRepository.find(trackingNumberId);

    if (inventory == null || product == null) {
      throw new AxelorException(
          TraceBackRepository.CATEGORY_NO_VALUE, I18n.get("Cannot find the data"));
    }

    Integer countingType = Integer.parseInt(context.get("countingTypeSelect").toString());
    BigDecimal firstCounting = (BigDecimal) context.get("firstCounting");
    BigDecimal secondCounting = (BigDecimal) context.get("secondCounting");
    BigDecimal controlCounting = (BigDecimal) context.get("controlCounting");

    Beans.get(InventoryLineService.class)
        .setInventoryLine(
            inventory,
            product,
            trackingNumber,
            countingType,
            firstCounting,
            secondCounting,
            controlCounting);
    response.setFlash("Updated Successfully");
    // response.setReload(true);
  }
}
