package com.utopiaindustries.util;

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

@Component
public class PDFResponseEntityInputStreamResource {

    /**
     * prepare pdf document from html string
     */
    private ResponseEntity<InputStreamResource> createPDFResponseEntityInputStreamResource( String htmlStr, String filename, String method ) throws IOException {
        // output stream
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        // converter properties
        ConverterProperties properties = new ConverterProperties();
        properties.setFontProvider( new DefaultFontProvider( false, false, true ) );
        // pdf document
        PdfWriter writer = new PdfWriter( outputStream );
        //temp Code
/*		PdfDocument temp = new PdfDocument(writer);
		Rectangle rectangle3x5 = new Rectangle(216, 360);
		PageSize pageSize =new PageSize( rectangle3x5 );
		temp.setDefaultPageSize( pageSize);
		properties.setTagWorkerFactory( new CustomTagWorkerFactory() );*/
        //temp code end
        Document document = HtmlConverter.convertToDocument( htmlStr, writer, properties );
        document.close();
        // input stream
        ByteArrayInputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() );
        // content disposition header
        String headerContentDispositionStr = String.format( "%s; filename=%s.pdf", method, filename.replaceAll( ",", "-" ) );
        // return response
        return ResponseEntity
                .ok()
                .header( HttpHeaders.CONTENT_DISPOSITION, headerContentDispositionStr )
                .contentType( MediaType.APPLICATION_PDF )
                .body( new InputStreamResource( inputStream ) );
    }

    /**
     * prepare pdf document from html string
     */
    private ResponseEntity<InputStreamResource> createPDFResponseEntityInvoiceInputStreamResource( String htmlStr, String filename, String method, long height, long width )
            throws IOException {
        // output stream
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        // converter properties
        ConverterProperties properties = new ConverterProperties();
        properties.setFontProvider( new DefaultFontProvider( false, true, false ) );
        // pdf document
        PdfWriter writer = new PdfWriter( outputStream );
        //Code for invoice slips
        PdfDocument temp = new PdfDocument( writer );
        Rectangle rectangle3x5 = new Rectangle( width, height );
        PageSize pageSize = new PageSize( rectangle3x5 );
        temp.setDefaultPageSize( pageSize );
        properties.setTagWorkerFactory( new CustomTagWorkerFactory() );
        //temp code end
        Document document = HtmlConverter.convertToDocument( htmlStr, temp, properties );
        //document.setFontSize( 200.0f );
        document.close();
        // input stream
        ByteArrayInputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() );
        // content disposition header
        String headerContentDispositionStr = String.format( "%s; filename=%s.pdf", method, filename.replaceAll( ",", "-" ) );
        // return response
        return ResponseEntity
                .ok()
                .header( HttpHeaders.CONTENT_DISPOSITION, headerContentDispositionStr )
                .contentType( MediaType.APPLICATION_PDF )
                .body( new InputStreamResource( inputStream ) );
    }

    /**
     * with inline as default content disposition "inline"
     */
    public ResponseEntity<InputStreamResource> generatePdf( String htmlStr, String filename ) throws IOException {
        return this.createPDFResponseEntityInputStreamResource( htmlStr, filename, "inline" );
    }

    /**
     * manual content disposition
     */
    public ResponseEntity<InputStreamResource> generatePdf( String htmlStr, String filename, String method ) throws IOException {
        return this.createPDFResponseEntityInputStreamResource( htmlStr, filename, method );
    }

    /**
     * manual content disposition
     */
    public ResponseEntity<InputStreamResource> generateInvoicePdf( String htmlStr, String filename, String method, long height, long width ) throws IOException {
        return this.createPDFResponseEntityInvoiceInputStreamResource( htmlStr, filename, method, height, width );
    }
}