/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.arrebol.taxiservicios.controller.admin;

import com.arrebol.taxiservicios.model.admin.Sale;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.stocktaking.ServiceOrder;
import com.arrebol.taxiservicios.model.view.dashboard.SaleDashboardView;
import java.io.Serializable;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author Picasso
 */
public class SaleControllerTest {

    private static final String TAXI_ID = "8c13de42-9b9f-468c-a439-66ae2d972951";
    private static final String DRIVER_ID = "1a24616e-9576-4879-b6f9-e52c6fdf400f";
    private static final String DRIVER_ID_TWO = "0063e1ac-3daf-4a03-a2de-ac7187c7853b";
    private SaleController controller;
    private Date startDate;
    private Date endDate;

    public SaleControllerTest() {
    }

    @Before
    public void setUp() {
        controller = new SaleController();
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();

        //2021-08-04 09:07:04
        start.set(2021, 7, 4, 0, 0, 0);
        //2019-04-06 21:07:04
        end.set(2021, 3, 10, 21, 7, 4);
        startDate = start.getTime();
        endDate = end.getTime();
    }

    @Test
    public void findSaleByDriverIdEqualstoDate() {
        try {
            SaleDashboardView result = controller.findSaleByDriverIdEqualstoDate(DRIVER_ID_TWO, endDate);

            assertNotNull(result);
        } catch (Exception e) {
            assertTrue(false);
        }
    }

    //@Test
    public void fillDriversComboBox() {
        try {
            List<Person> drivers = controller.fillDriversComboBox();
            controller.getTotalSaleForMonth();
            controller.getTotalSavingForMonth();

            assertFalse(drivers.isEmpty());
        } catch (Exception e) {
            assertTrue(false);
        }
    }

    //@Test
    public void getTotalSaleForMonth() {
        try {

            assertNotNull(controller.getTotalSaleForMonth());
        } catch (Exception e) {
            assertTrue(false);
        }
    }

    //@Test
    public void updateToCollectByTaxyDriverAndPaymentDate() {
        try {
            controller.updateToCollectByTaxyDriverAndPaymentDate(DRIVER_ID, startDate, false, false, false);
        } catch (Exception e) {
        }
    }

    //@Test
    public void findServiceOrderByTaxiId() {
        try {
            Calendar c = Calendar.getInstance();

            //2019-03-07 09:07:04
            c.set(2019, 2, 7, 21, 7, 4);

            ServiceOrder order = controller.findServiceOrderByTaxiId(TAXI_ID, c.getTime());

            assertNotNull(order);
        } catch (Exception e) {
            assertTrue(false);
        }
    }

    //@Test
    public void getSalesbyDriver() {
        try {
            List<Sale> results = controller.getSalesbyDriver(DRIVER_ID, startDate, endDate);
            List<Object[]> styleDetails = controller.findStyleClassSaleByDriverIdBetweenDates(DRIVER_ID, startDate, endDate);
            verifySaleDetails(results, styleDetails);
        } catch (Exception e) {
            assertTrue(false);
        }
    }

    /**
     *
     * @param sales
     * @param styleDetails
     */
    private void verifySaleDetails(List<Sale> sales, List<Object[]> styleDetails) {
        Double[] pays = getPaysByIdDriver();

        /*
        for (Person drvr : getDrivers()) {
            if (getDriverId().equals(drvr.getId())) {
                setDriver(drvr);
                break;
            }
        }


        if (!sales.isEmpty()) {
            setTaxiId(sales.get(0).getTaxi().getId());
        }
         */
        sales.forEach((Sale s) -> {
            String record;
            //DefaultScheduleEvent ev = new DefaultScheduleEvent();
            SaleWrapper sw = new SaleWrapper("N/A", s.getId(), s.getPayDay(), s.getPaySaving(), s.getPayDate(), s.getDescription(), s.getAccident());

            sw.setDriver("Carlos Janitzio Zavala Lopez");

            if (pays[0] > s.getPayDay()
                    || pays[1] > s.getPaySaving()
                    || pays[2] > s.getAccident()) {
                sw.setIncomplete(true);

                double toComplete = 0;

                if (pays[0] > s.getPayDay()) {
                    sw.setPayDayUpdate(pays[0] - s.getPayDay());
                    sw.setPayDayDisabled(false);
                    toComplete += sw.getPayDayUpdate();
                }

                if (pays[1] > s.getPaySaving()) {
                    sw.setPaySavingUpdate(pays[1] - s.getPaySaving());
                    sw.setPaySavingisabled(false);
                    toComplete += sw.getPaySavingUpdate();
                }

                if (pays[2] > s.getAccident()) {
                    sw.setAccidentUpdate(pays[2] - s.getAccident());
                    sw.setAccidentisabled(false);
                    toComplete += sw.getAccidentUpdate();
                }

                NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.CANADA);
                String currency = nf.format(toComplete);
                String abonado = nf.format((sw.getPayDay() + sw.getPaySaving() + sw.getAccident()));
                String deTotal = nf.format((pays[0] + pays[1] + pays[2]));

                /*
                ev.setStyleClass("schedule-no-payed");
                ev.setTitle("Faltante " + currency);
                 */
                record = "style='schedule-no-payed', text=Faltante " + currency;

                Calendar saleCalendar = Calendar.getInstance();

                saleCalendar.setTime(sw.getPayDate());
                saleCalendar.set(Calendar.HOUR, 10);
                saleCalendar.set(Calendar.MINUTE, 0);
                saleCalendar.set(Calendar.SECOND, 0);
                saleCalendar.set(Calendar.MILLISECOND, 0);

                for (Object[] styleDetail : styleDetails) {
                    Calendar styleCalendar = Calendar.getInstance();

                    styleCalendar.setTime((Date) styleDetail[1]);
                    styleCalendar.set(Calendar.HOUR, 10);
                    styleCalendar.set(Calendar.MINUTE, 0);
                    styleCalendar.set(Calendar.SECOND, 0);
                    styleCalendar.set(Calendar.MILLISECOND, 0);

                    if (styleCalendar.equals(saleCalendar)) {
                        /*
                        ev.setStyleClass("schedule-payed");
                        ev.setTitle("Faltante " + currency);
                         */
                        record = "style='schedule-payed', text=Abonó " + abonado + " de " + deTotal;
                        break;
                    }
                }
            } else {
                sw.setComplete(true);

                record = "style='schedule-payed', text=Liquidada";

                /*
                ev.setStyleClass("schedule-payed");
                ev.setTitle("Liquidada");
                 */
            }
            records.add(record);

            /*
            ev.setData(sw);
            ev.setStartDate(s.getPayDate());
            ev.setEndDate(s.getPayDate());
            ev.setAllDay(true);

            getSaleScheduleModel().addEvent(ev);
             */
        });

        records.forEach(record -> {
            System.out.println(record);
        });
    }

    private Double[] getPaysByIdDriver() {
        Double[] pays = new Double[3];
        pays[0] = PAY_DAY;
        pays[1] = PAY_SAVING;
        pays[2] = PAY_ACCIDENT;

        return pays;
    }

    private static final Double PAY_DAY = 300d;
    private static final Double PAY_SAVING = 50d;
    private static final Double PAY_ACCIDENT = 50d;
    private List<String> records = new ArrayList<>();

}

class SaleWrapper implements Serializable {

    private static final long serialVersionUID = 6865376244107918939L;

    private String taxiId;
    private String saleId;
    private String driverId;
    private Double payDay;
    private Double paySaving;
    private Date payDate;
    private String description;
    private Double accident;
    private String driver;
    private boolean complete;
    private boolean incomplete;
    private Double payDayUpdate = 0.0;
    private Double paySavingUpdate = 0.0;
    private Double accidentUpdate = 0.0;
    private boolean payDayDisabled = true;
    private boolean paySavingisabled = true;
    private boolean accidentisabled = true;

    public SaleWrapper() {
    }

    /**
     *
     * @param driverId Driver Id
     * @param saleId Sale Id
     * @param payDay Payment day
     * @param paySaving Saving payment day
     * @param payDate Dat of the payment
     * @param description Description
     * @param accident accident payment day
     */
    public SaleWrapper(String driverId, String saleId, Double payDay, Double paySaving, Date payDate, String description, Double accident) {
        this.driverId = driverId;
        this.saleId = saleId;
        this.payDay = payDay;
        this.paySaving = paySaving;
        this.payDate = payDate;
        this.description = description;
        this.accident = accident;
    }

    public String getTaxiId() {
        return taxiId;
    }

    public void setTaxiId(String taxiId) {
        this.taxiId = taxiId;
    }

    public String getSaleId() {
        return saleId;
    }

    public void setSaleId(String saleId) {
        this.saleId = saleId;
    }

    public void setDriverId(String driverId) {
        this.driverId = driverId;
    }

    public String getDriverId() {
        return driverId;
    }

    public Double getPayDay() {
        return payDay;
    }

    public void setPayDay(Double payDay) {
        this.payDay = payDay;
    }

    public Double getPaySaving() {
        return paySaving;
    }

    public void setPaySaving(Double paySaving) {
        this.paySaving = paySaving;
    }

    public Date getPayDate() {
        return payDate;
    }

    public void setPayDate(Date payDate) {
        this.payDate = payDate;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Double getAccident() {
        return accident;
    }

    public void setAccident(Double accident) {
        this.accident = accident;
    }

    public String getDriver() {
        return driver;
    }

    public void setDriver(String driver) {
        this.driver = driver;
    }

    public boolean isComplete() {
        return complete;
    }

    public void setComplete(boolean complete) {
        this.complete = complete;
    }

    public void setIncomplete(boolean incomplete) {
        this.incomplete = incomplete;
    }

    public boolean isIncomplete() {
        return incomplete;
    }

    public Double getPayDayUpdate() {
        return payDayUpdate;
    }

    public void setPayDayUpdate(Double payDayUpdate) {
        this.payDayUpdate = payDayUpdate;
    }

    public Double getPaySavingUpdate() {
        return paySavingUpdate;
    }

    public void setPaySavingUpdate(Double paySavingUpdate) {
        this.paySavingUpdate = paySavingUpdate;
    }

    public Double getAccidentUpdate() {
        return accidentUpdate;
    }

    public void setAccidentUpdate(Double accidentUpdate) {
        this.accidentUpdate = accidentUpdate;
    }

    public boolean isPayDayDisabled() {
        return payDayDisabled;
    }

    public void setPayDayDisabled(boolean payDayDisabled) {
        this.payDayDisabled = payDayDisabled;
    }

    public boolean isPaySavingisabled() {
        return paySavingisabled;
    }

    public void setPaySavingisabled(boolean paySavingisabled) {
        this.paySavingisabled = paySavingisabled;
    }

    public boolean isAccidentisabled() {
        return accidentisabled;
    }

    public void setAccidentisabled(boolean accidentisabled) {
        this.accidentisabled = accidentisabled;
    }

    @Override
    public String toString() {
        return "SaleWrapper{" + "taxiId=" + taxiId + ", saleId=" + saleId + ", payDate=" + payDate + ", description=" + description + '}';
    }

}
