package com.yd.csf.service.component;

import cn.hutool.core.util.NumberUtil;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import com.yd.common.exception.BusinessException;
import com.yd.csf.service.dto.PolicyReportData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;

@Service
@Slf4j
public class PolicyReportPdfService {
    private Font chineseFont;
    private Font chineseBoldFont;
    private Font chineseTitleFont;
    private Font chineseRedTitleFont;

    // 颜色定义
    private static final Color RED_TITLE_COLOR = new Color(255, 0, 0);
    private static final Color TEXT_COLOR = new Color(102, 102, 102);
    private static final Color FOOTNOTE_COLOR = new Color(153, 153, 153);
    private static final Color LINE_COLOR = new Color(226, 226, 226);

    // 调整字号常量
    private static final float MAIN_TITLE_FONT_SIZE = 28f;  // 增大主标题字号
    private static final float SECTION_TITLE_FONT_SIZE = 16f; // 调整章节标题字号
    private static final float CONTENT_FONT_SIZE = 12f;    // 调整内容文字字号
    private static final float FOOTNOTE_FONT_SIZE = 10f;   // 调整备注文字字号

    // 调整间距常量
    private static final float MAIN_TITLE_MARGIN_BOTTOM = 20f; // 增大主标题下方间距
    private static final float LINE_MARGIN_BOTTOM = 18f;       // 调整水平线间距
    private static final float ROW_SPACING = 12f;              // 调整行间距

    public byte[] generatePolicyReport(PolicyReportData reportData) throws DocumentException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            Document document = new Document(PageSize.A4, 40, 40, 40, 40);
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            document.open();

            initChineseFont();

            // 1. 主标题
            addMainTitle(document, "簽單完成報告");
            // 2. 主标题下方水平线
            addHorizontalLine(document, writer);
            // 3. 基本信息表格
            addBasicInfo(document, reportData);
            // 4. 保单详细信息标题
            addPolicyDetailTitle(document, reportData);
            // 5. 保单详细信息标题下方水平线
            addHorizontalLine(document, writer);
            // 6. 保单详细字段表格（包含备注和保費徵費）
            addPolicyDetailFields(document, reportData);
            // 7. 附加险表头
            addAdditionalInsuranceHeader(document);
            // 8. 附加险详细信息表格
            addAdditionalInsuranceDetail(document, reportData);
            // 9. 详细信息下方水平线
            addHorizontalLine(document, writer);
            // 移除了原来的备注说明，因为现在备注已经整合到保单详细字段中

            document.close();
            return outputStream.toByteArray();
        } catch (Exception e) {
            log.error("PDF生成失败", e);
            throw new BusinessException("生成报告失败: " + e.getMessage());
        }
    }

    /**
     * 附加险详细信息表格
     */
    private void addAdditionalInsuranceDetail(Document document, PolicyReportData reportData) throws DocumentException {
        if (reportData.getAdditionalInsurances() == null || reportData.getAdditionalInsurances().isEmpty()) {
            return;
        }

        PdfPTable table = new PdfPTable(4);
        table.setWidthPercentage(100);
        table.setWidths(new float[]{25, 25, 25, 25});
        table.setSpacingBefore(0f);
        table.setSpacingAfter(ROW_SPACING);

        // 添加附加险数据行
        for (PolicyReportData.AdditionalInsurance insurance : reportData.getAdditionalInsurances()) {
            addTableCenterCellNoBorder(table, insurance.getName() != null ? insurance.getName() : "");
            addTableCenterCellNoBorder(table, insurance.getPaymentTerm() != null ? String.valueOf(insurance.getPaymentTerm()) : "");
            addTableCenterCellNoBorder(table, insurance.getCurrency() != null ? insurance.getCurrency() : "");
            addTableCenterCellNoBorder(table, insurance.getFirstYearAmount() != null ? formatAmount(insurance.getFirstYearAmount()) : "");
        }

        document.add(table);
    }

    /**
     * 添加居中对齐的无边框内容单元格
     */
    private void addTableCenterCellNoBorder(PdfPTable table, String text) {
        Paragraph para = new Paragraph(text, chineseFont);
        com.lowagie.text.pdf.PdfPCell cell = new com.lowagie.text.pdf.PdfPCell(para);
        cell.setBorder(com.lowagie.text.Rectangle.NO_BORDER);
        cell.setHorizontalAlignment(com.lowagie.text.Element.ALIGN_CENTER);
        cell.setVerticalAlignment(com.lowagie.text.Element.ALIGN_MIDDLE);
        cell.setPadding(2f);
        table.addCell(cell);
    }

    /**
     * 主标题 - 放大并居中
     */
    private void addMainTitle(Document document, String title) throws DocumentException {
        // 创建更大的红色标题字体
        Font largeTitleFont = new Font(chineseRedTitleFont.getBaseFont(), MAIN_TITLE_FONT_SIZE, Font.BOLD, RED_TITLE_COLOR);

        Paragraph titleParagraph = new Paragraph(title, largeTitleFont);
        titleParagraph.setAlignment(Paragraph.ALIGN_CENTER);  // 设置为居中
        titleParagraph.setSpacingAfter(MAIN_TITLE_MARGIN_BOTTOM);
        document.add(titleParagraph);
    }

    /**
     * 水平线 - 调整位置
     */
    private void addHorizontalLine(Document document, PdfWriter writer) throws DocumentException {
        // 绘制直线
        PdfContentByte canvas = writer.getDirectContent();
        canvas.saveState();
        canvas.setColorStroke(LINE_COLOR);
        canvas.setLineWidth(1f);
        float y = writer.getVerticalPosition(false) - 5f;
        canvas.moveTo(40, y);
        canvas.lineTo(PageSize.A4.getWidth() - 40, y);
        canvas.stroke();
        canvas.restoreState();

        // 添加额外间距
        Paragraph extraSpacing = new Paragraph(" ");
        extraSpacing.setSpacingAfter(8f);
        document.add(extraSpacing);
    }

    /**
     * 保单详细信息标题 - 调整字体大小
     */
    private void addPolicyDetailTitle(Document document, PolicyReportData data) throws DocumentException {
        PdfPTable table = new PdfPTable(4);
        table.setWidthPercentage(100);
        table.setWidths(new float[]{25, 25, 25, 25});
        table.setSpacingBefore(0f);
        table.setSpacingAfter(ROW_SPACING);

        // 使用更大的字体和红色
        Font sectionTitleFont = new Font(chineseRedTitleFont.getBaseFont(), SECTION_TITLE_FONT_SIZE, Font.BOLD, RED_TITLE_COLOR);

        Paragraph titlePara = new Paragraph("保單詳細信息", sectionTitleFont);
        com.lowagie.text.pdf.PdfPCell titleCell = new com.lowagie.text.pdf.PdfPCell(titlePara);
        titleCell.setBorder(com.lowagie.text.Rectangle.NO_BORDER);
        titleCell.setHorizontalAlignment(com.lowagie.text.Element.ALIGN_LEFT);

        // 第二列：空
        com.lowagie.text.pdf.PdfPCell emptyCell1 = new com.lowagie.text.pdf.PdfPCell(new Paragraph(" "));
        emptyCell1.setBorder(com.lowagie.text.Rectangle.NO_BORDER);

        // 第三列：保單編號标签
        Paragraph numberLabelPara = new Paragraph("保單編號", chineseFont);
        com.lowagie.text.pdf.PdfPCell numberLabelCell = new com.lowagie.text.pdf.PdfPCell(numberLabelPara);
        numberLabelCell.setBorder(com.lowagie.text.Rectangle.NO_BORDER);
        numberLabelCell.setHorizontalAlignment(com.lowagie.text.Element.ALIGN_LEFT);

        // 第四列：保单编号值
        Paragraph numberValuePara = new Paragraph(data.getPolicyNumber() != null ? data.getPolicyNumber() : "", chineseFont);
        com.lowagie.text.pdf.PdfPCell numberValueCell = new com.lowagie.text.pdf.PdfPCell(numberValuePara);
        numberValueCell.setBorder(com.lowagie.text.Rectangle.NO_BORDER);
        numberValueCell.setHorizontalAlignment(com.lowagie.text.Element.ALIGN_LEFT);

        table.addCell(titleCell);
        table.addCell(emptyCell1);
        table.addCell(numberLabelCell);
        table.addCell(numberValueCell);

        document.add(table);
    }

    /**
     * 保单详细字段 - 修正保費徵費位置
     */
    private void addPolicyDetailFields(Document document, PolicyReportData data) throws DocumentException {
        PdfPTable table = new PdfPTable(4);
        table.setWidthPercentage(100);
        table.setWidths(new float[]{20, 30, 20, 30});
        table.setSpacingBefore(0f);
        table.setSpacingAfter(ROW_SPACING);

        // 第一行：保單持有人 | 持有人值 | 保險公司 | 公司值
        addTableHeaderCellNoBorder(table, "保單持有人");
        addTableCellNoBorder(table, data.getPolicyHolder() != null ? data.getPolicyHolder() : "");
        addTableHeaderCellNoBorder(table, "保單受保人");
        addTableCellNoBorder(table, data.getInsuredPerson() != null ? data.getInsuredPerson() : "");

        // 第二行：保單受保人 | 受保人值 | 受保人年齡 | 年齡值
        addTableHeaderCellNoBorder(table, "保險公司");
        addTableCellNoBorder(table, data.getInsuranceCompany() != null ? data.getInsuranceCompany() : "");
        addTableHeaderCellNoBorder(table, "受保人年齡");
        addTableCellNoBorder(table, data.getInsuredAge() != null ? String.valueOf(data.getInsuredAge()) : "");

        // 第三行：保險計劃 | 計劃值 | 繳費年期 | 年期值
        addTableHeaderCellNoBorder(table, "保險計劃");
        addTableCellNoBorder(table, data.getInsurancePlan() != null ? data.getInsurancePlan() : "");
        addTableHeaderCellNoBorder(table, "繳費年期");
        addTableCellNoBorder(table, data.getPaymentPeriod() != null ? String.valueOf(data.getPaymentPeriod()) : "");

        // 第四行：保單貨幣 | 貨幣值 | 备注 | 备注（跨列）
        addTableHeaderCellNoBorder(table, "保單貨幣");
        addTableCellNoBorder(table, data.getCurrency() != null ? data.getCurrency() : "");

        // 备注单元格 - 跨第3、4列，与保單貨幣同一行
        Font footnoteFont = new Font(chineseFont.getBaseFont(), FOOTNOTE_FONT_SIZE, Font.NORMAL, FOOTNOTE_COLOR);
        Paragraph footnotePara = new Paragraph(
                "*此徵費為香港政府收取，續期時亦須繳納，但不納入本報告金額統計。澳門保單毋需繳納此費用。",
                footnoteFont
        );
        com.lowagie.text.pdf.PdfPCell footnoteCell = new com.lowagie.text.pdf.PdfPCell(footnotePara);
        footnoteCell.setBorder(com.lowagie.text.Rectangle.NO_BORDER);
        footnoteCell.setHorizontalAlignment(com.lowagie.text.Element.ALIGN_LEFT);
        footnoteCell.setVerticalAlignment(com.lowagie.text.Element.ALIGN_TOP);
        footnoteCell.setColspan(2); // 跨2列
        footnoteCell.setPadding(2f);
        table.addCell(footnoteCell);

        // 第五行：年繳金額 | 金額值 | 保費徵費 | 費用值
        addTableHeaderCellNoBorder(table, "年繳金額");
        addTableCellNoBorder(table, formatAmount(data.getAnnualAmount()));
        addTableHeaderCellNoBorder(table, "保費徵費");
        addTableCellNoBorder(table, formatAmount(data.getPremiumFee()));

        // 第六行：首期合計金額 | 金額值 | (空) | (空)
        addTableHeaderCellNoBorder(table, "首期合計金額");
        addTableCellNoBorder(table, formatAmount(NumberUtil.add(data.getInitialPremium(), data.getPolicyLevy())));
        addTableCellNoBorder(table, "");
        addTableCellNoBorder(table, "");

        document.add(table);
    }

    /**
     * 添加无边框的表头单元格
     */
    private void addTableHeaderCellNoBorder(PdfPTable table, String text) {
        Paragraph para = new Paragraph(text, chineseFont);
        com.lowagie.text.pdf.PdfPCell cell = new com.lowagie.text.pdf.PdfPCell(para);
        cell.setBorder(com.lowagie.text.Rectangle.NO_BORDER);
        cell.setHorizontalAlignment(com.lowagie.text.Element.ALIGN_LEFT);
        cell.setVerticalAlignment(com.lowagie.text.Element.ALIGN_MIDDLE);
        cell.setPadding(2f);
        table.addCell(cell);
    }

    /**
     * 添加无边框的内容单元格
     */
    private void addTableCellNoBorder(PdfPTable table, String text) {
        Paragraph para = new Paragraph(text, chineseFont);
        com.lowagie.text.pdf.PdfPCell cell = new com.lowagie.text.pdf.PdfPCell(para);
        cell.setBorder(com.lowagie.text.Rectangle.NO_BORDER);
        cell.setHorizontalAlignment(com.lowagie.text.Element.ALIGN_LEFT);
        cell.setVerticalAlignment(com.lowagie.text.Element.ALIGN_MIDDLE);
        cell.setPadding(2f);
        table.addCell(cell);
    }

    /**
     * 基本信息 - 调整行间距
     */
    private void addBasicInfo(Document document, PolicyReportData data) throws DocumentException {
        PdfPTable table = new PdfPTable(4);
        table.setWidthPercentage(100);
        table.setWidths(new float[]{20, 30, 20, 30}); // 调整列宽比例
        table.setSpacingBefore(0f);
        table.setSpacingAfter(ROW_SPACING);

        // 第一行
        addTableHeaderCellNoBorder(table, "開始時間");
        addTableCellNoBorder(table, data.getStartTime() != null ? data.getStartTime() : "");
        addTableHeaderCellNoBorder(table, "結束時間");
        addTableCellNoBorder(table, data.getEndTime() != null ? data.getEndTime() : "");

        // 第二行
        addTableHeaderCellNoBorder(table, "簽單地點");
        addTableCellNoBorder(table, data.getLocation() != null ? data.getLocation() : "");
        addTableHeaderCellNoBorder(table, "服務主管");
        addTableCellNoBorder(table, data.getServiceManager() != null ? data.getServiceManager() : "");

        document.add(table);
    }

    /**
     * 附加险表头 - 去掉边框
     */
    private void addAdditionalInsuranceHeader(Document document) throws DocumentException {
        PdfPTable table = new PdfPTable(4);
        table.setWidthPercentage(100);
        table.setWidths(new float[]{25, 25, 25, 25});
        table.setSpacingBefore(10f);
        table.setSpacingAfter(10f);

        // 创建居中对齐的无边框单元格
        addTableCenterHeaderCellNoBorder(table, "附加险名称");
        addTableCenterHeaderCellNoBorder(table, "缴费期限");
        addTableCenterHeaderCellNoBorder(table, "幣种");
        addTableCenterHeaderCellNoBorder(table, "首年金额");

        document.add(table);
    }

    /**
     * 添加居中对齐的无边框表头单元格
     */
    private void addTableCenterHeaderCellNoBorder(PdfPTable table, String text) {
        Paragraph para = new Paragraph(text, chineseBoldFont);
        com.lowagie.text.pdf.PdfPCell cell = new com.lowagie.text.pdf.PdfPCell(para);
        cell.setBorder(com.lowagie.text.Rectangle.NO_BORDER);
        cell.setHorizontalAlignment(com.lowagie.text.Element.ALIGN_CENTER);
        cell.setVerticalAlignment(com.lowagie.text.Element.ALIGN_MIDDLE);
        cell.setPadding(2f);
        table.addCell(cell);
    }

    /**
     * 备注说明
     */
    private void addFootnote(Document document) throws DocumentException {
        Font footnoteFont = new Font(chineseFont.getBaseFont(), FOOTNOTE_FONT_SIZE, Font.NORMAL, FOOTNOTE_COLOR);
        Paragraph footnote = new Paragraph(
                "*此徵費為香港政府收取，續期時亦須繳納，但不納入本報告金額統計。澳門保單毋需繳納此費用。",
                footnoteFont
        );
        footnote.setAlignment(Paragraph.ALIGN_LEFT);
        footnote.setSpacingBefore(10f);
        document.add(footnote);
    }

    /**
     * 添加表格表头单元格
     */
    private void addTableHeaderCell(PdfPTable table, String text) {
        Paragraph para = new Paragraph(text, chineseFont);
        table.addCell(createCell(para, false));
    }

    /**
     * 添加表格内容单元格
     */
    private void addTableCell(PdfPTable table, String text) {
        Paragraph para = new Paragraph(text, chineseFont);
        table.addCell(createCell(para, false));
    }

    /**
     * 添加居中对齐的表头单元格
     */
    private void addTableCenterHeaderCell(PdfPTable table, String text) {
        Paragraph para = new Paragraph(text, chineseBoldFont);
        table.addCell(createCell(para, true));
    }

    /**
     * 创建单元格
     */
    private com.lowagie.text.pdf.PdfPCell createCell(Paragraph paragraph, boolean centerAlign) {
        com.lowagie.text.pdf.PdfPCell cell = new com.lowagie.text.pdf.PdfPCell(paragraph);
        cell.setBorder(com.lowagie.text.Rectangle.NO_BORDER);
        cell.setHorizontalAlignment(centerAlign ? com.lowagie.text.Element.ALIGN_CENTER : com.lowagie.text.Element.ALIGN_LEFT);
        cell.setVerticalAlignment(com.lowagie.text.Element.ALIGN_MIDDLE);
        cell.setPadding(5f);
        return cell;
    }

    /**
     * 初始化中文字体 - 从classpath资源加载
     */
    private void initChineseFont() throws IOException, DocumentException {
        try {
            BaseFont baseFont = null;

            // 优先使用Classpath资源流加载
            try {
                InputStream fontStream = getClass().getClassLoader().getResourceAsStream("font/DFKai-SB.ttf");
                if (fontStream != null) {
                    byte[] fontData = IOUtils.toByteArray(fontStream);
                    baseFont = BaseFont.createFont("DFKai-SB.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, BaseFont.CACHED, fontData, null);
                    log.info("成功从字节数组加载繁体楷体");
                }
            } catch (Exception e) {
                log.warn("Classpath加载失败: {}", e.getMessage());
            }

            // 如果还是失败，使用备用字体
            if (baseFont == null) {
                log.warn("繁体楷体加载失败，使用STSong-Light");
                baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            }

            // 创建字体样式
            this.chineseFont = new Font(baseFont, CONTENT_FONT_SIZE, Font.NORMAL, TEXT_COLOR);
            this.chineseBoldFont = new Font(baseFont, CONTENT_FONT_SIZE, Font.BOLD, TEXT_COLOR);
            this.chineseTitleFont = new Font(baseFont, SECTION_TITLE_FONT_SIZE, Font.BOLD, TEXT_COLOR);
            this.chineseRedTitleFont = new Font(baseFont, MAIN_TITLE_FONT_SIZE, Font.BOLD, RED_TITLE_COLOR); // 使用主标题字号

        } catch (Exception e) {
            log.error("字体初始化失败", e);
            throw new DocumentException("字体初始化失败: " + e.getMessage());
        }
    }

    /**
     * 金额格式化
     */
    private String formatAmount(BigDecimal amount) {
        if (amount == null) return "";
        return String.format("%.2f", amount);
    }
}