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

import java.io.File;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.CompletableFuture;

import com.ecep.contract.DesktopUtils;
import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.controller.customer.CompanyCustomerEvaluationFormFileWindowController;
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.Employee;
import com.ecep.contract.service.CompanyCustomerEvaluationFormFileService;
import com.ecep.contract.service.CompanyCustomerFileService;
import com.ecep.contract.service.CompanyCustomerService;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.ProjectQuotationService;
import com.ecep.contract.service.ProjectService;
import com.ecep.contract.util.ProxyUtils;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.ProjectQuotationViewModel;
import com.ecep.contract.vo.CompanyCustomerEvaluationFormFileVo;
import com.ecep.contract.vo.CompanyVo;
import com.ecep.contract.vo.ProjectQuotationVo;
import com.ecep.contract.vo.ProjectVo;

import javafx.beans.property.SimpleObjectProperty;
import javafx.event.ActionEvent;
import javafx.scene.control.Tab;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.stage.FileChooser;
import javafx.util.converter.LocalDateStringConverter;
import javafx.util.converter.LocalDateTimeStringConverter;
import javafx.util.converter.NumberStringConverter;
import lombok.Setter;

public class ProjectQuotationTabSkinBase
        extends AbstEntityBasedTabSkin<ProjectQuotationWindowController, ProjectQuotationVo, ProjectQuotationViewModel>
        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 CompanyCustomerEvaluationFormFileService evaluationFormFileService;
    @Setter
    private ProjectService projectService;

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

    public ProjectQuotationTabSkinBase(ProjectQuotationWindowController controller) {
        super(controller);
    }

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

    void setSelectedToggle(ToggleGroup group, int targetLevel) {
        group.getToggles().stream()
                .filter(toggle -> toggle.getUserData() instanceof Integer)
                .filter(toggle -> (Integer) toggle.getUserData() == targetLevel)
                .findFirst()
                .ifPresent(group::selectToggle);
    }

    @Override
    public void initializeTab() {
        controller.openFileBtn.setOnAction(event -> {
            DesktopUtils.showInExplorer(viewModel.getAuthorizationFile().get());
        });
        controller.openFileBtn.disableProperty().bind(viewModel.getAuthorizationFile().isNull());
        controller.changeFileBtn.setOnAction(this::onChangeAuthorizationFileAction);

        UITools.autoCompletion(controller.applicantField, viewModel.getApplicant(), controller.getEmployeeService());
        controller.applyTimeField.textProperty().bindBidirectional(viewModel.getApplyTime(),
                getLocalDateTimeStringConverter());
        //
        UITools.autoCompletion(controller.authorizerField, viewModel.getAuthorizer(), controller.getEmployeeService());
        controller.authorizationTimeField.textProperty().bindBidirectional(viewModel.getAuthorizationTime(),
                getLocalDateTimeStringConverter());

        // viewModel.getLevel();
        ToggleGroup levelGroup = new ToggleGroup();
        controller.good_radio_btn.setToggleGroup(levelGroup);
        controller.good_radio_btn.setUserData(2);
        controller.bad_radio_btn.setToggleGroup(levelGroup);
        controller.bad_radio_btn.setUserData(1);
        controller.poor_radio_btn.setToggleGroup(levelGroup);
        controller.poor_radio_btn.setUserData(0);
        setSelectedToggle(levelGroup, viewModel.getLevel().get());
        // levelGroup;
        // UI -> ViewModel
        levelGroup.selectedToggleProperty().addListener((obs, oldToggle, newToggle) -> {
            if (newToggle != null && newToggle.getUserData() instanceof Integer) {
                viewModel.getLevel().set((Integer) newToggle.getUserData());
            }
        });

        // ViewModel -> UI: 监听 level 属性变化
        viewModel.getLevel().addListener((obs, oldVal, newVal) -> {
            if (newVal == null)
                return;
            setSelectedToggle(levelGroup, newVal.intValue());
        });

        controller.standardPayWayField.selectedProperty().bindBidirectional(viewModel.getStandardPayWay());
        controller.noStandardPayWayTextField.textProperty().bindBidirectional(viewModel.getNoStandardPayWayText());
        controller.noStandardPayWayTextField.disableProperty().bind(controller.standardPayWayField.selectedProperty());
        controller.amountField.textProperty().bindBidirectional(viewModel.getAmount(),
                new NumberStringConverter(getLocale()));

        UITools.autoCompletion(controller.evaluationFileField, viewModel.getEvaluationFile(),
                getEvaluationFormFileService());

        controller.authorizationFileField.textProperty().bind(viewModel.getAuthorizationFile().map(File::getName));

        controller.descriptionField.textProperty().bindBidirectional(viewModel.getDescription());

        controller.evaluationFileBtn.setOnAction(event -> {
            CompletableFuture.runAsync(() -> {
                Integer formFileId = viewModel.getEvaluationFile().get();
                CompanyCustomerEvaluationFormFileVo file = getEvaluationFormFileService().findById(formFileId);
                if (file != null) {
                    // 直接使用Vo对象，不再需要初始化检查
                    CompanyCustomerEvaluationFormFileWindowController.show(file,
                            getTab().getTabPane().getScene().getWindow());
                }
            }).exceptionally(this::handleException);
        });

        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);
        }

        if (getViewModel().getAuthorizationFile().get() == null) {
            CompletableFuture.runAsync(this::tryGetAuthorizationFile).exceptionally(this::handleException);
        }

    }

    private void onChangeAuthorizationFileAction(ActionEvent event) {
        FileChooser fileChooser = new FileChooser();
        File file = viewModel.getAuthorizationFile().get();
        if (file == null) {
            Integer projectId = viewModel.getProject().get();
            ProjectVo project = getProjectService().findById(projectId);
            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());
        }
        File selectedFile = fileChooser.showOpenDialog(getTab().getTabPane().getScene().getWindow());
        if (selectedFile != null) {
            viewModel.getAuthorizationFile().set(selectedFile);
            save();
        }
    }

    private void tryGetEvaluationFile() {
        // 不需要再手动转换Vo为实体
        // 该方法已不再需要实现，因为我们直接使用Vo
    }

    private void tryGetAuthorizationFile() {
        // 直接使用Vo类，不再需要手动转换实体
        // 该方法已不再需要实现，因为我们直接使用Vo
    }

    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 evaluationFileAutoCompletion(TextField textField,
            SimpleObjectProperty<CompanyCustomerEvaluationFormFileVo> property) {
        // 直接使用Vo类，不再需要手动转换
    }

    private ProjectQuotationService getProjectQuotationService() {
        return getBean(ProjectQuotationService.class);
    }

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

    private EmployeeStringConverter getEmployeeStringConverter() {
        return getBean(EmployeeStringConverter.class);
    }

    public CompanyService getCompanyService() {
        return getBean(CompanyService.class);
    }

    private CompanyStringConverter getCompanyStringConverter() {
        return getBean(CompanyStringConverter.class);
    }

    private CompanyCustomerService getCompanyCustomerService() {
        return getBean(CompanyCustomerService.class);
    }

    private CompanyCustomerFileService getCompanyCustomerFileService() {
        return getBean(CompanyCustomerFileService.class);
    }

    private CompanyCustomerEvaluationFormFileService getEvaluationFormFileService() {
        return getBean(CompanyCustomerEvaluationFormFileService.class);
    }
}
