package com.ecep.contract.vm;

import java.io.File;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;

import org.springframework.util.StringUtils;

import com.ecep.contract.model.CompanyCustomerEvaluationFormFile;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.Project;
import com.ecep.contract.model.ProjectBid;
import com.ecep.contract.model.ProjectCost;
import com.ecep.contract.util.NumberUtils;

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

/**
 * 项目报价
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class ProjectBidViewModel extends IdentityViewModel<ProjectBid> implements ProjectBasedViewModel {
    /**
     * 关联的项目
     */
    private SimpleObjectProperty<Project> project = new SimpleObjectProperty<>();
    /**
     * 客户咨询等级（级别）
     */
    private SimpleIntegerProperty level = new SimpleIntegerProperty();

    /**
     * 报价金额
     */
    private SimpleDoubleProperty amount = new SimpleDoubleProperty();
    /**
     * 客户咨询评估文件，根据资信资评估文件生成客户资信等级（级别）
     */
    private SimpleObjectProperty<CompanyCustomerEvaluationFormFile> evaluationFile = new SimpleObjectProperty<>();
    /**
     * 项目成本表
     */
    private SimpleObjectProperty<ProjectCost> cost = new SimpleObjectProperty<>();

    /**
     * 是否标准付款方式
     */
    private SimpleBooleanProperty standardPayWay = new SimpleBooleanProperty();
    /**
     * 非标准付款方式文本
     */
    private SimpleStringProperty noStandardPayWayText = new SimpleStringProperty();
    /**
     * 是否标准合同文本
     */
    private SimpleBooleanProperty standardContractText = new SimpleBooleanProperty();
    /**
     * 非标准合同文本
     */
    private SimpleStringProperty noStandardContractText = new SimpleStringProperty();
    /**
     * 申请日期
     */
    private SimpleObjectProperty<LocalDateTime> applyTime = new SimpleObjectProperty<>();
    /**
     * 申请人
     */
    private SimpleObjectProperty<Employee> applicant = new SimpleObjectProperty<>();
    /**
     * 审核时间
     */
    private SimpleObjectProperty<LocalDateTime> authorizationTime = new SimpleObjectProperty<>();
    /**
     * 审核人
     */
    private SimpleObjectProperty<Employee> authorizer = new SimpleObjectProperty<>();
    /**
     * 审核文件
     */
    private SimpleObjectProperty<File> authorizationFile = new SimpleObjectProperty<>();
    /**
     * 中标通知书文件
     */
    private SimpleObjectProperty<File> bidAcceptanceLetterFile = new SimpleObjectProperty<>();

    /**
     * 说明、注释
     */
    private SimpleStringProperty description = new SimpleStringProperty();

    public static ProjectBidViewModel from(ProjectBid v) {
        ProjectBidViewModel model = new ProjectBidViewModel();
        model.update(v);
        return model;
    }

    @Override
    protected void updateFrom(ProjectBid v) {
        super.updateFrom(v);
        getProject().set(v.getProject());
        getLevel().set(v.getLevel());
        getAmount().set(v.getAmount());
        getEvaluationFile().set(v.getEvaluationFile());
        getCost().set(v.getCost());
        getStandardPayWay().set(v.isStandardPayWay());
        getNoStandardPayWayText().set(v.getNoStandardPayWayText());
        getStandardContractText().set(v.isStandardContractText());
        getNoStandardContractText().set(v.getNoStandardContractText());
        getApplicant().set(v.getApplicant());
        getApplyTime().set(v.getApplyTime());
        getAuthorizer().set(v.getAuthorizer());
        getAuthorizationTime().set(v.getAuthorizationTime());

        if (StringUtils.hasText(v.getAuthorizationFile())) {
            File file = new File(v.getAuthorizationFile());
            getAuthorizationFile().set(file);
        } else {
            getAuthorizationFile().set(null);
        }

        if (StringUtils.hasText(v.getBidAcceptanceLetterFile())) {
            File file = new File(v.getBidAcceptanceLetterFile());
            getBidAcceptanceLetterFile().set(file);
        } else {
            getBidAcceptanceLetterFile().set(null);
        }

        getDescription().set(v.getDescription());
    }

    @Override
    public boolean copyTo(ProjectBid v) {
        boolean modified = super.copyTo(v);
        if (!Objects.equals(getProject().get(), v.getProject())) {
            v.setProject(getProject().get());
            modified = true;
        }
        if (!Objects.equals(getLevel().get(), v.getLevel())) {
            v.setLevel(getLevel().get());
            modified = true;
        }
        if (!NumberUtils.equals(getAmount().get(), v.getAmount())) {
            v.setAmount(getAmount().get());
            modified = true;
        }
        if (!Objects.equals(getEvaluationFile().get(), v.getEvaluationFile())) {
            v.setEvaluationFile(getEvaluationFile().get());
            modified = true;
        }
        if (!Objects.equals(getCost().get(), v.getCost())) {
            v.setCost(getCost().get());
            modified = true;
        }

        if (!Objects.equals(getStandardPayWay().get(), v.isStandardPayWay())) {
            v.setStandardPayWay(getStandardPayWay().get());
            modified = true;
        }
        if (!Objects.equals(getNoStandardPayWayText().get(), v.getNoStandardPayWayText())) {
            v.setNoStandardPayWayText(getNoStandardPayWayText().get());
            modified = true;
        }
        if (!Objects.equals(getStandardContractText().get(), v.isStandardContractText())) {
            v.setStandardContractText(getStandardContractText().get());
            modified = true;
        }
        if (!Objects.equals(getNoStandardContractText().get(), v.getNoStandardContractText())) {
            v.setNoStandardContractText(getNoStandardContractText().get());
            modified = true;
        }

        if (!Objects.equals(getApplicant().get(), v.getApplicant())) {
            v.setApplicant(getApplicant().get());
            modified = true;
        }
        if (!Objects.equals(getApplyTime().get(), v.getApplyTime())) {
            v.setApplyTime(getApplyTime().get());
            modified = true;
        }
        if (!Objects.equals(getAuthorizer().get(), v.getAuthorizer())) {
            v.setAuthorizer(getAuthorizer().get());
            modified = true;
        }
        if (!Objects.equals(getAuthorizationTime().get(), v.getAuthorizationTime())) {
            v.setAuthorizationTime(getAuthorizationTime().get());
            modified = true;
        }

        if (updateFile(authorizationFile, v::getAuthorizationFile, v::setAuthorizationFile)) {
            modified = true;
        }

        if (updateFile(bidAcceptanceLetterFile, v::getBidAcceptanceLetterFile, v::setBidAcceptanceLetterFile)) {
            modified = true;
        }

        if (!Objects.equals(getDescription().get(), v.getDescription())) {
            v.setDescription(getDescription().get());
            modified = true;
        }
        return modified;
    }

    private boolean updateFile(SimpleObjectProperty<File> property, Supplier<String> getter, Consumer<String> setter) {
        File file = null;
        String path = getter.get();
        if (StringUtils.hasText(path)) {
            file = new File(path);
        }
        if (!Objects.equals(property.get(), file)) {
            setter.accept(property.get() == null ? null : property.get().getAbsolutePath());
            return true;
        }
        return false;
    }
}
