package com.ecep.contract.vm;

import java.time.MonthDay;
import java.time.Year;
import java.util.Objects;

import com.ecep.contract.model.HistoryPrice;
import com.ecep.contract.model.Inventory;
import com.ecep.contract.model.InventoryHistoryPrice;

import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleObjectProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode(callSuper = false)
public class InventoryHistoryPriceViewModel extends IdentityViewModel<InventoryHistoryPrice> {
    private SimpleObjectProperty<Inventory> inventory = new SimpleObjectProperty<>();
    private SimpleObjectProperty<Year> year = new SimpleObjectProperty<>();
    // latest  price
    private SimpleFloatProperty latestSaleTax = new SimpleFloatProperty();
    private SimpleDoubleProperty latestSalePrice = new SimpleDoubleProperty();
    private SimpleDoubleProperty latestSaleTaxPrice = new SimpleDoubleProperty();
    private SimpleObjectProperty<MonthDay> latestSalePriceDate = new SimpleObjectProperty<>();

    private SimpleFloatProperty latestPurchaseTax = new SimpleFloatProperty();
    private SimpleDoubleProperty latestPurchasePrice = new SimpleDoubleProperty();
    private SimpleDoubleProperty latestPurchaseTaxPrice = new SimpleDoubleProperty();
    private SimpleObjectProperty<MonthDay> latestPurchasePriceDate = new SimpleObjectProperty<>();
    // mini price
    private SimpleFloatProperty miniSaleTax = new SimpleFloatProperty();
    private SimpleDoubleProperty miniSalePrice = new SimpleDoubleProperty();
    private SimpleDoubleProperty miniSaleTaxPrice = new SimpleDoubleProperty();
    private SimpleObjectProperty<MonthDay> miniSalePriceDate = new SimpleObjectProperty<>();

    private SimpleFloatProperty miniPurchaseTax = new SimpleFloatProperty();
    private SimpleDoubleProperty miniPurchasePrice = new SimpleDoubleProperty();
    private SimpleDoubleProperty miniPurchaseTaxPrice = new SimpleDoubleProperty();
    private SimpleObjectProperty<MonthDay> miniPurchasePriceDate = new SimpleObjectProperty<>();
    // max price
    private SimpleFloatProperty maxSaleTax = new SimpleFloatProperty();
    private SimpleDoubleProperty maxSalePrice = new SimpleDoubleProperty();
    private SimpleDoubleProperty maxSaleTaxPrice = new SimpleDoubleProperty();
    private SimpleObjectProperty<MonthDay> maxSalePriceDate = new SimpleObjectProperty<>();

    private SimpleFloatProperty maxPurchaseTax = new SimpleFloatProperty();
    private SimpleDoubleProperty maxPurchasePrice = new SimpleDoubleProperty();
    private SimpleDoubleProperty maxPurchaseTaxPrice = new SimpleDoubleProperty();
    private SimpleObjectProperty<MonthDay> maxPurchasePriceDate = new SimpleObjectProperty<>();

    void updateHistoryPrice(HistoryPrice historyPrice,
                            SimpleFloatProperty taxProperty,
                            SimpleDoubleProperty priceProperty, SimpleDoubleProperty taxPriceProperty,
                            SimpleObjectProperty<MonthDay> monthDayProperty
    ) {
        if (historyPrice == null) {
            taxProperty.set(0);
            priceProperty.set(0);
            taxPriceProperty.set(0);
            monthDayProperty.set(null);
            return;
        }
        taxProperty.set(historyPrice.getTaxRate());
        priceProperty.set(historyPrice.getPreTaxPrice());
        taxPriceProperty.set(historyPrice.getPostTaxPrice());
        monthDayProperty.set(historyPrice.getMonthDay());
    }

    @Override
    protected void updateFrom(InventoryHistoryPrice v) {
        super.updateFrom(v);
        inventory.set(v.getInventory());
        year.set(v.getYear());
        //  latest price
        updateHistoryPrice(v.getLatestPurchasePrice(), latestPurchaseTax, latestPurchasePrice, latestPurchaseTaxPrice, latestPurchasePriceDate);
        updateHistoryPrice(v.getLatestSalePrice(), latestSaleTax, latestSalePrice, latestSaleTaxPrice, latestSalePriceDate);

        //  min price
        updateHistoryPrice(v.getMiniPurchasePrice(), miniPurchaseTax, miniPurchasePrice, miniPurchaseTaxPrice, miniPurchasePriceDate);
        updateHistoryPrice(v.getMiniSalePrice(), miniSaleTax, miniSalePrice, miniSaleTaxPrice, miniSalePriceDate);

        //  max price
        updateHistoryPrice(v.getMaxPurchasePrice(), maxPurchaseTax, maxPurchasePrice, maxPurchaseTaxPrice, maxPurchasePriceDate);
        updateHistoryPrice(v.getMaxSalePrice(), maxSaleTax, maxSalePrice, maxSaleTaxPrice, maxSalePriceDate);
    }

    boolean copyTo(HistoryPrice historyPrice,
                   SimpleFloatProperty taxProperty,
                   SimpleDoubleProperty priceProperty, SimpleDoubleProperty taxPriceProperty,
                   SimpleObjectProperty<MonthDay> monthDayProperty
    ) {
        boolean modified = false;
        if (!Objects.equals(priceProperty.get(), historyPrice.getPreTaxPrice())) {
            historyPrice.setPreTaxPrice(priceProperty.get());
            modified = true;
        }
        if (!Objects.equals(taxProperty.get(), historyPrice.getTaxRate())) {
            historyPrice.setTaxRate(taxProperty.get());
            modified = true;
        }
        if (!Objects.equals(taxPriceProperty.get(), historyPrice.getPostTaxPrice())) {
            historyPrice.setPostTaxPrice(taxPriceProperty.get());
            modified = true;
        }
        if (!Objects.equals(monthDayProperty.get(), historyPrice.getMonthDay())) {
            historyPrice.setMonthDay(monthDayProperty.get());
            modified = true;
        }
        return modified;
    }

    @Override
    public boolean copyTo(InventoryHistoryPrice v) {
        boolean modified = super.copyTo(v);
        if (!Objects.equals(inventory.get(), v.getInventory())) {
            v.setInventory(inventory.get());
            modified = true;
        }
        if (!Objects.equals(year.get(), v.getYear())) {
            v.setYear(year.get().getValue());
            modified = true;
        }

        // latest price
        if (copyTo(v.getLatestPurchasePrice(), latestPurchaseTax, latestPurchasePrice, latestPurchaseTaxPrice, latestPurchasePriceDate)) {
            modified = true;
        }
        if (copyTo(v.getLatestSalePrice(), latestSaleTax, latestSalePrice, latestSaleTaxPrice, latestSalePriceDate)) {
            modified = true;
        }


        // mini price
        if (copyTo(v.getMiniPurchasePrice(), miniPurchaseTax, miniPurchasePrice, miniPurchaseTaxPrice, miniPurchasePriceDate)) {
            modified = true;
        }
        if (copyTo(v.getMiniSalePrice(), miniSaleTax, miniSalePrice, miniSaleTaxPrice, miniSalePriceDate)) {
            modified = true;
        }

        // max price
        if (copyTo(v.getMaxPurchasePrice(), maxPurchaseTax, maxPurchasePrice, maxPurchaseTaxPrice, maxPurchasePriceDate)) {
            modified = true;
        }
        if (copyTo(v.getMaxSalePrice(), maxSaleTax, maxSalePrice, maxSaleTaxPrice, maxSalePriceDate)) {
            modified = true;
        }

        return modified;
    }
}
