package com.ecep.contract.vm;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Objects;

import com.ecep.contract.vo.ContractItemVo;

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

/**
 * 合同内容
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class ContractItemViewModel extends IdentityViewModel<ContractItemVo> {
    /**
     * 关联的合同对象,Contract
     */
    SimpleObjectProperty<Integer> contract = new SimpleObjectProperty<>();
    /**
     * 关联的用友系统中的数据ID
     */
    SimpleIntegerProperty refId = new SimpleIntegerProperty();
    SimpleObjectProperty<String> code = new SimpleObjectProperty<>();
    SimpleObjectProperty<String> title = new SimpleObjectProperty<>();
    SimpleObjectProperty<String> specification = new SimpleObjectProperty<>();
    SimpleObjectProperty<String> unit = new SimpleObjectProperty<>();

    /**
     * 存货,Inventory
     */
    SimpleObjectProperty<Integer> inventory = new SimpleObjectProperty<>();

    /**
     *
     */
    SimpleDoubleProperty taxRate = new SimpleDoubleProperty();
    SimpleDoubleProperty exclusiveTaxPrice = new SimpleDoubleProperty();
    SimpleDoubleProperty taxPrice = new SimpleDoubleProperty();
    SimpleDoubleProperty quantity = new SimpleDoubleProperty();
    SimpleDoubleProperty taxAmount = new SimpleDoubleProperty();
    SimpleDoubleProperty exclusiveTaxAmount = new SimpleDoubleProperty();

    SimpleObjectProperty<LocalDate> startDate = new SimpleObjectProperty<>();
    SimpleObjectProperty<LocalDate> endDate = new SimpleObjectProperty<>();

    SimpleObjectProperty<LocalDateTime> createDate = new SimpleObjectProperty<>();
    SimpleObjectProperty<LocalDateTime> updateDate = new SimpleObjectProperty<>();
    /**
     * 关联的创建人,Employee
     */
    SimpleObjectProperty<Integer> creator = new SimpleObjectProperty<>();
    /**
     * 关联的更新人,Employee
     */
    SimpleObjectProperty<Integer> updater = new SimpleObjectProperty<>();

    SimpleObjectProperty<String> remark = new SimpleObjectProperty<>();

    @Override
    protected void updateFrom(ContractItemVo v) {
        super.updateFrom(v);
        getContract().set(v.getContractId());
        getRefId().set(v.getRefId());
        getCode().set(v.getItemCode());
        getTitle().set(v.getTitle());
        getSpecification().set(v.getSpecification());
        getUnit().set(v.getUnit());
        getInventory().set(v.getInventoryId());

        getExclusiveTaxPrice().set(v.getExclusiveTaxPrice());
        getTaxRate().set(v.getTaxRate());
        getTaxPrice().set(v.getTaxPrice());
        getQuantity().set(v.getQuantity());

        getStartDate().set(v.getStartDate());
        getEndDate().set(v.getEndDate());

        getCreateDate().set(v.getCreateDate());
        getUpdateDate().set(v.getUpdateDate());
        getCreator().set(v.getCreatorId());
        getUpdater().set(v.getUpdaterId());
        getRemark().set(v.getRemark());

        getTaxAmount().set(v.getTaxPrice() * v.getQuantity());
        getExclusiveTaxAmount().set(v.getExclusiveTaxPrice() * v.getQuantity());
    }

    @Override
    public boolean copyTo(ContractItemVo v) {
        boolean modified = super.copyTo(v);
        if (!Objects.equals(contract.get(), v.getContractId())) {
            v.setContractId(contract.get());
            modified = true;
        }
        if (!Objects.equals(refId.get(), v.getRefId())) {
            v.setRefId(refId.get());
            modified = true;
        }
        if (!Objects.equals(code.get(), v.getItemCode())) {
            v.setItemCode(code.get());
            modified = true;
        }
        if (!Objects.equals(title.get(), v.getTitle())) {
            v.setTitle(title.get());
            modified = true;
        }
        if (!Objects.equals(specification.get(), v.getSpecification())) {
            v.setSpecification(specification.get());
            modified = true;
        }
        if (!Objects.equals(unit.get(), v.getUnit())) {
            v.setUnit(unit.get());
            modified = true;
        }
        if (!Objects.equals(inventory.get(), v.getInventoryId())) {
            v.setInventoryId(inventory.get());
            modified = true;
        }
        if (!doubleEquals(exclusiveTaxPrice.get(), v.getExclusiveTaxPrice())) {
            v.setExclusiveTaxPrice(exclusiveTaxPrice.get());
            modified = true;
        }
        if (!doubleEquals(taxRate.get(), v.getTaxRate())) {
            v.setTaxRate(taxRate.get());
            modified = true;
        }
        if (!doubleEquals(taxPrice.get(), v.getTaxPrice())) {
            v.setTaxPrice(taxPrice.get());
            modified = true;
        }
        if (!doubleEquals(quantity.get(), v.getQuantity())) {
            v.setQuantity(quantity.get());
            modified = true;
        }

        if (!Objects.equals(startDate.get(), v.getStartDate())) {
            v.setStartDate(startDate.get());
            modified = true;
        }
        if (!Objects.equals(endDate.get(), v.getEndDate())) {
            v.setEndDate(endDate.get());
            modified = true;
        }

        if (!Objects.equals(createDate.get(), v.getCreateDate())) {
            v.setCreateDate(createDate.get());
            modified = true;
        }
        if (!Objects.equals(updateDate.get(), v.getUpdateDate())) {
            v.setUpdateDate(updateDate.get());
            modified = true;
        }
        if (!Objects.equals(creator.get(), v.getCreatorId())) {
            v.setCreatorId(creator.get());
            modified = true;
        }
        if (!Objects.equals(updater.get(), v.getUpdaterId())) {
            v.setUpdaterId(updater.get());
            modified = true;
        }
        if (!Objects.equals(remark.get(), v.getRemark())) {
            v.setRemark(remark.get());
            modified = true;
        }

        return modified;
    }

    /**
     * 判断两个 double 值是否相等
     *
     * @param a a
     * @param b b
     * @return 在误差范围内是否相同
     */
    private boolean doubleEquals(double a, double b) {
        return Math.abs(a - b) < 0.0001;
    }

    public static ContractItemViewModel from(ContractItemVo contractItem) {
        ContractItemViewModel viewModel = new ContractItemViewModel();
        viewModel.update(contractItem);
        return viewModel;
    }
}
