package com.ecep.contract.controller.tab;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.function.Consumer;

import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils;

import com.ecep.contract.CompanyFileType;
import com.ecep.contract.DesktopUtils;
import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.constant.CloudServiceConstant;
import com.ecep.contract.controller.company.AbstCompanyTableTabSkin;
import com.ecep.contract.controller.company.CompanyWindowController;
import com.ecep.contract.controller.table.EditableEntityTableTabSkin;
import com.ecep.contract.controller.table.cell.CompanyFileTypeTableCell;
import com.ecep.contract.controller.table.cell.FilePathTableCell;
import com.ecep.contract.service.CloudTycService;
import com.ecep.contract.service.CompanyFileService;
import com.ecep.contract.service.CompanyFileTypeService;
import com.ecep.contract.task.CompanyFileMoveTasker;
import com.ecep.contract.task.CompanyFileResetTasker;
import com.ecep.contract.task.CompanyFileRetrieveFromDownloadDirTasker;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.CompanyFileViewModel;
import com.ecep.contract.vo.CompanyFileVo;
import com.ecep.contract.vo.CompanyVo;

import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.Event;
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;

/**
 *
 */
@FxmlPath("/ui/company/company-tab-file.fxml")
public class CompanyTabSkinFile
        extends AbstCompanyTableTabSkin<CompanyFileVo, CompanyFileViewModel>
        implements TabSkin, EditableEntityTableTabSkin<CompanyFileVo, CompanyFileViewModel> {

    public TableColumn<CompanyFileViewModel, Number> idColumn;
    public TableColumn<CompanyFileViewModel, CompanyFileType> typeColumn;
    public TableColumn<CompanyFileViewModel, String> filePathColumn;
    public TableColumn<CompanyFileViewModel, LocalDate> applyDateColumn;
    public TableColumn<CompanyFileViewModel, LocalDate> expiringDateColumn;

    public Button fileTable_file_move_btn;
    public Button fileTable_file_retrieve_from_download_dir_btn;
    public Button fileTable_file_reset_btn;
    public MenuItem fileTable_menu_refresh;
    public MenuItem fileTable_menu_del;
    public MenuItem fileTable_menu_copy_as_matched_by_contract;

    public CompanyTabSkinFile(CompanyWindowController controller) {
        super(controller);
        setDragAndDrop(true);
        setDragAndDropFileHandler(this::moveFileToCompany);
    }

    protected CompanyFileService getViewModelService() {
        return getCompanyFileService();
    }

    CompanyFileService getCompanyFileService() {
        return getBean(CompanyFileService.class);
    }

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

    @Override
    public void initializeTable() {
        super.initializeTable();
        fileTable_file_move_btn.setOnAction(this::onTableMoveFileAction);
        fileTable_file_retrieve_from_download_dir_btn.setOnAction(this::onTableRetrieveFromDownloadDirAction);
        fileTable_file_reset_btn.setOnAction(this::onTableResetAction);

        idColumn.setCellValueFactory(param -> param.getValue().getId());

        typeColumn.setCellValueFactory(param -> param.getValue().getType());
        typeColumn.setCellFactory(CompanyFileTypeTableCell.forTableColumn(getCachedBean(CompanyFileTypeService.class)));

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

        applyDateColumn.setCellValueFactory(param -> param.getValue().getApplyDate());
        expiringDateColumn.setCellValueFactory(param -> param.getValue().getExpiringDate());

        fileTable_menu_refresh.setOnAction(this::onTableRefreshAction);
        fileTable_menu_del.setOnAction(this::onTableDeleteAction);
        fileTable_menu_copy_as_matched_by_contract.setOnAction(this::onTableCopyAsMatchedByContractAction);
        fileTable_menu_copy_as_matched_by_contract.setOnMenuValidation(this::onTableCopyAsMatchedMenuValidation);
    }

    private void onTableResetAction(ActionEvent event) {
        // 创建本地任务
        CompanyFileResetTasker tasker = new CompanyFileResetTasker();
        tasker.setCompany(getParent());
        UITools.showTaskDialogAndWait("重置公司文件", tasker, null);
        if (tasker.isFilesUpdated()) {
            loadTableDataSet();
        }
    }

    /**
     * 从 下载目录 中查找相关的资质文件
     */
    private void onTableRetrieveFromDownloadDirAction(ActionEvent event) {
        // 创建本地任务
        CompanyFileRetrieveFromDownloadDirTasker tasker = new CompanyFileRetrieveFromDownloadDirTasker();
        tasker.setCompany(getEntity());
        UITools.showTaskDialogAndWait("从下载目录检索文件", tasker, null);
        loadTableDataSet();
    }

    /**
     * 把文件从 老系统中移到 \\10.84.209.8\项目信息\相关方信息 目录中
     */
    private void onTableMoveFileAction(ActionEvent event) {
        // 创建本地任务
        CompanyFileMoveTasker tasker = new CompanyFileMoveTasker();
        tasker.setCompany(getParent());
        UITools.showTaskDialogAndWait("移动公司文件", tasker, null);
        if (tasker.isFilesMoved()) {
            loadTableDataSet();
        }
    }

    /**
     *
     */
    private void onTableCopyAsMatchedByContractAction(ActionEvent event) {
        UITools.showDialogAndWait("复制资信评估报告", "按当前评估报告复制一个合同中最匹配的", list -> {
            getViewModelService().copyAsMatchedByContract(getParent(), list);
            onTableCopyAsMatchedAction_(msg -> {
                Platform.runLater(() -> {
                    list.add(msg);
                });
            });
        });
    }

    private void onTableCopyAsMatchedAction_(Consumer<String> state) {
        CompanyVo company = getParent();

        CompanyFileViewModel selectedItem = getSelectedItem();
        if (selectedItem == null) {
            state.accept("未选择行");
            return;
        }
        if (selectedItem.getApplyDate().get() == null) {
            state.accept("有效日期不能未空");
            return;
        }

        LocalDate nextCreditReportDate = null;
        try {
            nextCreditReportDate = getViewModelService().getNextCreditReportDate(company, state);
            if (nextCreditReportDate == null) {
                state.accept("没有找到下一个咨询评估日期");
                return;
            }
        } catch (Exception e) {
            state.accept("获取下一个咨询评估日期失败:" + e.getMessage());
            return;
        }

        state.accept("下一个咨询评估日期：" + nextCreditReportDate);

        if (!nextCreditReportDate.isBefore(selectedItem.getApplyDate().get())) {
            state.accept("咨询评估日期晚于下一个咨询评估日期");
            return;
        }

        File src = new File(selectedItem.getFilePath().get());
        if (!src.exists()) {
            state.accept("当前选择行的文件不存在");
            return;
        }

        String srcDate = MyDateTimeUtils.format(selectedItem.getApplyDate().get());
        String destDate = MyDateTimeUtils.format(nextCreditReportDate);
        String srcFileName = src.getName();
        String destFileName;

        // 天眼查的报告
        if (CloudTycService.isTycReport(srcFileName)) {
            state.accept("天眼查的报告按标准格式命名");
            String name = company.getName() + "_" + CloudServiceConstant.TYC_NAME;
            if (srcFileName.contains(CloudServiceConstant.TYC_ENTERPRISE_BASIC_REPORT)) {
                name = name + "_" + CloudServiceConstant.TYC_ENTERPRISE_BASIC_REPORT;
            } else if (srcFileName.contains(CloudServiceConstant.TYC_ENTERPRISE_MAJOR_REPORT)) {
                name = name + "_" + CloudServiceConstant.TYC_ENTERPRISE_MAJOR_REPORT;
            } else if (srcFileName.contains(CloudServiceConstant.TYC_ENTERPRISE_ANALYSIS_REPORT)) {
                name = name + "_" + CloudServiceConstant.TYC_ENTERPRISE_ANALYSIS_REPORT;
            }
            destFileName = name + "_" + destDate + "_cp." + StringUtils.getFilenameExtension(srcFileName);
        } else {
            if (srcFileName.contains(srcDate)) {
                // 如果文件名中包含日期，则替换为新日期
                destFileName = srcFileName.replace(srcDate, destDate + "_cp");
            } else {
                // 如果文件名中不包含日期，则添加日期
                destFileName = company.getName() + "_" + destDate + "_cp."
                        + StringUtils.getFilenameExtension(srcFileName);
            }
        }

        state.accept("新文件名：" + destFileName);

        File dest = new File(src.getParent(), destFileName);
        try {
            FileSystemUtils.copyRecursively(src, dest);
            state.accept("新文件复制成功");
        } catch (IOException e) {
            state.accept("新文件复制失败：" + e.getMessage());
        }

        CompanyFileVo companyFile = new CompanyFileVo();
        companyFile.setFilePath(dest.getAbsolutePath());
        companyFile.setApplyDate(nextCreditReportDate);
        companyFile.setExpiringDate(nextCreditReportDate.plusYears(1));
        companyFile.setType(CompanyFileType.CreditReport);
        companyFile.setCompanyId(company.getId());
        saveRowData(companyFile);

        state.accept("新文件已记录");

        loadTableDataSet();
        state.accept("文件表已刷新");
    }

    /**
     * 当fileTable选中的行是咨询评估时，可用
     *
     * @param event event
     */
    public void onTableCopyAsMatchedMenuValidation(Event event) {
        // 当fileTable选中的行是咨询评估时，可用
        CompanyFileViewModel selectedItem = getSelectedItem();
        if (selectedItem == null) {
            event.consume();
            return;
        }
        CompanyFileType type = selectedItem.getType().get();
        if (type != CompanyFileType.CreditReport) {
            event.consume();
            return;
        }
    }

    @Override
    protected boolean deleteRow(CompanyFileViewModel 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;
    }

    private void moveFileToCompany(List<File> files) {
        String path = viewModel.getPath().get();
        if (!StringUtils.hasText(path)) {
            setStatus("未设置目录");
            return;
        }
        File dir = new File(path);
        if (!dir.exists()) {
            setStatus("目录错误,不存在");
            return;
        }
    }

    @Override
    protected void onTableRowDoubleClickedAction(CompanyFileViewModel item) {
        String path = item.getFilePath().get();
        if (StringUtils.hasText(path)) {
            File file = new File(path);
            if (!file.exists()) {
                setStatus("文件不存在 " + file.getName());
                return;
            }
            DesktopUtils.showInExplorer(file);
        }
    }
}
