package com.axelor.apps.account.service;

import com.axelor.apps.account.db.Invoice;
import com.axelor.apps.account.db.InvoiceLine;
import com.axelor.apps.account.db.InvoiceTemplate;
import com.axelor.apps.account.db.InvoiceTemplateLine;
import com.axelor.apps.account.db.repo.InvoiceRepository;
import com.axelor.apps.account.service.invoice.generator.InvoiceGenerator;
import com.axelor.apps.account.service.invoice.generator.InvoiceLineGenerator;
import com.axelor.apps.base.db.Company;
import com.axelor.apps.base.db.Partner;
import com.axelor.apps.base.db.Product;
import com.axelor.exception.AxelorException;
import com.axelor.inject.Beans;
import com.google.inject.persist.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class InvoiceTemplateService {

  @Transactional
  public Invoice generateInvoiceFromTemplate(InvoiceTemplate invoiceTemplate)
      throws AxelorException {

    Partner partner = invoiceTemplate.getPartner();
    Company company = invoiceTemplate.getCompany();
    InvoiceGenerator invoiceGenerator =
        new InvoiceGenerator(
            InvoiceRepository.OPERATION_TYPE_SUPPLIER_PURCHASE,
            company,
            null,
            null,
            null,
            partner,
            partner,
            partner.getCurrency(),
            null,
            "",
            "",
            null,
            company.getDefaultBankDetails(),
            null) {

          @Override
          public Invoice generate() throws AxelorException {

            return super.createInvoiceHeader();
          }
        };

    List<InvoiceLine> invoiceLineList = new ArrayList<>();

    Invoice invoice = invoiceGenerator.generate();

    int priority = 0;
    for (InvoiceTemplateLine invoiceTemplateLine : invoiceTemplate.getMoveTemplateLineList()) {
      invoiceLineList.addAll(createInvoiceLine(invoice, invoiceTemplateLine, priority));
      priority++;
    }
    invoiceGenerator.populate(invoice, invoiceLineList);

    Invoice returnInvoiced = Beans.get(InvoiceRepository.class).save(invoice);

    return returnInvoiced;
  }

  protected List<InvoiceLine> createInvoiceLine(
      Invoice invoice, InvoiceTemplateLine invoiceTemplateLine, int priority)
      throws AxelorException {

    Product product = invoiceTemplateLine.getProduct();

    InvoiceLineGenerator invoiceLineGenerator =
        new InvoiceLineGenerator(
            invoice,
            product,
            invoiceTemplateLine.getProduct().getName(),
            BigDecimal.ZERO,
            BigDecimal.ZERO,
            BigDecimal.ZERO,
            "",
            invoiceTemplateLine.getQty(),
            invoiceTemplateLine.getProduct().getUnit(),
            null,
            priority,
            BigDecimal.ZERO,
            0,
            BigDecimal.ZERO,
            BigDecimal.ZERO,
            false,
            false,
            null) {

          @Override
          public List<InvoiceLine> creates() throws AxelorException {

            InvoiceLine invoiceLine = this.createInvoiceLine();
            invoiceLine.setQty(BigDecimal.ONE);
            invoiceLine.setPrice(BigDecimal.ZERO);
            invoiceLine.setPriceDiscounted(BigDecimal.ZERO);

            List<InvoiceLine> invoiceLines = new ArrayList<InvoiceLine>();
            invoiceLines.add(invoiceLine);

            return invoiceLines;
          }
        };

    return invoiceLineGenerator.creates();
  }
}
