package unitest;

import eu.dnetlib.goldoa.domain.*;
import eu.dnetlib.goldoa.service.AlternativeFundingBidManager;
import eu.dnetlib.goldoa.service.InvoiceManager;
import eu.dnetlib.goldoa.service.OrganizationManager;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.transaction.Transactional;
import java.io.*;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import static eu.dnetlib.goldoa.domain.Constants.*;

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration(locations = "classpath:applicationContext-goldoa-service-test.xml")
public class AlternativeFundingBidsTest {

    @Autowired
    OrganizationManager organizationManager;
    @Autowired
    InvoiceManager invoiceManager;
    @Autowired
    AlternativeFundingBidManager alternativeFundingBidManager;

    @Test
    @Transactional
    @Rollback(true)
    public void importAlternativeFundingBids(){

        alternativeFundingBidManager.importAlternativeFundingBids();
        /*String path = "/home/panagiotis/Desktop/uploadFiles/";
        BufferedReader br = null;
        String s = "";
        String cvsSplitBy = ",";
        AlternativeFundingBid bid = null;

        try {
            br = new BufferedReader(new FileReader(path + "Alternative Funding Bids - First round.csv"));
            s = br.readLine();
            while ((s = br.readLine()) != null) {

                System.out.println("Line -> " + s);

                String[] line = s.split(cvsSplitBy);
                String id = !line[0].equals("")?line[0].trim():null;
                String funding_name = !line[1].equals("")?line[1].trim():null;
                String organization = !line[2].equals("")?line[2].trim():null;
                String country = !line[3].equals("")?line[3].trim():null;
                String totalAmount = !line[4].equals("")?line[4].trim():null;
                String contractStartDate = !line[5].equals("")?line[5].trim():null;
                String contractEndDate = !line[6].equals("")?line[6].trim():null;

                String firstInvoiceDate = !line[7].equals("")?line[7].trim():null;
                String firstInvoiceNumber = !line[8].equals("")?line[8].trim():null;

                String secondInvoiceDate = !line[9].equals("")?line[9].trim():null;
                String secondInvoiceNumber = !line[10].equals("")?line[10].trim():null;

                String firstPaymentAmount = !line[11].equals("")?line[11].trim():null;
                String firstPaymentDate = !line[12].equals("")?line[12].trim():null;
                String firstPaymentOtherCosts = !line[13].equals("")?line[13].trim():null;
                String firstPaymentTransferCost = !line[14].equals("")?line[14].trim():null;

                String secondPaymentAmount = !line[15].equals("")?line[15].trim():null;
                String secondPaymentDate = !line[16].equals("")?line[16].trim():null;
                String secondPaymentOtherCosts = !line[17].equals("")?line[17].trim():null;
                String secondPaymentTransferCost = !line[18].equals("")?line[18].trim():null;


                List<Object> orgs =  organizationManager.search(organization);
                if(orgs == null)
                    System.out.println("Organization " + organization +  "  not exists!");

                Organization org = (Organization) organizationManager.search(organization).get(0);
                bid = this.initializeBid(funding_name,id,country,totalAmount,contractStartDate,contractEndDate);
                System.out.println("Bid initialized!");

                bid.setFirstInvoice(this.uploadInvoiceFile(path,funding_name,FIRST_INVOICE_PDF,
                        firstInvoiceDate,firstInvoiceNumber));
                System.out.println("First invoice ready!");

                bid.setSecondInvoice(this.uploadInvoiceFile(path,funding_name,SECOND_INVOICE_PDF,
                        secondInvoiceDate,secondInvoiceNumber));
                System.out.println("Second invoice ready!");

                bid.setFirstPaymentDocument(this.uploadReceiptFile(path,funding_name,FIRST_PAYMENT_PDF,
                        firstPaymentAmount,firstPaymentDate,firstPaymentOtherCosts,firstPaymentTransferCost));
                System.out.println("First payment ready!");

                bid.setSecondPaymentDocument(this.uploadReceiptFile(path,funding_name,SECOND_PAYMENT_PDF,
                        secondPaymentAmount,secondPaymentDate,secondPaymentOtherCosts,secondPaymentTransferCost));
                System.out.println("Second payment ready!");

                bid.setContract(this.uploadContract(path,funding_name,CONTRACT_PDF));
                System.out.println("Contract ready!");
                //alternativeFundingBidManager.save(bid);
            }

        } catch (IOException | ParseException e) {
            e.printStackTrace();
        }*/
    }

    private eu.dnetlib.goldoa.domain.File uploadContract(String basePath, String funding_name, String contract) {

        String fullPath = basePath + funding_name + "/" + contract;
        File file = new File(basePath + funding_name + "/" + contract);
        InputStream inputStream = null;
        Path source = Paths.get(fullPath);
        String contentType = null;
        eu.dnetlib.goldoa.domain.File contractFile = null;
        try {
            inputStream = new FileInputStream(file);
            contentType = Files.probeContentType(source);

            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
            IOUtils.copy(inputStream, baos);
            IOUtils.closeQuietly(baos);

            contractFile = new eu.dnetlib.goldoa.domain.File();
            contractFile.setId(invoiceManager.getFileId());
            contractFile.setMimetype(contentType);
            contractFile.setFile(baos.toByteArray());



        } catch (IOException e) {
            e.printStackTrace();
        }

        return contractFile;
    }

    private BankTransferReceipt uploadReceiptFile(String basePath, String funding_name, String receipt,
                                                  String paymentAmount, String paymentDate,
                                                  String paymentOtherCosts, String paymentTransferCost) throws ParseException {

        String fullPath = basePath + funding_name + "/" + receipt;
        File file = new File(basePath + funding_name + "/" + receipt);
        InputStream inputStream = null;
        Path source = Paths.get(fullPath);
        String contentType = null;
        Invoice invoice = null;
        BankTransferReceipt bankTransferReceipt = null;
        try {
            inputStream = new FileInputStream(file);
            contentType = Files.probeContentType(source);

            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
            IOUtils.copy(inputStream, baos);
            IOUtils.closeQuietly(baos);
            bankTransferReceipt = new BankTransferReceipt();
            bankTransferReceipt.setContent(baos.toByteArray());
            bankTransferReceipt.setContentType(contentType);
            bankTransferReceipt.setAmount(Double.valueOf(paymentAmount));
            Date parsedDate = new SimpleDateFormat("yyyy-MM-dd").parse(paymentDate);
            Timestamp st = new java.sql.Timestamp(parsedDate.getTime());
            bankTransferReceipt.setDate(st);
            bankTransferReceipt.setOtherCosts(Double.valueOf(paymentOtherCosts));
            bankTransferReceipt.setTransferCost(Double.valueOf(paymentTransferCost));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bankTransferReceipt;

    }

    private AlternativeFundingBid initializeBid(String funding_name, String id, String country,
                                                String totalAmount, String contractStartDate,
                                                String contractEndDate) {

        AlternativeFundingBid bid = new AlternativeFundingBid();
        bid.setBidName(funding_name);
        bid.setId(id);
        bid.setCountry(alternativeFundingBidManager.getCountry(country));
        bid.setBidNo(Integer.valueOf(id));
        bid.setTotalAmountRequested(Double.parseDouble(totalAmount));
        bid.setFirstPayment(Double.parseDouble(totalAmount)/2);
        bid.setSecondPayment(Double.parseDouble(totalAmount)/2);
        bid.setRound(FIRST_ROUND);
        try {
            if(contractStartDate != null){
                Date parsedStartDate = new SimpleDateFormat("yyyy-MM-dd").parse(contractStartDate);
                Timestamp start = new java.sql.Timestamp(parsedStartDate.getTime());
                bid.setContractStartDate(start);
            }

            if(contractEndDate != null){
                Date parsedEndDate = new SimpleDateFormat("yyyy-MM-dd").parse(contractEndDate);
                Timestamp end = new java.sql.Timestamp(parsedEndDate.getTime());
                bid.setContractEndDate(end);
            }
        } catch (ParseException e) {
            System.out.println("Start or end date null! ");
        }
        return bid;

    }

    private Invoice uploadInvoiceFile(String basePath, String funding_name, String invoicePdf,
                                      String invoiceDate, String invoiceNumber) throws ParseException {

        String fullPath = basePath + funding_name + "/" + invoicePdf;
        File file = new File(basePath + funding_name + "/" + invoicePdf);
        InputStream inputStream = null;
        Path source = Paths.get(fullPath);
        String contentType = null;
        Invoice invoice = null;
        try {
            inputStream = new FileInputStream(file);
            contentType = Files.probeContentType(source);
            invoice = new Invoice();
            invoice.setSource("portal");
            invoice.setNumber(invoiceNumber);
            Date parsedStartDate = new SimpleDateFormat("yyyy-MM-dd").parse(invoiceDate);
            Timestamp st = new java.sql.Timestamp(parsedStartDate.getTime());
            invoice.setDate(st);
            invoice = invoiceManager.saveInvoice(invoice);
            invoice = invoiceManager.uploadInvoice(invoice.getId(), contentType, inputStream);
            invoiceManager.saveInvoice(invoice);
        } catch (IOException | ManagerException e) {
            e.printStackTrace();
        }
        return invoice;
    }


}
