package com.yiboshi.science.utils;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.yiboshi.science.param.dto.ComProjectDTO;
import org.springframework.core.io.ClassPathResource;
import java.io.*;
import java.util.Objects;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ProjectInfoToPDF {

    /**
     * 生成项目申请书和合同书PDF
     * @param project 项目信息
     * @param outputPath 输出路径
     */
    public static void generateProjectPDF(ComProjectDTO project, String outputPath) throws DocumentException, IOException {
        Document document = new Document(PageSize.A4);
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(outputPath));
        document.open();

        // 宋体
        BaseFont bfChinese = loadChineseFont("/fonts/simsun.ttc");
        // 仿宋
        BaseFont fsChinese = loadChineseFont("/fonts/simfang.ttf");

        Font normalFont = new Font(bfChinese, 12, Font.NORMAL);
        Font boldFont = new Font(bfChinese, 12, Font.BOLD);

        //首页内容
        FirstPageInfo(document, project, bfChinese, fsChinese);
        
        // 添加新页面
        document.newPage();

        // 添加项目内容章节
        addSection(document, "一、项目基本情况", boldFont);
        addProjectBasicTable(document, project, bfChinese, fsChinese);  // 添加项目基本信息表格
        // 添加新页面
        document.newPage();

        addSection(document, "二、主要技术指标", boldFont);
        addContent(document, project.getTechnologyTarget(), normalFont);

        addSection(document, "三、主要经济指标", boldFont);
        addContent(document, project.getEconomyTarget(), normalFont);

        addSection(document, "四、项目实施中形成的示范基地、中试线、生产线及其规模等", boldFont);
        addContent(document, project.getAchievementTarget(), normalFont);

        addSection(document, "五、科技报告考核指标", boldFont);
        addContent(document, project.getTechnologyReportsTarget(), normalFont);

        addSection(document, "六、其他应考核的指标", boldFont);
        addContent(document, project.getOtherTarget(), normalFont);

        // 添加签字栏
        addSignatureSection(document, normalFont);

        document.close();
    }

    /**
     * 加载中文字体
     * @param fontPath 字体文件路径(相对于resources目录)
     * @return BaseFont 中文字体
     * @throws RuntimeException 加载字体失败时抛出异常
     */
    private static BaseFont loadChineseFont(String fontPath) {
        try {
            // 从资源文件夹加载字体
            String path = ProjectInfoToPDF.class.getResource(fontPath).getPath();
            
            // 根据字体文件类型使用不同的加载方式
            if (fontPath.toLowerCase().endsWith(".ttc")) {
                return BaseFont.createFont(path + ",0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            } else {
                return BaseFont.createFont(path, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            }
        } catch (Exception e) {
            throw new RuntimeException("加载字体文件失败,请确保resources目录下存在字体文件 " + fontPath + ":" + e.getMessage(), e);
        }
    }

    /**
     * 格式化起止年限
     * @param date 开始日期
     * @return 格式化后的日期范围字符串
     */
    private static String formatDateRange(Date date, int type) {
        // 定义日期格式
        SimpleDateFormat sdf;
        if (type == 1)
            sdf = new SimpleDateFormat("yyyy年MM月");
        else
            sdf = new SimpleDateFormat("yyyy年MM月dd日");

        return sdf.format(date);
    }

    /**
     * 首页项目信息
     * @param document
     * @param project
     * @param bfChinese
     * @param fsChinese
     * @return
     * @throws DocumentException
     */
    private static Document FirstPageInfo(Document document, ComProjectDTO project, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {

        Font titleFont = new Font(bfChinese, 20, Font.BOLD);
        Font normalFont = new Font(bfChinese, 12, Font.NORMAL);
        Font labelFont = new Font(fsChinese, 16, Font.NORMAL);
        Font valueFont = new Font(bfChinese, 16, Font.NORMAL);

        // 添加项目编号到左上角
        Paragraph projNo;
        if (Objects.nonNull(project.getProjNo())) {
            Chunk text = new Chunk("项目编号:", normalFont);
            Chunk number = new Chunk(project.getProjNo(), normalFont);
            number.setUnderline(0.1f, -2f); // 设置下划线
            projNo = new Paragraph();
            projNo.add(text);
            projNo.add(number);
            projNo.add(Chunk.NEWLINE);
            projNo.add(Chunk.NEWLINE);
            projNo.add(Chunk.NEWLINE);
            projNo.add(Chunk.NEWLINE);
        } else {
            Chunk text = new Chunk("项目编号:", normalFont);
            Chunk underline = new Chunk("                    ", normalFont);
            underline.setUnderline(0.1f, -2f); // 设置下划线
            projNo = new Paragraph();
            projNo.add(text);
            projNo.add(underline);
            projNo.add(Chunk.NEWLINE);
            projNo.add(Chunk.NEWLINE);
            projNo.add(Chunk.NEWLINE);
            projNo.add(Chunk.NEWLINE);
        }
        projNo.setAlignment(Element.ALIGN_LEFT);
        projNo.setSpacingAfter(50f);
        document.add(projNo);

        // 添加标题
        Paragraph title = new Paragraph("省级临床医学中心科研项目申请书", titleFont);
        title.setAlignment(Element.ALIGN_CENTER);
        title.setSpacingAfter(50f);  // 增加标题后的间距
        document.add(title);

        // 添加项目基本信息表格
        PdfPTable table = new PdfPTable(2);
        table.setWidthPercentage(95);
        table.setSpacingBefore(50f);  // 增加表格前的间距
        table.setSpacingAfter(10f);
        table.setHorizontalAlignment(Element.ALIGN_LEFT);  // 设置表格左对齐
        
        // 设置列宽度
        float[] columnWidths = {0.35f, 0.65f};
        table.setWidths(columnWidths);

        // 添加表格内容
        addTableRow(table, "项目名称:", project.getProjName(), labelFont, valueFont);
        addTableRow(table, "申报单位:", project.getAppUnitName(), labelFont, valueFont);
        addTableRow(table, "推荐部门(丙方):", "", labelFont, valueFont);
        addTableRow(table, "项目负责人:", project.getAppPersonName(), labelFont, valueFont);
        addTableRow(table, "联系电话:", project.getMobile(), labelFont, valueFont);
        addTableRow(table, "起止年限:", formatDateRange(project.getStartDate(), 1) + "至" + formatDateRange(project.getEndDate(), 1), labelFont, valueFont);
        addTableRow(table, "填报日期:", formatDateRange(project.getCreated(), 2), labelFont, valueFont);
        document.add(table);

        return document;
    }

    /**
     * 添加首页项目表格信息
     * @param table
     * @param label
     * @param value
     * @param labelFont
     * @param valueFont
     */
    private static void addTableRow(PdfPTable table, String label, String value, Font labelFont, Font valueFont) {
        // 标签单元格
        PdfPCell labelCell = new PdfPCell(new Phrase(label, labelFont));
        labelCell.setMinimumHeight(28f);
        labelCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        labelCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
        labelCell.setPaddingRight(5f);
        labelCell.setBorder(Rectangle.NO_BORDER);
        
        // 值单元格
        Phrase valuePhrase;
        if (value != null && !value.trim().isEmpty()) {
            valuePhrase = new Phrase(value, valueFont);
        } else {
            valuePhrase = new Phrase(" ", valueFont); // 空值时使用一个空格
        }
        
        PdfPCell valueCell = new PdfPCell(valuePhrase);
        valueCell.setMinimumHeight(28f);
        valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        valueCell.setHorizontalAlignment(Element.ALIGN_LEFT);  // 修改为左对齐
        valueCell.setPaddingLeft(5f);
        valueCell.setPaddingRight(10f);
        valueCell.setBorder(Rectangle.NO_BORDER);
        
        // 添加自定义事件来绘制下划线
        valueCell.setCellEvent(new PdfPCellEvent() {
            public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
                PdfContentByte cb = canvases[PdfPTable.LINECANVAS];
                cb.setLineWidth(0.5f);
                float y = position.getBottom() + 2; // 调整下划线位置
                cb.moveTo(position.getLeft(), y);
                cb.lineTo(position.getRight(), y);
                cb.stroke();
            }
        });
        
        table.addCell(labelCell);
        table.addCell(valueCell);
    }

    /**
     * 项目基本信息
     * @param document
     * @param project
     * @param bfChinese
     * @param fsChinese
     * @throws DocumentException
     */
    private static void addProjectBasicTable(Document document, ComProjectDTO project, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        Font labelFont = new Font(bfChinese, 12, Font.NORMAL);
        Font valueFont = new Font(fsChinese, 12, Font.NORMAL);
        Font titleFont = new Font(bfChinese, 12, Font.BOLD);

        // 创建一个大表格
        PdfPTable mainTable = new PdfPTable(1);  // 单列表格
        mainTable.setWidthPercentage(95);
        mainTable.setSpacingBefore(10f);

        // 申请人信息部分
        PdfPTable personTable = new PdfPTable(9);  // 9列,第一列用于标题
        float[] personWidths = {1f, 1.5f, 2f, 1f, 2f, 1.5f, 2f, 2f, 2f};  // 调整第一列宽度
        personTable.setWidths(personWidths);
        
        // 申请人信息标题行
        PdfPCell titleCell = new PdfPCell(new Phrase("申\n请\n人\n信\n息", titleFont));
        titleCell.setRowspan(6);  // 合并6行
        titleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        titleCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        titleCell.setMinimumHeight(150f);  // 调整高度以适应内容
        personTable.addCell(titleCell);
        
        // 第一行
        addBasicTableCell(personTable, "姓    名", project.getAppPersonName(), 2, labelFont, valueFont);
        addBasicTableCell(personTable, "性别", project.getSex(), 2, labelFont, valueFont);
        addBasicTableCell(personTable, "出生年月", formatDateRange(project.getBirthday(), 1), 2, labelFont, valueFont);
        addBasicTableCell(personTable, "民族", project.getNationName(), 2, labelFont, valueFont);
        
        // 第二行
        addBasicTableCell(personTable, "学    位", project.getDegreeName(), 2, labelFont, valueFont);
        addBasicTableCell(personTable, "职称", project.getTitleName(), 2, labelFont, valueFont);
        addBasicTableCell(personTable, "每年工作时间(月)", project.getJobTime().toString(), 4, labelFont, valueFont);
        
        // 第三行
        addBasicTableCell(personTable, "电    话", project.getMobile(), 4, labelFont, valueFont);
        addBasicTableCell(personTable, "电子邮箱", project.getEmail(), 4, labelFont, valueFont);
        
        // 第四行
        addBasicTableCell(personTable, "个人通讯地址", project.getAddress(), 8, labelFont, valueFont);
        
        // 第五行
        addBasicTableCell(personTable, "工作单位", project.getAppUnitName(), 8, labelFont, valueFont);
        
        // 第六行
        addBasicTableCell(personTable, "主要研究领域", project.getMainResearchAreas(), 8, labelFont, valueFont);

        // 将申请人信息表格添加到主表格
        PdfPCell personCell = new PdfPCell(personTable);
        personCell.setPadding(0);
        personCell.setBorder(Rectangle.BOX);
        mainTable.addCell(personCell);
        
        // 申请单位信息部分
        PdfPTable unitTable = new PdfPTable(5);  // 5列,第一列用于标题
        float[] unitWidths = {1.2f, 3f, 5f, 3f, 5f};  // 调整所有列的比例,保持第一列宽度一致
        unitTable.setWidths(unitWidths);
        
        // 申请单位信息标题行
        titleCell = new PdfPCell(new Phrase("申\n请\n单\n位\n信\n息", titleFont));
        titleCell.setRowspan(5);  // 合并5行
        titleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        titleCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        titleCell.setMinimumHeight(100f);
        unitTable.addCell(titleCell);
        
        // 单位信息内容
        addBasicTableCell(unitTable, "单位名称", project.getAppUnitName(), 4, labelFont, valueFont);
        addBasicTableCell(unitTable, "联系人", project.getUnitLinkName(), 2, labelFont, valueFont);
        addBasicTableCell(unitTable, "电话", project.getUnitLinkMobile(), 2, labelFont, valueFont);
        addBasicTableCell(unitTable, "电子信箱", project.getUnitLinkEmail(), 2, labelFont, valueFont);
        addBasicTableCell(unitTable, "传真", project.getUnitLinkFax(), 2, labelFont, valueFont);

        // 将申请单位信息表格添加到主表格
        PdfPCell unitCell = new PdfPCell(unitTable);
        unitCell.setPadding(0);
        unitCell.setBorder(Rectangle.BOX);
        mainTable.addCell(unitCell);
        
        // 项目基本情况部分
        PdfPTable projTable = new PdfPTable(5);  // 5列,第一列用于标题
        float[] projWidths = {1.2f, 3f, 5f, 3f, 5f};  // 与申请单位信息表格使用相同的比例
        projTable.setWidths(projWidths);
        
        // 项目基本情况标题行
        titleCell = new PdfPCell(new Phrase("项\n目\n基\n本\n信\n息", titleFont));
        titleCell.setRowspan(8);  // 合并8行
        titleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        titleCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        titleCell.setMinimumHeight(200f);
        projTable.addCell(titleCell);
        
        // 项目基本情况内容
        addBasicTableCell(projTable, "项目名称", project.getProjName(), 4, labelFont, valueFont);
        addBasicTableCell(projTable, "学科代码", project.getKnowledgeName(), 2, labelFont, valueFont);
        addBasicTableCell(projTable, "选题范围", project.getSubjectScope(), 2, labelFont, valueFont);
        addBasicTableCell(projTable, "项目类别", project.getProjClassName(), 2, labelFont, valueFont);
        addBasicTableCell(projTable, "研究期限", formatDateRange(project.getStartDate(), 1), 2, labelFont, valueFont);
        addBasicTableCell(projTable, "项目总经费(万元)", project.getTotalFunding().toString(), 2, labelFont, valueFont);
        addBasicTableCell(projTable, "申请经费", project.getGovFunding().toString(), 2, labelFont, valueFont);
        addBasicTableCell(projTable, "项目摘要", project.getProjAbstract(), 4, labelFont, valueFont);
        addBasicTableCell(projTable, "关键词", project.getProjKeywords(), 4, labelFont, valueFont);

        // 将项目基本情况表格添加到主表格
        PdfPCell projCell = new PdfPCell(projTable);
        projCell.setPadding(0);
        projCell.setBorder(Rectangle.BOX);
        mainTable.addCell(projCell);

        document.add(mainTable);
    }

    /**
     * 添加基本信息表格单元格
     * @param table
     * @param label
     * @param value
     * @param colspan
     * @param labelFont
     * @param valueFont
     */
    private static void addBasicTableCell(PdfPTable table, String label, String value, int colspan, Font labelFont, Font valueFont) {
        PdfPCell labelCell = new PdfPCell(new Phrase(label, labelFont));
        labelCell.setMinimumHeight(25f);
        labelCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        labelCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.addCell(labelCell);
        
        PdfPCell valueCell = new PdfPCell(new Phrase(value != null ? value : "", valueFont));
        valueCell.setMinimumHeight(25f);
        valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        valueCell.setHorizontalAlignment(Element.ALIGN_LEFT);
        valueCell.setColspan(colspan - 1);
        table.addCell(valueCell);
    }

    private static void addSection(Document document, String title, Font font) throws DocumentException {
        Paragraph section = new Paragraph(title, font);
        section.setSpacingBefore(15);
        section.setSpacingAfter(10);
        document.add(section);
    }

    private static void addContent(Document document, String content, Font font) throws DocumentException {
        if (content != null) {
            Paragraph paragraph = new Paragraph(content, font);
            paragraph.setIndentationLeft(20);
            paragraph.setSpacingAfter(10);
            document.add(paragraph);
        }
    }

    private static void addSignatureSection(Document document, Font font) throws DocumentException {
        Paragraph signature = new Paragraph("\n\n", font);
        signature.add(new Chunk("申请人签字:", font));
        signature.add(new Chunk("                            ", font));
        signature.add(new Chunk("日期:", font));
        signature.add(new Chunk("                            ", font));
        signature.setAlignment(Element.ALIGN_RIGHT);
        signature.setSpacingBefore(50);
        document.add(signature);

        Paragraph unitSignature = new Paragraph("\n", font);
        unitSignature.add(new Chunk("申请单位(盖章):", font));
        unitSignature.add(new Chunk("                            ", font));
        unitSignature.add(new Chunk("日期:", font));
        unitSignature.add(new Chunk("                            ", font));
        unitSignature.setAlignment(Element.ALIGN_RIGHT);
        unitSignature.setSpacingBefore(30);
        document.add(unitSignature);
    }
}