package com.njcn.gather.comservice.filepreview;

import cn.hutool.core.util.StrUtil;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.util.HtmlUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

/**
 * 公共文件预览服务，统一处理报告模板相关预览内容转换。
 */
@Component
public class FilePreviewService {

    private static final String PDF_EXTENSION = ".pdf";
    private static final String DOC_EXTENSION = ".doc";
    private static final String DOCX_EXTENSION = ".docx";
    private static final String HTML_CONTENT_TYPE = MediaType.TEXT_HTML_VALUE + ";charset=UTF-8";

    public PreviewContent preview(Path filePath, String fileName) {
        String extension = resolveExtension(fileName);
        try {
            if (PDF_EXTENSION.equals(extension)) {
                return new PreviewContent(MediaType.APPLICATION_PDF_VALUE, Files.readAllBytes(filePath));
            }
            if (DOCX_EXTENSION.equals(extension)) {
                return buildHtmlPreview(extractDocxText(filePath));
            }
            if (DOC_EXTENSION.equals(extension)) {
                return buildHtmlPreview(extractDocText(filePath));
            }
            throw new IllegalArgumentException("仅支持预览 .docx、.doc、.pdf 文件");
        } catch (IOException exception) {
            throw new IllegalArgumentException("读取文件预览内容失败", exception);
        }
    }

    private PreviewContent buildHtmlPreview(String text) {
        String[] lines = StrUtil.nullToEmpty(text).replace("\r\n", "\n").replace('\r', '\n').split("\n");
        StringBuilder htmlBuilder = new StringBuilder(256);
        htmlBuilder.append("<!DOCTYPE html><html><head><meta charset=\"UTF-8\">")
                .append("<title>文件预览</title>")
                .append("<style>")
                .append("body{margin:0;padding:24px;background:#f5f7fa;color:#1f2329;font:14px/1.7 'Microsoft YaHei',sans-serif;}")
                .append(".preview{max-width:960px;margin:0 auto;padding:24px;background:#fff;border-radius:8px;box-shadow:0 4px 16px rgba(31,35,41,.08);}")
                .append("p{margin:0 0 12px;white-space:pre-wrap;word-break:break-word;}")
                .append("</style></head><body><div class=\"preview\">");
        if (lines.length == 1 && StrUtil.isBlank(lines[0])) {
            htmlBuilder.append("<p>文件内容为空</p>");
        } else {
            for (String line : lines) {
                if (StrUtil.isBlank(line)) {
                    htmlBuilder.append("<p>&nbsp;</p>");
                } else {
                    htmlBuilder.append("<p>").append(HtmlUtils.htmlEscape(line)).append("</p>");
                }
            }
        }
        htmlBuilder.append("</div></body></html>");
        return new PreviewContent(HTML_CONTENT_TYPE, htmlBuilder.toString().getBytes(StandardCharsets.UTF_8));
    }

    private String extractDocxText(Path filePath) throws IOException {
        try (XWPFDocument document = new XWPFDocument(Files.newInputStream(filePath));
             XWPFWordExtractor extractor = new XWPFWordExtractor(document)) {
            return extractor.getText();
        }
    }

    private String extractDocText(Path filePath) throws IOException {
        try (HWPFDocument document = new HWPFDocument(Files.newInputStream(filePath));
             WordExtractor extractor = new WordExtractor(document)) {
            return extractor.getText();
        }
    }

    private String resolveExtension(String fileName) {
        String normalized = StrUtil.nullToEmpty(fileName).trim().toLowerCase();
        if (normalized.endsWith(DOCX_EXTENSION)) {
            return DOCX_EXTENSION;
        }
        if (normalized.endsWith(DOC_EXTENSION)) {
            return DOC_EXTENSION;
        }
        if (normalized.endsWith(PDF_EXTENSION)) {
            return PDF_EXTENSION;
        }
        return "";
    }

    public static class PreviewContent {
        private final String contentType;
        private final byte[] content;

        public PreviewContent(String contentType, byte[] content) {
            this.contentType = contentType;
            this.content = content;
        }

        public String getContentType() {
            return contentType;
        }

        public byte[] getContent() {
            return content;
        }
    }
}
