package com.ecep.contract.service;

import java.io.File;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.ecep.contract.MessageHolder;
import com.ecep.contract.SpringApp;
import com.ecep.contract.constant.CompanyCustomerConstant;
import com.ecep.contract.controller.customer.tasker.CustomerRebuildFilesTasker;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.CompanyCustomerViewModel;
import com.ecep.contract.vo.CompanyVo;
import com.ecep.contract.vo.CustomerVo;

@Service
public class CustomerService extends QueryService<CustomerVo, CompanyCustomerViewModel> {
    private File basePath;

    public File getBasePath() {
        if (basePath == null) {
            basePath = new File(
                    SpringApp.getBean(SysConfService.class).getString(CompanyCustomerConstant.KEY_BASE_PATH));
        }
        return basePath;
    }

    public CustomerVo findByCompany(CompanyVo company) {
        Page<CustomerVo> page = findAll(ParamUtils.equal("company", company.getId()), Pageable.ofSize(1));
        if (page.isEmpty()) {
            return null;
        }
        return page.getContent().getFirst();
    }

    /**
     * 重建客户相关文件
     *
     * @param companyCustomer 客户对象
     * @param holder          消息持有者，用于显示任务执行过程中的消息
     * @return 如果文件重建成功则返回true，否则返回false
     */
    public boolean reBuildingFiles(CustomerVo companyCustomer, MessageHolder holder) {
        // 首先确保客户有有效的路径
        if (!makePathAbsent(companyCustomer)) {
            holder.warn("无法创建或确认客户路径，文件重建可能失败");
        }

        // 创建并配置文件重建任务
        CustomerRebuildFilesTasker tasker = new CustomerRebuildFilesTasker();
        tasker.setCompanyCustomer(companyCustomer);

        // 显示任务对话框并等待任务完成
        UITools.showTaskDialogAndWait("重建客户文件", tasker, null);

        // 返回任务执行结果
        return tasker.isFilesUpdated();
    }

    /**
     * 检查客户路径是否不存在，如果不存在则创建并设置路径
     *
     * @param companyCustomer 客户对象
     * @return 如果成功创建路径并设置则返回true，否则返回false
     */
    public boolean makePathAbsent(CustomerVo companyCustomer) {
        String path = companyCustomer.getPath();
        if (StringUtils.hasText(path)) {
            File file = new File(path);
            if (file.exists()) {
                return false;
            }
        }

        File dir = makePath(companyCustomer);
        if (dir == null) {
            return false;
        }
        if (!dir.exists()) {
            return false;
        }
        companyCustomer.setPath(dir.getAbsolutePath());
        return true;
    }

    /**
     * 为客户创建路径
     *
     * @param companyCustomer 客户对象
     * @return 创建的目录对象，如果创建失败则返回null
     */
    private File makePath(CustomerVo companyCustomer) {
        File basePath = getBasePath();
        Integer companyId = companyCustomer.getCompanyId();
        CompanyVo company = SpringApp.getBean(CompanyService.class).findById(companyId);
        // 在client端，company对象通常已经是完整加载的，不需要额外查询
        String companyName = company.getName();
        // 格式化公司客户ID并创建文件名
        String fileName = formatCompanyCustomerId(companyCustomer.getId()) + "-" + escapeFileName(companyName);

        File dir = new File(basePath, fileName);
        if (!dir.exists()) {
            if (!dir.mkdir()) {
                return null;
            }
        }
        return dir;
    }

    /**
     * 格式化公司客户ID，确保格式一致
     *
     * @param id 客户ID
     * @return 格式化后的ID字符串
     */
    private String formatCompanyCustomerId(Integer id) {
        if (id != null) {
            if (id > 99) {
                return String.valueOf(id);
            } else if (id > 9) {
                return "0" + id;
            } else if (id > 0) {
                return "00" + id;
            }
        }
        throw new IllegalArgumentException("客户ID必须为正数");
    }

    /**
     * 转义文件名，确保合法
     *
     * @param fileName 原始文件名
     * @return 转义后的文件名
     */
    private String escapeFileName(String fileName) {
        // 替换文件名中的非法字符
        return fileName.replaceAll("[/\\:*?\"<>|]", "_");
    }
}
