package com.interplug.qcast.util;

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.utils.PdfMerger;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
public class PdfUtil {
  // HTML 템플릿 파일 경로
  //  @Value("${file.excel.template.path}")
  //  private String excelTemplateFilePath;

  /**
   * 파일 템플릿 HTML 불러오기
   *
   * @param request
   * @param templateFileName
   * @return
   * @throws IOException
   */
  public static Document getPdfDoc(HttpServletRequest request, String templateFileName)
      throws IOException {

    String templateFilePath = "template/pdf/" + templateFileName;
    InputStream templateStream =
        PdfUtil.class.getClassLoader().getResourceAsStream(templateFilePath);

    if (templateStream == null) {
      throw new FileNotFoundException("Template file not found: " + templateFilePath);
    }

    Document doc = Jsoup.parse(templateStream, StandardCharsets.UTF_8.name(), "");

    return doc;
  }

  /**
   * PDF 다운로드
   *
   * @param request
   * @param response
   * @param doc
   * @param pdfFileName 파일명
   * @param arrSection 노출 Section
   * @throws IOException
   */
  public static void pdfDownload(
      HttpServletRequest request,
      HttpServletResponse response,
      Document doc,
      String pdfFileName,
      String[] arrSection)
      throws IOException {

    // 응답에 PDF 설정
    response.setContentType("application/pdf");
    response.setHeader("Content-Disposition", "attachment; filename=\"" + pdfFileName + "\".pdf");
    response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");

    try (OutputStream os = response.getOutputStream();
        PdfWriter writer = new PdfWriter(os);
        PdfDocument pdfDoc = new PdfDocument(writer)) {

      // 폰트 설정
      ConverterProperties properties = new ConverterProperties();
      String fontPath = "template/pdf/BIZUDPGothic-Regular.ttf";
      properties.setFontProvider(setFontProvider(fontPath));

      // arrSection이 비어 있는 경우 HTML 전체를 변환
      if (arrSection == null || arrSection.length == 0) {
        // HTML 전체를 pdfDoc에 직접 변환
        HtmlConverter.convertToPdf(
            new ByteArrayInputStream(doc.html().getBytes(StandardCharsets.UTF_8)), os, properties);
        os.flush();
      } else {
        // arrSection이 있는 경우 각 섹션을 개별적으로 변환 후 병합
        String headHtml = doc.select("head").outerHtml();

        PdfMerger merger = new PdfMerger(pdfDoc);
        for (String section : arrSection) {
          if (section != null && !"".equals(section)) {
            Elements eSections = doc.select(section);
            if (eSections != null && eSections.size() > 0) {
              for (Element eSection : eSections) {

                String sectionHtml =
                    "<html>" + headHtml + "<body>" + eSection.outerHtml() + "</body></html>";

                try (ByteArrayOutputStream tempOutputStream = new ByteArrayOutputStream();
                    PdfWriter tempWriter = new PdfWriter(tempOutputStream);
                    PdfDocument tempPdfDoc = new PdfDocument(tempWriter)) {

                  HtmlConverter.convertToPdf(
                      new ByteArrayInputStream(sectionHtml.getBytes(StandardCharsets.UTF_8)),
                      tempPdfDoc,
                      properties);

                  PdfDocument tempDoc =
                      new PdfDocument(
                          new PdfReader(new ByteArrayInputStream(tempOutputStream.toByteArray())));
                  merger.merge(tempDoc, 1, tempDoc.getNumberOfPages());
                  tempDoc.close();

                  if (!eSection.equals(eSections.last())) {
                    pdfDoc.addNewPage();
                  }
                }
              }
            }
          }
        }
        pdfDoc.close();
        os.flush();
      }
    } catch (Exception e) {
      log.error("PDF 생성 중 오류 발생: " + e.getMessage(), e);
      if (!response.isCommitted()) {
        response.reset();
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "PDF 생성 중 오류가 발생했습니다.");
      }
    }
  }

  /**
   * 폰트 설정 메서드
   *
   * @param fontPath 폰트 파일 경로
   * @return 설정된 FontProvider
   */
  private static DefaultFontProvider setFontProvider(String fontPath) throws IOException {
    DefaultFontProvider fontProvider = new DefaultFontProvider(false, false, false);
    InputStream fontStream = PdfUtil.class.getClassLoader().getResourceAsStream(fontPath);

    if (fontStream != null) {
      File tempFontFile = Files.createTempFile("BIZUDPGothic-Regular", ".ttf").toFile();
      Files.copy(
          fontStream, tempFontFile.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
      fontProvider.addFont(tempFontFile.getAbsolutePath());
      fontStream.close();
      tempFontFile.deleteOnExit();
    } else {
      log.error("폰트 파일을 찾을 수 없습니다: " + fontPath);
    }
    return fontProvider;
  }
}
