package com.ecep.contract.controller.project.satisfaction_survey;

import java.io.File;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import com.ecep.contract.util.ProxyUtils;
import org.springframework.util.StringUtils;

import com.ecep.contract.CompanyCustomerFileType;
import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.controller.tab.AbstEntityBasedTabSkin;
import com.ecep.contract.controller.tab.TabSkin;
import com.ecep.contract.converter.CompanyStringConverter;
import com.ecep.contract.converter.EmployeeStringConverter;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyCustomer;
import com.ecep.contract.model.CompanyCustomerEvaluationFormFile;
import com.ecep.contract.model.CompanyCustomerFile;
import com.ecep.contract.model.CustomerSatisfactionSurvey;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.Project;
import com.ecep.contract.service.CompanyCustomerFileService;
import com.ecep.contract.service.CompanyCustomerService;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.ProjectCostService;
import com.ecep.contract.service.ProjectQuotationService;
import com.ecep.contract.service.ProjectService;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.CustomerSatisfactionSurveyViewModel;

import javafx.application.Platform;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.event.ActionEvent;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.Tab;
import javafx.scene.control.TextField;
import javafx.stage.FileChooser;
import javafx.util.converter.LocalDateStringConverter;
import javafx.util.converter.LocalDateTimeStringConverter;
import lombok.Getter;
import lombok.Setter;

public class CustomerSatisfactionSurveyTabSkinBase
        extends
        AbstEntityBasedTabSkin<CustomerSatisfactionSurveyWindowController, CustomerSatisfactionSurvey, CustomerSatisfactionSurveyViewModel>
        implements TabSkin {

    @Setter
    private LocalDateTimeStringConverter localDateTimeStringConverter;
    @Setter
    private ProjectQuotationService projectQuotationService;
    @Setter
    private LocalDateStringConverter localDateStringConverter;
    @Setter
    private EmployeeStringConverter employeeStringConverter;
    @Setter
    private CompanyStringConverter companyStringConverter;
    @Setter
    private CompanyService companyService;
    @Setter
    private CompanyCustomerService customerService;
    @Setter
    private CompanyCustomerFileService customerFileService;
    @Setter
    private ProjectService projectService;
    @Setter
    private ProjectCostService projectCostService;

    private ProjectService getProjectService() {
        if (projectService == null) {
            projectService = getBean(ProjectService.class);
        }
        return projectService;
    }

    ProjectCostService getProjectCostService() {
        if (projectCostService == null) {
            projectCostService = getBean(ProjectCostService.class);
        }
        return projectCostService;
    }

    public CustomerSatisfactionSurveyTabSkinBase(CustomerSatisfactionSurveyWindowController controller) {
        super(controller);
    }

    static class Entity {
        String title;
        int min = 1;
        int max = 10;

        Label label;
        @Getter
        Slider slider;

        public Entity(String title, int min, int max) {
            this.title = title;
            this.min = min;
            this.max = max;
        }

        public Entity(String title, Label label, Slider slider) {
            this(title, 1, 10);
            this.label = label;
            this.slider = slider;
        }
    }

    static class Controls {
        Label label;
        Slider slider;
    }

    private SimpleIntegerProperty versionProperty = new SimpleIntegerProperty(1);

    @Override
    public Tab getTab() {
        return controller.baseInfoTab;
    }

    Entity[] entities = new Entity[] {
            new Entity("系统总体质量", controller.sliderLabel1, controller.slider1),
            new Entity("交货期", controller.sliderLabel2, controller.slider2),
            new Entity("外包装及标识", controller.sliderLabel3, controller.slider3),
            new Entity("人员礼貌态度", controller.sliderLabel4, controller.slider4),
            new Entity("问题回复速度", controller.sliderLabel5, controller.slider5),
            new Entity("性能价格比", controller.sliderLabel6, controller.slider6),
            new Entity("安装指导服务", controller.sliderLabel7, controller.slider7),
            new Entity("售后服务", controller.sliderLabel8, controller.slider8),
            new Entity("送检资料完整", controller.sliderLabel9, controller.slider9),
            new Entity("其它配合度", controller.sliderLabel10, controller.slider10)
    };

    ChangeListener<Number> scoreUpdater = (observable, oldValue, newValue) -> {
        try {
            double total = Arrays.stream(entities).map(Entity::getSlider).mapToDouble(Slider::getValue).sum();
            viewModel.getTotalScore().set((int) total);
            viewModel.getData().set(versionProperty.get() + ":" + Arrays.stream(entities)
                    .map(v -> String.valueOf((int) v.getSlider().getValue())).collect(Collectors.joining(",")));
            System.out.println("newValue = " + newValue);
        } catch (Exception e) {
            handleException("计算总分失败", e);
        }
    };

    @Override
    public void initializeTab() {
        String[] split = StringUtils.split(viewModel.getData().get(), ":");
        if (split != null) {
            versionProperty.set(Integer.parseInt(split[0]));
        }

        for (Entity entity : entities) {
            entity.label.setText(entity.title);
            entity.slider.setMax(entity.max);
            entity.slider.setMin(entity.min);
            entity.slider.setValue(9);
            entity.slider.valueProperty().addListener(scoreUpdater);
        }
        if (split != null) {
            String[] scores = split[1].split(",");
            for (int i = 0; i < entities.length; i++) {
                entities[i].slider.setValue(Integer.parseInt(scores[i]));
            }
        }
        controller.codeField.textProperty().bindBidirectional(viewModel.getCode());
        controller.dateField.textProperty().bindBidirectional(viewModel.getDate(), getLocalDateStringConverter());
        controller.totalScoreField.textProperty().bind(viewModel.getTotalScore().asString());

        employeeAutoCompletion(controller.applicantField, viewModel.getApplicant());
        controller.applyTimeField.textProperty().bindBidirectional(viewModel.getApplyTime(),
                getLocalDateTimeStringConverter());
        controller.descriptionField.textProperty().bindBidirectional(viewModel.getDescription());

        controller.importExcelBtn.setOnAction(event -> {
            FileChooser chooser = new FileChooser();
            chooser.setTitle("导入投标审批表");
            File file = chooser.showOpenDialog(getTab().getTabPane().getScene().getWindow());
            importFromExcel(file);
        });

        // if (getViewModel().getEvaluationFile().get() == null) {
        // CompletableFuture.runAsync(this::tryGetEvaluationFile).exceptionally(this::handleException);
        // }
        controller.exportExcelBtn.setOnAction(this::onExportExcelAction);
    }

    private void onExportExcelAction(ActionEvent event) {
        ProjectCustomerSatisfactionSurveyExportAsExcelFile tasker = new ProjectCustomerSatisfactionSurveyExportAsExcelFile();
        tasker.setSatisfactionSurvey(getEntity());
        UITools.showTaskDialogAndWait("导出Excel", tasker, null);
    }

    void setInitialDirectory(FileChooser fileChooser, File file, Project project) {
        if (file == null) {
            if (project != null) {
                if (!ProxyUtils.isInitialized(project)) {
                    project = getProjectService().findById(project.getId());
                }
                File path = getProjectService().searchPath(project);
                if (path != null) {
                    fileChooser.setInitialDirectory(path);
                }
            }
        } else {
            fileChooser.setInitialDirectory(file.getParentFile());
        }
    }

    /**
     * 尝试获取客户资信评估表
     */
    private void tryGetEvaluationFile() {
        Project project = getViewModel().getProject().get();
        if (project == null) {
            return;
        }
        if (!ProxyUtils.isInitialized(project)) {
            project = getProjectService().findById(project.getId());
        }
        Company company = project.getCustomer();
        CompanyCustomer customer = getCompanyCustomerService().findByCompany(company);
        if (customer == null) {
            return;
        }

        CompanyCustomerFileService companyCustomerFileService = getBean(CompanyCustomerFileService.class);
        List<CompanyCustomerFile> list = companyCustomerFileService.findAllByCustomerAndType(customer,
                CompanyCustomerFileType.EvaluationForm);
        if (list.isEmpty()) {
            return;
        }

        LocalDateTime applyTime = getViewModel().getApplyTime().get();
        LocalDate verifyDate = applyTime.toLocalDate();
        CompanyCustomerFile file = list.stream()
                .filter(v -> v.getSignDate() != null && v.isValid())
                .filter(v -> v.getType() == CompanyCustomerFileType.EvaluationForm)
                .filter(v -> MyDateTimeUtils.dateValidFilter(verifyDate, v.getSignDate(), v.getSignDate().plusYears(1),
                        7))
                .findFirst().orElse(null);
        if (file == null) {
            return;
        }

        CompanyCustomerEvaluationFormFile evaluationFile = companyCustomerFileService
                .findCustomerEvaluationFormFileByCustomerFile(file);
        if (evaluationFile == null) {
            return;
        }
        Platform.runLater(() -> {
            // getViewModel().getEvaluationFile().set(evaluationFile);
            save();
        });
    }

    private LocalDateTimeStringConverter getLocalDateTimeStringConverter() {
        if (localDateTimeStringConverter == null) {
            localDateTimeStringConverter = new LocalDateTimeStringConverter(
                    DateTimeFormatter.ofPattern(MyDateTimeUtils.DEFAULT_DATETIME_FORMAT_PATTERN), null);
        }
        return localDateTimeStringConverter;
    }

    private void uploadScanFile(File file) {
        // TODO
    }

    private void importFromExcel(File file) {
        // TODO
    }

    private void employeeAutoCompletion(TextField textField, SimpleObjectProperty<Employee> property) {
        UITools.autoCompletion(textField, property, getEmployeeStringConverter());
    }

    private void companyAutoCompletion(TextField textField, SimpleObjectProperty<Company> property) {
        UITools.autoCompletion(textField, property, getCompanyStringConverter());
    }

    private ProjectQuotationService getProjectQuotationService() {
        if (projectQuotationService == null) {
            projectQuotationService = getBean(ProjectQuotationService.class);
        }
        return projectQuotationService;
    }

    private LocalDateStringConverter getLocalDateStringConverter() {
        if (localDateStringConverter == null) {
            localDateStringConverter = new LocalDateStringConverter(DateTimeFormatter.ISO_LOCAL_DATE, null);
        }
        return localDateStringConverter;
    }

    private EmployeeStringConverter getEmployeeStringConverter() {
        if (employeeStringConverter == null) {
            employeeStringConverter = getBean(EmployeeStringConverter.class);
        }
        return employeeStringConverter;
    }

    public CompanyService getCompanyService() {
        if (companyService == null) {
            companyService = getBean(CompanyService.class);
        }
        return companyService;
    }

    private CompanyStringConverter getCompanyStringConverter() {
        if (companyStringConverter == null) {
            companyStringConverter = getBean(CompanyStringConverter.class);
        }
        return companyStringConverter;
    }

    private CompanyCustomerService getCompanyCustomerService() {
        if (customerService == null) {
            customerService = getBean(CompanyCustomerService.class);
        }
        return customerService;
    }

    private CompanyCustomerFileService getCompanyCustomerFileService() {
        if (customerFileService == null) {
            customerFileService = getBean(CompanyCustomerFileService.class);
        }
        return customerFileService;
    }
}
