package com.mvrent.carrental.service;

import com.lowagie.text.pdf.BaseFont;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring6.SpringTemplateEngine;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Map;

/**
 * Renders a Thymeleaf template (strict XHTML under templates/pdf/) to a PDF
 * byte array via Flying Saucer. A configurable TTF font (containing the ₹ glyph)
 * is embedded so currency renders correctly.
 */
@Service
@Slf4j
public class PdfService {

    private final SpringTemplateEngine templateEngine;
    private final ResourceLoader resourceLoader;
    private final String fontLocation;
    private final String currencySymbol;

    /** Absolute path to a usable font file, or null if none configured/available. */
    private String fontPath;

    public PdfService(SpringTemplateEngine templateEngine,
                      ResourceLoader resourceLoader,
                      @Value("${app.pdf.font:}") String fontLocation,
                      @Value("${app.currency.symbol}") String currencySymbol) {
        this.templateEngine = templateEngine;
        this.resourceLoader = resourceLoader;
        this.fontLocation = fontLocation;
        this.currencySymbol = currencySymbol;
    }

    @PostConstruct
    void resolveFont() {
        if (fontLocation == null || fontLocation.isBlank()) return;
        try {
            Resource res = resourceLoader.getResource(fontLocation);
            if (!res.exists()) {
                log.warn("PDF font not found at {} — currency will use a fallback glyph", fontLocation);
                return;
            }
            // Copy to a temp file so it works whether running from disk or inside a jar.
            File tmp = File.createTempFile("pdf-font-", ".ttf");
            tmp.deleteOnExit();
            try (InputStream in = res.getInputStream()) {
                Files.copy(in, tmp.toPath(), StandardCopyOption.REPLACE_EXISTING);
            }
            this.fontPath = tmp.getAbsolutePath();
            log.info("PDF font registered from {}", fontLocation);
        } catch (Exception e) {
            log.warn("Failed to load PDF font {}: {}", fontLocation, e.getMessage());
        }
    }

    public byte[] render(String template, Map<String, Object> vars) {
        Context ctx = new Context();
        ctx.setVariables(vars);
        ctx.setVariable("currencySymbol", currencySymbol);
        String html = templateEngine.process(template, ctx);
        try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
            ITextRenderer renderer = new ITextRenderer();
            if (fontPath != null) {
                renderer.getFontResolver().addFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            }
            renderer.setDocumentFromString(html);
            renderer.layout();
            renderer.createPDF(os);
            return os.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("Failed to render PDF (" + template + "): " + e.getMessage(), e);
        }
    }
}
