package com.fs.his.service.impl;


import com.fs.his.domain.FsPrescribeDrug;
import com.fs.his.param.PrescribeXyImgParam;
import com.fs.his.service.PrescriptionImageService;
import com.fs.system.oss.CloudStorageService;
import com.fs.system.oss.OSSFactory;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 处方图片生成服务
 */
@Slf4j
@Service
public class PrescriptionImageServiceImpl implements PrescriptionImageService {


    /**
     * 模板图片路径
     */
    private static final String TEMPLATE_PATH = "C:\\fs\\ysy_prescribe.jpg";
    //官方印章
    private static final String TEMPLATE_PATH_OFFICIAL = "C:\\fs\\ysy_official.png";
    //已使用印章
    private static final String TEMPLATE_PATH_USED = "C:\\fs\\ysy_used.png";

    /**
     * 模板图片缓存key
     */
    private static final String TEMPLATE_CACHE_KEY = "prescription_template";

    private static final String OFFICIAL_SEAL_CACHE_KEY = "official_seal";

    private static final String USED_SEAL_CACHE_KEY = "used_seal";

    /**
     * 图片缓存(模板永久,签名24小时)
     */
    private final Cache<String, BufferedImage> imageCache = Caffeine.newBuilder()
            .maximumSize(1000)
            .expireAfterWrite(24, TimeUnit.HOURS)
            .build();

    @PostConstruct
    public void init() {
        try {
            getTemplateImage();
            getOfficialSealImage();
            getUsedSealImage();
            log.info("处方模板图片预加载成功");
        } catch (Exception e) {
            log.error("处方模板图片预加载失败", e);
        }
    }

    @Override
    public String generatePrescriptionImage(PrescribeXyImgParam param) {
        try {
            BufferedImage template = getTemplateImage();

            BufferedImage workImage = deepCopy(template);

            Graphics2D pen = workImage.createGraphics();

            // 设置字体和渲染质量
            setupGraphics(pen);

            // 绘制处方编号和时间
            drawHeaderInfo(pen, param);

            // 绘制患者信息
            drawPatientInfo(pen, param);

            // 绘制诊断
            drawDiagnosis(pen, param);

            // 绘制医生证号和医生职称
            drawDoctorNoAndDoctorTitle(pen,param);

            // 绘制药品列表
            int lastY = drawDrugList(pen, param.getPrescribeDrug());

            // 绘制医嘱
            drawAdvice(pen, param, lastY);

            // 叠加官方印章
            overlayOfficialSeal(pen, param);

            // 叠加已使用使用印章
            overlayUsedSeal(pen, param);

            // 叠加签名图片
            overlaySignatures(pen, param);

            // 释放资源
            pen.dispose();

            String url = uploadToOSS(workImage);

            log.info("处方图片生成成功, URL: {}", url);
            return url;

        } catch (Exception e) {
            log.error("生成处方图片失败", e);
            throw new RuntimeException("生成处方图片失败: " + e.getMessage());
        }
    }

    /**
     * 获取模板图片(带缓存)
     */
    public BufferedImage getTemplateImage() {
        return imageCache.get(TEMPLATE_CACHE_KEY, key -> {
            try {
                File templateFile = new File(TEMPLATE_PATH);
                if (!templateFile.exists()) {
                    throw new RuntimeException("模板图片不存在: " + TEMPLATE_PATH);
                }
                BufferedImage image = ImageIO.read(templateFile);
                log.info("模板图片加载成功, 尺寸: {}x{}", image.getWidth(), image.getHeight());
                return image;
            } catch (Exception e) {
                log.error("加载模板图片失败", e);
                throw new RuntimeException("加载模板图片失败", e);
            }
        });
    }

    // 官方印章加载方法
    public BufferedImage getOfficialSealImage() {
        return imageCache.get(OFFICIAL_SEAL_CACHE_KEY, key -> {
            try {
                File file = new File(TEMPLATE_PATH_OFFICIAL);
                if (!file.exists()) {
                    throw new RuntimeException("官方印章图片不存在: " + TEMPLATE_PATH_OFFICIAL);
                }
                BufferedImage image = ImageIO.read(file);
                log.info("官方印章图片加载成功, 尺寸: {}x{}", image.getWidth(), image.getHeight());
                return image;
            } catch (Exception e) {
                log.error("加载官方印章图片失败", e);
                throw new RuntimeException("加载官方印章图片失败", e);
            }
        });
    }

    // 已使用印章加载方法
    public BufferedImage getUsedSealImage() {
        return imageCache.get(USED_SEAL_CACHE_KEY, key -> {
            try {
                File file = new File(TEMPLATE_PATH_USED);
                if (!file.exists()) {
                    throw new RuntimeException("已使用印章图片不存在: " + TEMPLATE_PATH_USED);
                }
                BufferedImage image = ImageIO.read(file);
                log.info("已使用印章图片加载成功, 尺寸: {}x{}", image.getWidth(), image.getHeight());
                return image;
            } catch (Exception e) {
                log.error("加载已使用印章图片失败", e);
                throw new RuntimeException("加载已使用印章图片失败", e);
            }
        });
    }


    /**
     * 深拷贝图片
     */
    private BufferedImage deepCopy(BufferedImage source) {
        BufferedImage copy = new BufferedImage(
                source.getWidth(),
                source.getHeight(),
                source.getType()
        );
        Graphics2D g = copy.createGraphics();
        g.drawImage(source, 0, 0, null);
        g.dispose();
        return copy;
    }

    /**
     * 设置Graphics2D渲染参数
     */
    private void setupGraphics(Graphics2D pen) {
        pen.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        pen.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        pen.setRenderingHint(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);

        pen.setFont(new Font("黑体", Font.PLAIN, 40));
        pen.setColor(Color.BLACK);
    }

    /**
     * 绘制处方编号和时间
     */
    private void drawHeaderInfo(Graphics2D pen, PrescribeXyImgParam param) {
        // 处方编号
        if (StringUtils.isNotBlank(param.getPrescribeId())) {
            pen.drawString(param.getPrescribeId(), 282, 215);
        }

        // 时间
        if (param.getTime() != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String timeStr = sdf.format(param.getTime());
            pen.drawString(timeStr, 1228, 215);
        }
    }

    /**
     * 绘制患者信息
     */
    private void drawPatientInfo(Graphics2D pen, PrescribeXyImgParam param) {
        int y = 320;

        // 姓名
        if (StringUtils.isNotBlank(param.getPatientName())) {
            pen.drawString(param.getPatientName(), 217, y);
        }

        // 性别
        if (StringUtils.isNotBlank(param.getPatientGender())) {
            String gender = "1".equals(param.getPatientGender()) ? "男" : "女";
            pen.drawString(gender, 658, y);
        }

        // 年龄
        if (StringUtils.isNotBlank(param.getPatientAge())) {
            pen.drawString(param.getPatientAge(), 979, y);
        }

        // 电话
        if (StringUtils.isNotBlank(param.getTelPhone())) {
            pen.drawString(param.getTelPhone(), 1290, y);
        }
    }

    /**
     * 绘制诊断信息
     */
    private void drawDiagnosis(Graphics2D pen, PrescribeXyImgParam param) {
        if (StringUtils.isNotBlank(param.getDiagnose())) {
            int x = 233;
            int y = 550;
            int maxWidth = 1350;
            drawMultiLineText(pen, param.getDiagnose(), x, y, maxWidth);
        }
    }


    /**
     * 绘制医生证号和职称
     * @param pen
     * @param param
     */
    private void drawDoctorNoAndDoctorTitle(Graphics2D pen, PrescribeXyImgParam param) {
        int x = 890;
        int y = 1892;
        int maxWidth = 760;
        int titleX = 690;
        // 优先绘制执业证号，没有就绘制医生证号
        if (StringUtils.isNotBlank(param.getJobLicenseNumber())) {
            //绘制标题
            drawMultiLineText(pen, "执业证号", titleX, y, maxWidth);
            //绘制证内容
            drawMultiLineText(pen, param.getJobLicenseNumber(), x, y, maxWidth);
        } else {
            //绘制标题
            drawMultiLineText(pen, "医生证号", titleX, y, maxWidth);
            //绘制内容
            drawMultiLineText(pen, param.getDoctorNo(), x, y, maxWidth);
        }

        if (StringUtils.isNotBlank(param.getDoctorTitle())) {
            int x2 = 302;
            int y2 = 2078;
            int maxWidth2 = 760;
            drawMultiLineText(pen, param.getDoctorTitle(), x2, y2, maxWidth2);
        }
    }

    /**
     * 绘制药品列表（每药两行：第一行药名规格数量，第二行用法用量）
     * @return 返回最后一行的Y坐标
     */
    public int drawDrugList(Graphics2D pen, List<FsPrescribeDrug> drugs) {
        if (drugs == null || drugs.isEmpty()) {
            return 330;
        }
        // ====== 关键：预处理药品列表（清洗 + 合并） ======
        List<FsPrescribeDrug> processedDrugs = preprocessDrugsForPrescription(drugs);
        if (processedDrugs.isEmpty()) {
            return 330;
        }
        // ====== 绘制逻辑 ======
        int x = 105;
        int y = 720;
        int innerLineSpacing = 40;
        int blankLine = 40;

        for (FsPrescribeDrug drug : processedDrugs) {
            // ========== 第一行：药名 + 规格 + 数量 ==========
            StringBuilder line1 = new StringBuilder();
            if (StringUtils.isNotBlank(drug.getDrugName())) {
                line1.append(drug.getDrugName());
            }
            if (StringUtils.isNotBlank(drug.getDrugSpec())) {
                line1.append(" ").append(drug.getDrugSpec());
            }
            if (drug.getDrugNum() != null) {
                line1.append("x").append(drug.getDrugNum());
                if (StringUtils.isNotBlank(drug.getDrugUnit())) {
                    line1.append(drug.getDrugUnit()).append("。");
                }
            }

            String firstLine = line1.toString().trim();
            if (StringUtils.isNotBlank(firstLine)) {
                y = drawDrugTextLine(pen, firstLine, x, y, 1100, innerLineSpacing);
            }
            y += innerLineSpacing;

            // ========== 第二行：用法用量 ==========
            StringBuilder line2 = new StringBuilder();
            if (StringUtils.isNotBlank(drug.getUsageMethod())) {
                line2.append("用法用量:").append(drug.getUsageMethod());
            }
            if (StringUtils.isNotBlank(drug.getUsagePerUseCount())) {
                line2.append(",").append(drug.getUsagePerUseCount());
                if (StringUtils.isNotBlank(drug.getUsagePerUseUnit())) {
                    line2.append(drug.getUsagePerUseUnit());
                }
            }
            if (StringUtils.isNotBlank(drug.getUsageFrequencyUnit())) {
                line2.append(",").append(drug.getUsageFrequencyUnit()).append("。");
            }

            String secondLine = line2.toString().trim();
            if (StringUtils.isNotBlank(secondLine)) {
                y = drawDrugTextLine(pen, secondLine, x, y, 1000, innerLineSpacing);
            }
            y += innerLineSpacing;

            // 每个药品之后（包括最后一个）加一个空白行
            y += blankLine;
        }

        return y;
    }

    /**
     * 预处理处方药品列表（满足三个需求）：
     * 1. 药名中“赠品”二字被移除；
     * 2. 按（药名+规格）合并重复项，数量累加。
     */
    private List<FsPrescribeDrug> preprocessDrugsForPrescription(List<FsPrescribeDrug> originalDrugs) {
        if (originalDrugs == null || originalDrugs.isEmpty()) {
            return new ArrayList<>();
        }


        // key: cleanedName + "|" + baseSpec（不含×N部分）
        Map<String, FsPrescribeDrug> drugMap = new LinkedHashMap<>();

        for (FsPrescribeDrug drug : originalDrugs) {
            if (drug == null) continue;

            String rawName = StringUtils.defaultString(drug.getDrugName()).trim();
            String cleanedName = rawName.replace("赠品", "").trim();
            if (cleanedName.isEmpty()) continue;

            String spec = StringUtils.defaultString(drug.getDrugSpec()).trim();

            // 解析规格：分离基础规格和盒数
            SpecParseResult parsed = parseSpec(spec);
            String baseSpec = parsed.baseSpec;
            long specBoxCount = parsed.boxCount;

            // 获取 drugNum 字段的值（可能为 null）
            Long drugNumObj = drug.getDrugNum();
            long drugNum = (drugNumObj != null) ? drugNumObj : 0L;

            long totalBoxes;
            if (drugNum > 0) {
                totalBoxes = drugNum;
            } else {
                totalBoxes = specBoxCount;
            }

            String key = cleanedName + "|" + baseSpec;

            if (drugMap.containsKey(key)) {
                FsPrescribeDrug existing = drugMap.get(key);
                existing.setDrugNum(existing.getDrugNum() + totalBoxes);
            } else {
                FsPrescribeDrug newDrug = new FsPrescribeDrug();
                newDrug.setDrugName(cleanedName);
                newDrug.setDrugSpec(baseSpec);
                newDrug.setDrugNum(totalBoxes);
                newDrug.setDrugUnit(drug.getDrugUnit());
                newDrug.setUsageMethod(drug.getUsageMethod());
                newDrug.setUsagePerUseCount(drug.getUsagePerUseCount());
                newDrug.setUsagePerUseUnit(drug.getUsagePerUseUnit());
                newDrug.setUsageFrequencyUnit(drug.getUsageFrequencyUnit());
                drugMap.put(key, newDrug);
            }
        }
        return new ArrayList<>(drugMap.values());
    }

    /**
     * 从规格字符串中提取基础规格和盒数。
     * 例如："0.35g*24粒/盒×2" -> baseSpec="0.35g*24粒/盒", boxCount=2
     * 如果没有 ×N，则 boxCount=1
     */
    private static class SpecParseResult {
        String baseSpec;
        long boxCount;

        SpecParseResult(String baseSpec, long boxCount) {
            this.baseSpec = baseSpec;
            this.boxCount = boxCount;
        }
    }

    private SpecParseResult parseSpec(String spec) {
        if (spec == null || spec.isEmpty()) {
            return new SpecParseResult(spec, 1L);
        }

        // 匹配末尾的 "×数字" 或 "*数字"或 "x数字"或 "X数字"（兼容不同写法）
        // 例如：×2、×10、*3、× 2（带空格）
        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("([×＊*xXｘＸ]\\s*\\d+)$");
        java.util.regex.Matcher matcher = pattern.matcher(spec);

        if (matcher.find()) {
            String countPart = matcher.group(1);
            String base = spec.substring(0, matcher.start()).trim();
            String numStr = countPart.replaceAll("[×＊*xXｘＸ\\s]", "").trim();
            long count = 1L;
            try {
                count = Long.parseLong(numStr);
            } catch (NumberFormatException ignored) {
                count = 1L;
            }
            return new SpecParseResult(base.isEmpty() ? spec : base, count);
        } else {
            // 没有 ×N，默认 1 盒
            return new SpecParseResult(spec, 1L);
        }
    }

    /**
     * 专用于药品列表的文本绘制：支持自动换行，返回最后一行文本的基线 Y 坐标
     * 不额外增加行高，由调用方控制换行（如 y += innerLineSpacing）
     */
    private int drawDrugTextLine(Graphics2D pen, String text, int x, int y, int maxWidth, int lineHeight) {
        if (StringUtils.isBlank(text)) {
            return y;
        }

        FontMetrics fm = pen.getFontMetrics();
        StringBuilder currentLine = new StringBuilder();
        int currentY = y;

        for (char c : text.toCharArray()) {
            String testLine = currentLine.toString() + c;
            int testWidth = fm.stringWidth(testLine);

            // 如果加上当前字符会超宽，且当前行已有内容，则换行
            if (testWidth > maxWidth && currentLine.length() > 0) {
                pen.drawString(currentLine.toString(), x, currentY);
                currentY += lineHeight; // 使用固定 lineHeight 换行
                currentLine = new StringBuilder().append(c);
            } else {
                currentLine.append(c);
            }
        }

        // 绘制最后一行（不额外增加 lineHeight）
        if (currentLine.length() > 0) {
            pen.drawString(currentLine.toString(), x, currentY);
        }

        return currentY;
    }


    /**
     * 绘制医嘱
     */
    private void drawAdvice(Graphics2D pen, PrescribeXyImgParam param, int startY) {
        int y = 1400;

        if (StringUtils.isNotBlank(param.getRemark())) {
            drawMultiLineText(pen, param.getRemark(), 133, y, 1450);
        }
    }



    /**
     * 叠加签名图片
     */
    private void overlaySignatures(Graphics2D pen, PrescribeXyImgParam param) {
        // 医师签名
        if (StringUtils.isNotBlank(param.getUrl())) {
            try {
                BufferedImage doctorSign = downloadSignatureImage(param.getUrl());
                if (doctorSign != null) {
                    Image scaledSign = doctorSign.getScaledInstance(120, 80, Image.SCALE_SMOOTH);
                    pen.drawImage(scaledSign, 302, 1842, null);
                }
            } catch (Exception e) {
                log.error("加载医师签名失败: {}", param.getUrl(), e);
            }
        }

        // 药师签名
        if (StringUtils.isNotBlank(param.getDrugDoctorUrl())) {
            try {
                BufferedImage pharmacistSign = downloadSignatureImage(param.getDrugDoctorUrl());
                if (pharmacistSign != null) {
                    Image scaledSign = pharmacistSign.getScaledInstance(120, 80, Image.SCALE_SMOOTH);
                    pen.drawImage(scaledSign, 1400, 2028, null);
                }
            } catch (Exception e) {
                log.error("加载药师签名失败: {}", param.getDrugDoctorUrl(), e);
            }
        }
    }

    /**
     * 叠加官方印章（如：审核通过章）
     * —— 保持透明，直接绘制
     */
    private void overlayOfficialSeal(Graphics2D pen, PrescribeXyImgParam param) {
        try {
            BufferedImage seal = getSealImage(TEMPLATE_PATH_OFFICIAL);
            if (seal != null) {
                int width = 500;
                int height = 344;
                Image scaledSeal = seal.getScaledInstance(width, height, Image.SCALE_SMOOTH);
                int x = 1315;
                int y = 1350;

                // 保存原始合成模式
                Composite originalComposite = pen.getComposite();
                AlphaComposite transparent = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.75f);
                // 设置透明合成模式（如果图片有透明度，这会保留透明度）
                pen.setComposite(transparent);

                // 绘制印章
                pen.drawImage(scaledSeal, x, y, null);

                // 恢复原始合成模式
                pen.setComposite(originalComposite);
            }
        } catch (Exception e) {
            log.error("叠加官方印章失败", e);
        }
    }

    /**
     * 叠加“已使用”印章（如：作废/已发药章）
     */
    private void overlayUsedSeal(Graphics2D pen, PrescribeXyImgParam param) {

        if (param.getStatus()!=null && param.getStatus()==3) {
            //当处方的订单状态为"待收货"时叠加已使用印章
        try {
            BufferedImage seal = getSealImage(TEMPLATE_PATH_USED);
            if (seal != null) {
                int width = 1045;
                int height = 577;
                Image scaledSeal = seal.getScaledInstance(width, height, Image.SCALE_SMOOTH);
                int x = 125;
                int y = 1100;

                // 保存原始合成模式
                Composite originalComposite = pen.getComposite();

                AlphaComposite transparent = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.75f);
                // 设置透明合成模式（如果图片有透明度，这会保留透明度）
                pen.setComposite(transparent);

                // 绘制印章
                pen.drawImage(scaledSeal, x, y, null);

                // 恢复原始合成模式
                pen.setComposite(originalComposite);
            }
        } catch (Exception e) {
            log.error("叠加已使用印章失败", e);
        }

        }

    }

    /**
     * 获取印章图片（带缓存）
     */
    private BufferedImage getSealImage(String path) {
        if (StringUtils.isBlank(path)) {
            return null;
        }
        return imageCache.get(path, key -> {
            try {
                File file = new File(path);
                if (!file.exists()) {
                    throw new RuntimeException("印章图片不存在: " + path);
                }
                BufferedImage img = ImageIO.read(file);
                log.debug("印章图片加载成功: {}", path);
                return img;
            } catch (Exception e) {
                log.error("加载印章图片失败: {}", path, e);
                return null;
            }
        });
    }

    /**
     * 下载签名图片(带缓存)
     */
    private BufferedImage downloadSignatureImage(String url) {
        if (StringUtils.isBlank(url)) {
            return null;
        }

        return imageCache.get(url, key -> {
            try {
                log.info("下载签名图片: {}", url);
                URL imageUrl = new URL(url);
                BufferedImage image = ImageIO.read(imageUrl);
                return image;
            } catch (Exception e) {
                log.error("下载签名图片失败: {}", url, e);
                return null;
            }
        });
    }

    /**
     * 多行文本绘制(自动换行)
     * @return 返回最后一行的Y坐标
     */
    private int drawMultiLineText(Graphics2D pen, String text, int x, int y, int maxWidth) {
        if (StringUtils.isBlank(text)) {
            return y;
        }

        FontMetrics fm = pen.getFontMetrics();
        String[] words = text.split("");
        StringBuilder line = new StringBuilder();
        int currentY = y;

        for (String word : words) {
            String testLine = line + word;
            int lineWidth = fm.stringWidth(testLine);

            if (lineWidth > maxWidth && line.length() > 0) {
                // 绘制当前行
                pen.drawString(line.toString(), x, currentY);
                currentY += fm.getHeight();
                line = new StringBuilder(word);
            } else {
                line.append(word);
            }
        }

        if (line.length() > 0) {
            pen.drawString(line.toString(), x, currentY);
            currentY += fm.getHeight();
        }

        return currentY;
    }

    /**
     * 上传图片到OSS
     */
    private String uploadToOSS(BufferedImage image) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", baos);

        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        CloudStorageService storage = OSSFactory.build();
        String url = storage.uploadSuffix(bais, ".jpg");

        baos.close();
        bais.close();

        return url;
    }

    //    /**
//     * 绘制药品列表
//     * @return 返回最后一行的Y坐标
//     */
//    public int drawDrugList(Graphics2D pen, List<FsPrescribeDrug> drugs) {
//        if (drugs == null || drugs.isEmpty()) {
//            return 330;
//        }
//
//        int x = 133;
//        int y = 728;
//        int lineHeight = 30;
//
//        for (FsPrescribeDrug drug : drugs) {
//            // 格式: 药品名 规格 用法 频次 每次用量 x 数量
//            StringBuilder sb = new StringBuilder();
//
//            if (StringUtils.isNotBlank(drug.getDrugName())) {
//                sb.append(drug.getDrugName()).append(" ");
//            }
//            if (StringUtils.isNotBlank(drug.getDrugSpec())) {
//                sb.append(drug.getDrugSpec()).append(" ");
//            }
//            if (StringUtils.isNotBlank(drug.getUsageMethod())) {
//                sb.append(drug.getUsageMethod()).append(" ");
//            }
//            if (StringUtils.isNotBlank(drug.getUsageFrequencyUnit())) {
//                sb.append(drug.getUsageFrequencyUnit()).append(" ");
//            }
//            if (StringUtils.isNotBlank(drug.getUsagePerUseCount())) {
//                sb.append(drug.getUsagePerUseCount());
//            }
//            if (StringUtils.isNotBlank(drug.getUsagePerUseUnit())) {
//                sb.append(drug.getUsagePerUseUnit()).append(" ");
//            }
//            if (drug.getDrugNum() != null) {
//                sb.append("x ").append(drug.getDrugNum());
//            }
//            if (StringUtils.isNotBlank(drug.getDrugUnit())) {
//                sb.append(drug.getDrugUnit());
//            }
//
//            String drugInfo = sb.toString().trim();
//            if (StringUtils.isNotBlank(drugInfo)) {
//                y = drawMultiLineText(pen, drugInfo, x, y, 760);
//                y += lineHeight;
//            }
//        }
//
//        return y;
//    }
}
