package com.fs.store.service;

import com.fs.common.config.FSSysConfig;
import com.fs.store.dto.MedicalRecordDTO;
import com.fs.system.oss.CloudStorageService;
import com.fs.system.oss.OSSFactory;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.resizers.configurations.Antialiasing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;

@Service
@Slf4j
public class MedicalRecordService {
    @Autowired
    private FSSysConfig fsSysConfig;
    /**
     * 生成病历单图片并上传到OSS
     * @param dto 病历单数据
     * @return OSS图片URL
     */
    public String generateMedicalRecord(MedicalRecordDTO dto) {
        try {
            // 创建图片
            BufferedImage image = createMedicalRecordImage(dto);

            // 转换为字节流
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);

            // 上传到OSS
            InputStream inputStream = new ByteArrayInputStream(os.toByteArray());
            CloudStorageService storage = OSSFactory.build();
            String url = storage.uploadSuffix(inputStream, ".jpg");

            log.info("病历单生成成功，URL: {}", url);
            return url;

        } catch (Exception e) {
            log.error("生成病历单失败", e);
            throw new RuntimeException("生成病历单失败", e);
        }
    }

    /**
     * 创建病历单图片
     */
    private BufferedImage createMedicalRecordImage(MedicalRecordDTO dto) {
        // 创建A4大小的图片 (210mm x 297mm, 72dpi)
        int width = 595;  // A4宽度
        int height = 842; // A4高度

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = image.createGraphics();

        // 设置抗锯齿，提高文字清晰度
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        // 填充白色背景
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, width, height);

        // 设置黑色画笔
        g2d.setColor(Color.BLACK);

        // 绘制标题
        Font titleFont = new Font("黑体", Font.PLAIN,20);
        g2d.setFont(titleFont);
        drawCenteredString(g2d, "成都御君方互联网医院电子病历", width, 40);

        // 设置内容字体
        Font labelFont = new Font("黑体", Font.PLAIN, 12);
        Font contentFont = new Font("黑体", Font.PLAIN, 12);

        // 起始坐标
        int leftMargin = 50;
        int rightMargin = width - 50;
        int yPos = 80;
        int lineHeight = 25;
        int columnWidth = (rightMargin - leftMargin) / 2;

        // 绘制日期和基本信息行
        g2d.setFont(labelFont);
        g2d.drawString("就诊日期：", leftMargin, yPos);
        g2d.setFont(contentFont);
        g2d.drawString(formatDate(dto.getVisitDate()), leftMargin + 70, yPos);

        g2d.setFont(labelFont);
        g2d.drawString("科别：", leftMargin + columnWidth, yPos);
        g2d.setFont(contentFont);
        g2d.drawString(dto.getDepartment() != null ? dto.getDepartment() : "", leftMargin + columnWidth + 40, yPos);

        yPos += lineHeight;

        // 门诊号和付款类型
        g2d.setFont(labelFont);
        g2d.drawString("门诊号：", leftMargin, yPos);
        g2d.setFont(contentFont);
        g2d.drawString(dto.getOutpatientNo() != null ? dto.getOutpatientNo() : "", leftMargin + 55, yPos);

        g2d.setFont(labelFont);
        g2d.drawString("付款类型：", leftMargin + columnWidth, yPos);
        g2d.setFont(contentFont);
        g2d.drawString(dto.getPaymentType() != null ? dto.getPaymentType() : "", leftMargin + columnWidth + 65, yPos);

        yPos += lineHeight+30;

        // 患者基本信息
        drawPatientInfo(g2d, dto, leftMargin, rightMargin, yPos, lineHeight, labelFont, contentFont);
        yPos += lineHeight * 3;

        // 分隔线
        g2d.drawLine(leftMargin, yPos, rightMargin, yPos);
        yPos += 30;

        // 病情信息
        yPos = drawSection(g2d, "主诉：", dto.getChiefComplaint(), leftMargin, rightMargin, yPos, labelFont, contentFont);
        yPos = drawSection(g2d, "现病史：", dto.getPresentIllness(), leftMargin, rightMargin, yPos, labelFont, contentFont);
        yPos = drawSection(g2d, "既往史：", dto.getPastHistory(), leftMargin, rightMargin, yPos, labelFont, contentFont);
        yPos = drawSection(g2d, "过敏史：", dto.getAllergyHistory(), leftMargin, rightMargin, yPos, labelFont, contentFont);
        yPos = drawSection(g2d, "生命体征：", dto.getVitalSigns(), leftMargin, rightMargin, yPos, labelFont, contentFont);
        yPos = drawSection(g2d, "辅助检查：", dto.getAuxiliaryExam(), leftMargin, rightMargin, yPos, labelFont, contentFont);
        yPos = drawSection(g2d, "诊断：", dto.getDiagnosis(), leftMargin, rightMargin, yPos, labelFont, contentFont);
        yPos = drawSection(g2d, "医嘱：", dto.getMedicalAdvice(), leftMargin, rightMargin, yPos, labelFont, contentFont);
        yPos = drawSection(g2d, "健康教育：", dto.getHealthEducation(), leftMargin, rightMargin, yPos, labelFont, contentFont);
        yPos = drawSection(g2d, "处理意见：", dto.getTreatmentPlan(), leftMargin, rightMargin, yPos, labelFont, contentFont);
        yPos = drawSection(g2d, "处方1：", dto.getPrescription(), leftMargin, rightMargin, yPos, labelFont, contentFont);

        // 医生签名
        yPos += 60;
        g2d.setFont(labelFont);
        g2d.drawString("医生签名：", rightMargin - 200, yPos);

        try{
            URL imageUrl = new URL(fsSysConfig.getDoctorSignImgUrl());
            BufferedImage scaledImg = Thumbnails.of(imageUrl)
                    .size(120, 55)
                    .outputQuality(1.0)
                    .antialiasing(Antialiasing.ON)
                    .asBufferedImage();
            g2d.drawImage(scaledImg, rightMargin - 150, yPos-25, null);

        }catch (Exception e) {
            e.printStackTrace();
        }


        // 底部日期
        g2d.setFont(labelFont);
        g2d.drawString("就诊日期：", leftMargin, yPos);
        g2d.setFont(contentFont);
        g2d.drawString(formatDate(dto.getVisitDate()), leftMargin + 70, yPos);

        g2d.dispose();
        return image;
    }

    /**
     * 绘制患者基本信息
     */
    private void drawPatientInfo(Graphics2D g2d, MedicalRecordDTO dto, int leftMargin, int rightMargin,
                                int yPos, int lineHeight, Font labelFont, Font contentFont) {
        int columnWidth = (rightMargin - leftMargin) / 3;

        // 第一行：姓名、性别、年龄
        g2d.setFont(labelFont);
        g2d.drawString("姓名：", leftMargin, yPos);
        g2d.setFont(contentFont);
        g2d.drawString(dto.getPatientName() != null ? dto.getPatientName() : "", leftMargin + 40, yPos);

        g2d.setFont(labelFont);
        g2d.drawString("性别：", leftMargin + columnWidth, yPos);
        g2d.setFont(contentFont);
        g2d.drawString(dto.getGender() != null ? dto.getGender() : "", leftMargin + columnWidth + 40, yPos);

        g2d.setFont(labelFont);
        g2d.drawString("年龄：", leftMargin + columnWidth * 2, yPos);
        g2d.setFont(contentFont);
        g2d.drawString(dto.getAge() != null ? dto.getAge() + "岁" : "", leftMargin + columnWidth * 2 + 40, yPos);

        // 第二行：身高、体重、联系电话
        yPos += lineHeight;
        g2d.setFont(labelFont);
        g2d.drawString("身高/体重：", leftMargin, yPos);
        g2d.setFont(contentFont);
        String heightWeight = (dto.getHeight() != null ? dto.getHeight() : "") + "/" +
                            (dto.getWeight() != null ? dto.getWeight() : "");
        g2d.drawString(heightWeight, leftMargin + 75, yPos);

        g2d.setFont(labelFont);
        g2d.drawString("联系电话：", leftMargin + columnWidth, yPos);
        g2d.setFont(contentFont);
        g2d.drawString(dto.getPhone() != null ? dto.getPhone() : "", leftMargin + columnWidth + 65, yPos);

        // 第三行：单位或地址
        yPos += lineHeight;
        g2d.setFont(labelFont);
        g2d.drawString("单位或地址：", leftMargin, yPos);
        g2d.setFont(contentFont);
        g2d.drawString(dto.getAddress() != null ? dto.getAddress() : "", leftMargin + 85, yPos);
    }

    /**
     * 绘制文本段落（支持自动换行）
     */
    private int drawSection(Graphics2D g2d, String label, String content, int leftMargin, int rightMargin,
                           int yPos, Font labelFont, Font contentFont) {
        g2d.setFont(labelFont);
        g2d.drawString(label, leftMargin, yPos);

        if (content == null || content.isEmpty()) {
            return yPos + 25;
        }

        g2d.setFont(contentFont);
        FontMetrics fm = g2d.getFontMetrics();
        int labelWidth = fm.stringWidth(label);
        int contentX = leftMargin + labelWidth;
        int maxWidth = rightMargin - contentX - 10;

        // 自动换行处理
        String[] lines = wrapText(content, fm, maxWidth);
        for (int i = 0; i < lines.length; i++) {
            if (i == 0) {
                g2d.drawString(lines[i], contentX, yPos);
            } else {
                yPos += 20;
                g2d.drawString(lines[i], leftMargin + 20, yPos);
            }
        }

        return yPos + 25;
    }

    /**
     * 文本自动换行
     */
    private String[] wrapText(String text, FontMetrics fm, int maxWidth) {
        java.util.List<String> lines = new java.util.ArrayList<>();

        // 先处理制表符，将 \t 替换为4个空格（可根据需要调整）
        text = text.replace("\t", "    ");

        // 按换行符分割，保留原有的换行
        String[] paragraphs = text.split("\n", -1);

        for (String paragraph : paragraphs) {
            if (paragraph.isEmpty()) {
                lines.add(""); // 保留空行
                continue;
            }

            // 对每个段落进行宽度换行处理
            StringBuilder line = new StringBuilder();
            String[] chars = paragraph.split("");

            for (String ch : chars) {
                String testLine = line.toString() + ch;
                if (fm.stringWidth(testLine) > maxWidth) {
                    if (line.length() > 0) {
                        lines.add(line.toString());
                        line = new StringBuilder(ch);
                    }
                } else {
                    line.append(ch);
                }
            }

            if (line.length() > 0) {
                lines.add(line.toString());
            }
        }

        return lines.toArray(new String[0]);
    }

    /**
     * 居中绘制文字
     */
    private void drawCenteredString(Graphics2D g2d, String text, int width, int y) {
        FontMetrics fm = g2d.getFontMetrics();
        int x = (width - fm.stringWidth(text)) / 2;
        g2d.drawString(text, x, y);
    }

    /**
     * 格式化日期
     */
    private String formatDate(Date date) {
        if (date == null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        return sdf.format(date);
    }
}
