package com.ecep.contract.controller.customer;

import java.io.File;
import java.time.LocalDate;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import org.springframework.util.StringUtils;

import com.ecep.contract.CustomerFileType;
import com.ecep.contract.DesktopUtils;
import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.SpringApp;
import com.ecep.contract.constant.CompanyCustomerConstant;
import com.ecep.contract.controller.customer.tasker.CustomerEvaluationFormUpdateTask;
import com.ecep.contract.controller.customer.tasker.CustomerNextSignDateTask;
import com.ecep.contract.controller.table.EditableEntityTableTabSkin;
import com.ecep.contract.controller.table.cell.CompanyCustomerFileTableTypeTableCell;
import com.ecep.contract.controller.table.cell.FilePathTableCell;
import com.ecep.contract.service.CompanyCustomerEvaluationFormFileService;
import com.ecep.contract.service.CompanyCustomerFileService;
import com.ecep.contract.service.CompanyCustomerFileTypeService;
import com.ecep.contract.service.CustomerService;
import com.ecep.contract.task.CustomerFileMoveTasker;
import com.ecep.contract.util.FileUtils;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.CustomerFileViewModel;
import com.ecep.contract.vo.CompanyCustomerEvaluationFormFileVo;
import com.ecep.contract.vo.CustomerFileVo;
import com.ecep.contract.vo.CompanyVo;
import com.ecep.contract.vo.CustomerVo;

import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import lombok.Setter;

@FxmlPath("/ui/company/customer/customer-tab-file.fxml")
public class CustomerTabSkinFile
        extends AbstCompanyCustomerTableTabSkin<CustomerFileVo, CustomerFileViewModel>
        implements EditableEntityTableTabSkin<CustomerFileVo, CustomerFileViewModel> {

    @Setter
    private CompanyCustomerFileService companyCustomerFileService;

    public TableColumn<CustomerFileViewModel, Number> fileTable_idColumn;
    public TableColumn<CustomerFileViewModel, CustomerFileType> fileTable_typeColumn;
    public TableColumn<CustomerFileViewModel, String> fileTable_filePathColumn;
    public TableColumn<CustomerFileViewModel, String> fileTable_editFilePathColumn;
    public TableColumn<CustomerFileViewModel, LocalDate> fileTable_signDateColumn;
    public TableColumn<CustomerFileViewModel, Boolean> fileTable_validColumn;
    public TableColumn<CustomerFileViewModel, String> fileTable_descriptionColumn;

    public Button fileTable_reBuildBtn;
    public Button fileTable_updateEvaluationFormBuildBtn;
    public Button fileTable_calcNextSignDateBtn;
    public MenuItem fileTable_menu_refresh;
    public MenuItem fileTable_menu_add;
    public MenuItem fileTable_menu_del;

    public CustomerTabSkinFile(CompanyCustomerWindowController controller) {
        super(controller);
        setDragAndDrop(true);
        setDragAndDropFileHandler(this::moveFileToCustomer);
    }

    // 文件 tab
    @Override
    public Tab getTab() {
        return controller.fileTab;
    }

    @Override
    protected CompanyCustomerFileService getViewModelService() {
        return getCompanyCustomerFileService();
    }

    public CompanyCustomerEvaluationFormFileService getEvaluationFormFileService() {
        return getCachedBean(CompanyCustomerEvaluationFormFileService.class);
    }

    @Override
    public ParamUtils.Builder getSpecification(CustomerVo parent) {
        ParamUtils.Builder params = getSpecification();
        params.equals("customer", parent.getId());
        return params;
    }

    @Override
    public void initializeTable() {
        super.initializeTable();

        TableView<CustomerFileViewModel> table = getTableView();

        table.disableProperty().bind(viewModel.getPath().isEmpty());
        fileTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
        CompanyCustomerFileTypeService fileTypeService = getCachedBean(CompanyCustomerFileTypeService.class);
        fileTable_typeColumn.setCellValueFactory(param -> param.getValue().getType());
        fileTable_typeColumn.setCellFactory(CompanyCustomerFileTableTypeTableCell.forTableColumn(fileTypeService));

        fileTable_filePathColumn.setCellValueFactory(param -> param.getValue().getFilePath());
        fileTable_filePathColumn.setCellFactory(FilePathTableCell.forTableColumn(viewModel.getPath()));

        fileTable_editFilePathColumn.setCellValueFactory(param -> param.getValue().getEditFilePath());
        fileTable_editFilePathColumn.setCellFactory(FilePathTableCell.forTableColumn(viewModel.getPath()));

        fileTable_signDateColumn.setCellValueFactory(param -> param.getValue().getSignDate());
        fileTable_validColumn.setEditable(true);
        fileTable_validColumn.setCellValueFactory(param -> param.getValue().getValid());
        fileTable_validColumn.setCellFactory(param -> new CheckBoxTableCell<>());

        table.setOnDragOver(event -> {
            Dragboard dragboard = event.getDragboard();
            if (dragboard.hasFiles()) {
                event.acceptTransferModes(TransferMode.MOVE);
            }
            event.consume();
        });

        table.setOnDragDropped(event -> {
            Dragboard dragboard = event.getDragboard();
            boolean success = false;
            if (dragboard.hasFiles()) {
                List<File> files = dragboard.getFiles();
                CompletableFuture.runAsync(() -> {
                    try {
                        moveFileToCustomer(files);
                    } catch (Exception e) {
                        UITools.showExceptionAndWait("移动文件出错", e);
                    }
                });
            }
            event.setDropCompleted(success);
            event.consume();
        });

        fileTable_reBuildBtn.setOnAction(this::onFileReBuildingAction);
        fileTable_updateEvaluationFormBuildBtn.setOnAction(this::onUpdateEvaluationFormAction);
        fileTable_calcNextSignDateBtn.setOnAction(this::onCalcNextSignDateAction);

        fileTable_menu_refresh.setOnAction(this::onTableRefreshAction);
        fileTable_menu_add.setOnAction(this::onTableDeleteAction);
        fileTable_menu_del.setOnAction(this::onFileTableMoveToCompanyPathAction);
    }

    @Override
    protected void onTableRowDoubleClickedAction(CustomerFileViewModel item) {
        CustomerFileType fileType = item.getType().get();
        if (fileType == CustomerFileType.EvaluationForm) {

            // 文件不是 Excel 文件时，打开编辑UI
            if (!FileUtils.withExtensions(item.getFilePath().get(), FileUtils.XLS,
                    FileUtils.XLSX)) {
                CompanyCustomerEvaluationFormFileVo evaluationFormFile = getEvaluationFormFileService()
                        .findByCustomerFile(item.getId().get());
                CompanyCustomerEvaluationFormFileWindowController.show(evaluationFormFile,
                        controller.root.getScene().getWindow());
                return;
            }
        }
        File file = new File(item.getFilePath().get());
        if (!file.exists()) {
            setStatus("文件不存在 " + file.getName());
            return;
        }
        DesktopUtils.showInExplorer(file);
    }

    private void moveFileToCustomer(List<File> files) {
        String path = viewModel.getPath().get();
        if (!StringUtils.hasText(path)) {
            setStatus("未设置目录");
            return;
        }
        File dir = new File(path);
        if (!dir.exists()) {
            setStatus("目录错误,不存在");
            return;
        }
        CustomerVo companyCustomer = getParent();
        LocalDate nextSignDate = getCompanyCustomerFileService().getNextSignDate(companyCustomer,
                ((level, message) -> setStatus(message)));
        if (nextSignDate != null && files.size() == 1) {
            File file = files.getFirst();
            String fileName = file.getName();
            if (fileName.startsWith("S")) {
                String destFileName = CompanyCustomerConstant.EVALUATION_FORM_NAME2 + "_"
                        + MyDateTimeUtils.format(nextSignDate)
                        + "." + StringUtils.getFilenameExtension(fileName);
                File dest = new File(dir, destFileName);
                if (file.renameTo(dest)) {
                    CustomerFileVo ccf = new CustomerFileVo();
                    ccf.setCustomer(companyCustomer.getId());
                    ccf.setType(CustomerFileType.EvaluationForm);
                    ccf.setFilePath(dest.getAbsolutePath());
                    ccf.setSignDate(nextSignDate);
                    ccf.setValid(false);
                    CustomerFileVo saved = getCompanyCustomerFileService().save(ccf);
                    Platform.runLater(() -> {
                        CustomerFileViewModel model = new CustomerFileViewModel();
                        model.update(saved);
                        dataSet.add(model);

                        CompanyCustomerEvaluationFormFileVo evaluationFormFile = getCachedBean(
                                CompanyCustomerEvaluationFormFileService.class).findByCustomerFile(saved);

                        CompanyCustomerEvaluationFormFileWindowController.show(evaluationFormFile,
                                getTableView().getScene().getWindow());
                    });
                    return;
                }
            }

        }

        for (File file : files) {
            File dest = new File(dir, file.getName());
            if (file.renameTo(dest)) {
                CustomerFileVo ccf = new CustomerFileVo();
                ccf.setCustomer(companyCustomer.getId());
                ccf.setType(CustomerFileType.General);
                ccf.setFilePath(dest.getAbsolutePath());
                ccf.setValid(false);
                getCompanyCustomerFileService().save(ccf);
            }
        }
        loadTableDataSet();
    }

    public void onFileReBuildingAction(ActionEvent event) {

        CustomerService customerService = getCompanyCustomerService();
        try {
            CustomerVo companyCustomer = customerService.findById(viewModel.getId().get());
            if (customerService.reBuildingFiles(companyCustomer, (level, message) -> setStatus(message))) {
                loadTableDataSet();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected boolean deleteRow(CustomerFileViewModel row) {
        String path = row.getFilePath().get();
        if (super.deleteRow(row)) {
            File file = new File(path);
            if (file.exists()) {
                UITools.showConfirmation("数据记录已经删除，请确认是否删除物理文件", path)
                        .thenAccept(buttonType -> {
                            if (buttonType == ButtonType.OK) {
                                if (file.delete()) {
                                    setStatus("删除文件 " + path);
                                }
                            }
                        });
            }
            return true;
        }
        return false;
    }

    public void onFileTableMoveToCompanyPathAction(ActionEvent event) {
        CustomerFileViewModel selectedItem = getSelectedItem();
        if (selectedItem == null) {
            return;
        }

        // 检查公司目录设置
        Integer companyId = viewModel.getCompany().get();
        CompanyVo company = getCompanyService().findById(companyId);

        if (!StringUtils.hasText(company.getPath())) {
            setStatus("公司目录未设置");
            return;
        }

        File companyPath = new File(company.getPath());
        if (!companyPath.exists()) {
            setStatus("公司目录设置异常，无法访问");
            return;
        }

        // 创建并启动任务
        CustomerFileMoveTasker task = new CustomerFileMoveTasker();
        task.setFileId(selectedItem.getId().get());
        UITools.showTaskDialogAndWait("移动文件到公司目录", task, null);

        // 刷新表格数据
        loadTableDataSet();
    }

    public void onUpdateEvaluationFormAction(ActionEvent event) {
        CustomerEvaluationFormUpdateTask task = new CustomerEvaluationFormUpdateTask();
        task.setCustomer(getCompanyCustomerService().findById(viewModel.getId().get()));
        UITools.showTaskDialogAndWait("更新评价表", task, null);
        loadTableDataSet();
    }

    public void onCalcNextSignDateAction(ActionEvent event) {
        CustomerNextSignDateTask task = new CustomerNextSignDateTask();
        task.setCustomer(getEntity());
        UITools.showTaskDialogAndWait("计算客户的下一个评价日期", task, null);
    }

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

}
