/*
 * 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.qvm.web;

import com.axelor.apps.qvm.db.QvmOperation;
import com.axelor.apps.qvm.db.repo.QvmOperationRepository;
import com.axelor.apps.qvm.service.QvmOperationService;
import com.axelor.apps.qvm.translation.ITranslation;
import com.axelor.auth.AuthUtils;
import com.axelor.auth.db.User;
import com.axelor.exception.AxelorException;
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 java.lang.invoke.MethodHandles;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class QvmOperationController {

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

  public void setSequenceOperation(ActionRequest request, ActionResponse response) {
    try {
      QvmOperation calibration = request.getContext().asType(QvmOperation.class);

      if (calibration != null && calibration.getCompany() != null) {
        response.setValue(
            "serialNumber",
            Beans.get(QvmOperationService.class)
                .createOperationSeq(calibration.getCompany())
                .getSerialNumber());
      } else {
        System.out.println("Operation or company est null");
        System.out.println("Operation : " + calibration);
        System.out.println("Company : " + calibration.getCompany());
      }
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void setSequenceCalibration(ActionRequest request, ActionResponse response) {
    try {
      QvmOperation calibration = request.getContext().asType(QvmOperation.class);

      if (calibration != null && calibration.getCompany() != null) {
        response.setValue(
            "serialNumber",
            Beans.get(QvmOperationService.class)
                .createCalibrationSeq(calibration.getCompany())
                .getSerialNumber());
      } else {
        System.out.println("Operation or company est null");
        System.out.println("Operation : " + calibration);
        System.out.println("Company : " + calibration.getCompany());
      }
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void setSequenceQualification(ActionRequest request, ActionResponse response) {
    try {
      QvmOperation calibration = request.getContext().asType(QvmOperation.class);

      if (calibration != null && calibration.getCompany() != null) {
        response.setValue(
            "serialNumber",
            Beans.get(QvmOperationService.class)
                .createQualificationSeq(calibration.getCompany())
                .getSerialNumber());
      } else {
        System.out.println("Operation or company est null");
        System.out.println("Operation : " + calibration);
        System.out.println("Company : " + calibration.getCompany());
      }
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void setMachineInfo(ActionRequest request, ActionResponse response)
      throws AxelorException {
    QvmOperation calibration = request.getContext().asType(QvmOperation.class);
    QvmOperation newOperation = Beans.get(QvmOperationService.class).setMachine(calibration);
  }

  public void generateQvmOperation(ActionRequest request, ActionResponse response) {
    try {
      User user = AuthUtils.getUser();
      Context context = request.getContext();
      Long id = (Long) request.getContext().get("id");
      QvmOperation operation = Beans.get(QvmOperationRepository.class).find(id);
      if (operation == null) {
        response.setError("Operation not found.");
        return;
      }
      operation = Beans.get(QvmOperationRepository.class).find(operation.getId());

      // printOperationInformation(operation);
      QvmOperation nextOperation =
          Beans.get(QvmOperationService.class).createNextOperation(operation, user.getId());

      // printOperationInformation(nextOperation);
      if (nextOperation != null) {
        try {
          // Beans.get(QvmOperationRepository.class).save(nextOperation);
          saveQvmOperation(nextOperation);
        } catch (Exception e) {
          TraceBackService.trace(response, e);
        }
        response.setView(
            ActionView.define(I18n.get(ITranslation.OPERATION))
                .model(QvmOperation.class.getName())
                .add("grid", "operation-grid")
                .add("form", "operation-form")
                .param("forceEdit", "true")
                .context("_showRecord", nextOperation.getId())
                .map());
        response.setCanClose(true);
      } else {
        response.setError("Failed to create the next operation.");
      }
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void saveQvmOperation(QvmOperation operation) {
    EntityManager entityManager = Beans.get(EntityManager.class);
    EntityTransaction transaction = entityManager.getTransaction();

    System.out.println("Is transaction active? " + transaction.isActive());

    try {
      transaction.begin();
      entityManager.persist(operation);
      transaction.commit();
    } catch (Exception e) {
      if (transaction != null && transaction.isActive()) {
        transaction.rollback();
      }
      throw e;
    }
  }
}
