package com.zksy.property.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zksy.property.domain.ARentalContract;
import com.zksy.property.domain.bo.RentalTempBo;
import com.zksy.property.mapper.ARentalContractMapper;
import com.zksy.property.service.ARentalContentService;
import com.zksy.property.service.ARentalContractService;
import com.zksy.service.MinioFileStorageService;
import com.zksy.utils.WordUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* @author Administrator
* @description 针对表【a_rental_contract(租赁合同管理表)】的数据库操作Service实现
* @createDate 2025-07-01 08:57:36
*/
@Service
public class ARentalContractServiceImpl extends ServiceImpl<ARentalContractMapper, ARentalContract>
    implements ARentalContractService{

    @Autowired
    private ARentalContentService aRentalContentService;

    @Autowired
    private MinioFileStorageService minioFileStorageService;

    @Override
    public Page<ARentalContract> findByPage(long pageNum, long pageSize, String tenantName, String contractNumber, String contractStatus) {
        Page<ARentalContract> page = new Page<>(pageNum,pageSize);
        LambdaQueryWrapper<ARentalContract> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.like(tenantName != null,ARentalContract::getTenantName,tenantName);
        queryWrapper.like(contractNumber != null,ARentalContract::getContractNumber,contractNumber);
        queryWrapper.like(contractStatus != null,ARentalContract::getContractStatus,contractStatus);
        Page<ARentalContract> page1 = this.page(page, queryWrapper);
        return page1;
    }

    @Override
    public List<ARentalContract> getARentalContractList(String tenantName, String contractNumber, String contractStatus) {
        LambdaQueryWrapper<ARentalContract> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.like(tenantName != null,ARentalContract::getTenantName,tenantName);
        queryWrapper.like(contractNumber != null,ARentalContract::getContractNumber,contractNumber);
        queryWrapper.like(contractStatus != null,ARentalContract::getContractStatus,contractStatus);
        List<ARentalContract> list = this.list(queryWrapper);
        return list;
    }

    @Override
    public String generatorRental(String mark, RentalTempBo bo,boolean isPrintPdf) {
        // 定义标记与字段数量的映射关系
        Map<String, Integer> markToFieldCount = new HashMap<>();
        markToFieldCount.put("1", 9);
        markToFieldCount.put("2", 56);
        markToFieldCount.put("3", 27);
        markToFieldCount.put("4", 13);
        markToFieldCount.put("5", 8);

        // 验证标记类型
        if (!markToFieldCount.containsKey(mark)) {
            throw new IllegalArgumentException("不支持的 mark 类型：" + mark);
        }

        int fieldCount = markToFieldCount.get(mark);

        // 根据标记确定前缀
        String prefix;
        switch (mark) {
            case "1":
                prefix = "a";
                break;
            case "2":
                prefix = "b";
                break;
            case "3":
                prefix = "c";
                break;
            case "4":
                prefix = "d";
                break;
            case "5":
                prefix = "e";
                break;
            default:
                throw new IllegalStateException("非法 mark 值：" + mark);
        }

        String templatePath = "templates/" + mark + ".docx";

        try (InputStream inputStream = new ClassPathResource(templatePath).getInputStream()) {
            // 构建内容映射
            Map<String, String> contentMap = buildContentMap(bo, prefix, fieldCount);

            // 创建临时文件
            File tempFile = File.createTempFile("rental_contract_", ".docx");
            tempFile.deleteOnExit(); // JVM退出时自动删除

            // 处理文档并写入临时文件
            try (XWPFDocument document = new XWPFDocument(inputStream);
                 FileOutputStream outputStream = new FileOutputStream(tempFile)) {

                replacePlaceholders(document, contentMap);
                document.write(outputStream);
            }
            if(isPrintPdf){
                File file = WordUtils.wordToPdf(tempFile);
                return minioFileStorageService.uploadFileByFile(file,getFileTypeDescription(mark));
            }
            return minioFileStorageService.uploadFileByFile(tempFile,getFileTypeDescription(mark));
        } catch (Exception e) {
            throw new RuntimeException("处理文档时发生错误", e);
        }
    }

    @Override
    public String generatorRental(String mark, RentalTempBo bo) {
        return generatorRental(mark, bo,false);
    }

    private String getFileTypeDescription(String mark) {
        switch (mark) {
            case "1":
            case "2":
            case "3":
                return "合同";
            case "4":
                return "收据";
            case "5":
                return "退据";
            default:
                throw new IllegalArgumentException("不支持的标记类型: " + mark);
        }
    }

    private Map<String, String> buildContentMap(RentalTempBo bo, String prefix, int count) {
        Map<String, String> contentMap = new HashMap<>();
        for (int i = 1; i <= count; i++) {
            String methodName = "get" + prefix.toUpperCase() + i;
            try {
                Method method = bo.getClass().getMethod(methodName);
                String value = (String) method.invoke(bo);
                contentMap.put(prefix + i, value != null ? value : "  ");
            } catch (Exception e) {
                e.printStackTrace(); // 可替换为日志记录
                contentMap.put(prefix + i, "  ");
            }
        }
        return contentMap;
    }

    private void replacePlaceholders(XWPFDocument document, Map<String, String> contentMap) {
        for (XWPFParagraph paragraph : document.getParagraphs()) {
            for (XWPFRun run : paragraph.getRuns()) {
                if (run == null || run.getText(0) == null) continue;
                String text = run.getText(0);

                Matcher matcher = Pattern.compile("\\$\\{(.+?)\\}").matcher(text);
                boolean found = false;

                while (matcher.find()) {
                    found = true;
                    String key = matcher.group(1);
                    String replacement = contentMap.getOrDefault(key, "未知字段");
                    if(replacement == null) {
                        replacement = "   ";
                    }
                    text = text.replace("${" + key + "}", replacement);
                }

                if (found) {
                    run.setText(text, 0);
                }
            }
        }
    }

}




