package com.britton.servlets;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
// import java.sql.Connection;
// import java.sql.DriverManager;
// import java.sql.SQLException;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.britton.models.MemberCardDataBean;
import com.britton.models.CardLogoBean;
import com.britton.services.IdCardsReportService;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.export.HtmlExporter;
import net.sf.jasperreports.engine.export.JRCsvExporter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRXmlExporter;
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
import net.sf.jasperreports.engine.util.JRSwapFile;
import net.sf.jasperreports.export.Exporter;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleHtmlExporterOutput;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;

public class JRIDCardsServlet
        extends HttpServlet {

    public static final int SALT_BYTES = 128 / 8;
    private static final long serialVersionUID = 1L;
    

    
    @Override
    public void init() throws ServletException {
        
        
        ServletConfig conf = getServletConfig();

    }

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws
            javax.servlet.ServletException, java.io.IOException {
        doPost(req, resp);
    }

    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws
            javax.servlet.ServletException, java.io.IOException {
        ByteArrayOutputStream baosPDF = null;
        String type = req.getParameter("FileType");
        Connection conn = null;
        try {
            if (type.equals("PDF")) {
                baosPDF = generatePDFDocumentBytes(req, this.getServletContext());
                resp.setContentType("application/pdf");
            } else {
                baosPDF = export(getJasperPrint(req, this.getServletContext(), conn), type);
                if (type.equals("HTML")) {
                    resp.setContentType("text/html");
                }
                if (type.equals("XLSX")) {
                    resp.setContentType("application/vnd.ms-excel");
                }
            }
            //Throw an exception if the Document has zero bytes
            if (baosPDF.size() == 0) {
                throw new Exception("File is empty");
            }

            StringBuffer sbFilename = new StringBuffer();
            sbFilename.append("filename_");
            sbFilename.append(System.currentTimeMillis());
            sbFilename.append(".pdf");
            resp.setHeader("Expires", "0");
            resp.setHeader("Cache-Control",
                    "must-revalidate, post-check=0, pre-check=0");

            StringBuilder sbContentDispValue = new StringBuilder();
            sbContentDispValue.append("inline");
            sbContentDispValue.append("; filename=");
            sbContentDispValue.append(sbFilename);
            resp.setHeader("Content-disposition", sbContentDispValue.toString());
            resp.setContentLength(baosPDF.size());
            ServletOutputStream sos;
            sos = resp.getOutputStream();
            baosPDF.writeTo(sos);
            sos.flush();

        } catch (Exception dex) {
            dex.printStackTrace();
            resp.setContentType("text/html");
            PrintWriter writer = resp.getWriter();
            writer.println(
                    this.getClass().getName()
                    + " caught an exception: "
                    + dex.getClass().getName()
                    + "<br>");
            writer.println("<pre>");
            dex.printStackTrace(writer);
            writer.println("</pre>");
        } finally {
            if (baosPDF != null) {
                baosPDF.reset();
            }
        }

    }

    public ByteArrayOutputStream export(final JasperPrint print, String type) throws JRException {
        final Exporter exporter;
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        boolean html = false;

        switch (type) {
            case "HTML":
                exporter = new HtmlExporter();
                exporter.setExporterOutput(new SimpleHtmlExporterOutput(out));
                html = true;
                break;

            case "CSV":
                exporter = new JRCsvExporter();
                break;

            case "XML":
                exporter = new JRXmlExporter();
                break;

            case "XLSX":
                exporter = new JRXlsxExporter();
                break;

            case "PDF":
                exporter = new JRPdfExporter();
                break;

            default:
                throw new JRException("Unknown report format: " + type);
        }

        if (!html) {
            exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(out));
        }

        exporter.setExporterInput(new SimpleExporterInput(print));
        exporter.exportReport();
        return out;
    }

    protected JasperPrint getJasperPrint(final HttpServletRequest req, final ServletContext ctx, Connection conn) throws JRException, NoSuchAlgorithmException, InvalidKeySpecException {

        String reportConn = req.getParameter("reportConn");
        String printType = req.getParameter("printType");

        String employerLogoFilename = req.getParameter("employer_logo");
        String networkLogoFilename = req.getParameter("network_logo");
        String jasperBatchId = req.getParameter("jasper_batch_id");

        String reportPath = "";
        File reportFile = null;
        HashMap<String, Object> reportParams;
        String reportParam = "";
        JasperPrint jasperPrint = null;

        try {
                Class.forName("net.sourceforge.jtds.jdbc.Driver");
                if (conn != null) {
                    conn.close();
                }
                conn = DriverManager.getConnection("jdbc:jtds:sqlserver://10.41.82.73:1433/BrittonConnect", "SA", "Adm1nBb5");

        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }

        reportParams = new HashMap<String, Object>();
        
        reportPath = this.getServletConfig().getServletContext().
                getRealPath("/reports/idcards");
        reportParams.put("baseDir", reportPath);

        reportFile = new File(reportPath + "/" + printType + ".jasper");
        

        for (Enumeration e = req.getParameterNames(); e.hasMoreElements();) {
            reportParam = (String) e.nextElement();
            reportParams.put(reportParam, req.getParameter(reportParam));
        }

        // employerLogoFilename = (employerLogoFilename == null) ? "imageB.png" : employerLogoFilename;
        // try {
        //     String sql = "SELECT * FROM id_card_employer_logos WHERE filename = ?";
        //     PreparedStatement pstmt = conn.prepareStatement(sql);
        //     pstmt.setString(1, employerLogoFilename);
        //     ResultSet rs = pstmt.executeQuery();

        //     if (rs.next()) {
        //         Blob employerBlob = rs.getBlob("image_data");
        //         InputStream employerStream = employerBlob.getBinaryStream();

        //         reportParams.put("employer_logo", employerStream);
                
        //         float aspect_ratio = rs.getFloat("aspect_ratio");
        //         reportParams.put("employer_logo_ar", aspect_ratio);
        //     }
        // } catch (Exception e) {
        //     e.printStackTrace();
        // }

        // networkLogoFilename = (networkLogoFilename == null) ? "CignaLogo.png" : networkLogoFilename;
        // if (networkLogoFilename != null) {
        //     try {
        //         String sql = "SELECT * FROM id_card_network_logos WHERE filename = ?";
        //         PreparedStatement pstmt = conn.prepareStatement(sql);
        //         pstmt.setString(1, networkLogoFilename);
        //         ResultSet rs = pstmt.executeQuery();

        //         if (rs.next()) {
        //             Blob networkBlob = rs.getBlob("image_data");
        //             InputStream networkStream = networkBlob.getBinaryStream();

        //             reportParams.put("network_logo", networkStream);
        //         }
        //     } catch (Exception e) {
        //         e.printStackTrace();
        //     }
        // }

        List<MemberCardDataBean> memberCardsDataList = IdCardsReportService.getMemberCardData(conn, jasperBatchId);
        System.out.println("-before collection: " + memberCardsDataList.size());
        // List<MemberCardDataBean> memberCardsDataList = new ArrayList<MemberCardDataBean>();
        // if (jasperBatchId != null) {
        //     memberCardsDataList = IdCardsReportService.getMemberCardData(conn, jasperBatchId);
        // }
        List<CardLogoBean> employerLogosList = IdCardsReportService.getEmployerLogoImages(conn, memberCardsDataList);
        List<CardLogoBean> networkLogosList = IdCardsReportService.getNetworkLogoImages(conn, memberCardsDataList);
        // JRBeanCollectionDataSource cardLogosDataSource = new JRBeanCollectionDataSource(cardLogosList);
        reportParams.put("employerLogosList", employerLogosList);
        reportParams.put("networkLogosList", networkLogosList);
        JRBeanCollectionDataSource memberCardsDataSource = new JRBeanCollectionDataSource(memberCardsDataList);

        jasperPrint = JasperFillManager.fillReport(reportFile.getPath(), reportParams, memberCardsDataSource);
        // jasperPrint = JasperFillManager.fillReport(reportFile.getPath(), reportParams, conn);

        return jasperPrint;
    }

    protected ByteArrayOutputStream generatePDFDocumentBytes(
            final HttpServletRequest req,
            final ServletContext ctx) throws Exception {
        ByteArrayOutputStream baosPDF = new ByteArrayOutputStream();
        Connection conn = null;
        JasperPrint jasperPrint = null;
        try {
            jasperPrint = getJasperPrint(req, this.getServletContext(), conn);

            JasperExportManager.exportReportToPdfStream(jasperPrint, baosPDF);
        } catch (Exception dex) {
            baosPDF.reset();
            dex.printStackTrace();
            throw dex;
        } finally {
            if (conn != null) {
                try {
                    if (!conn.isClosed()) {
                        conn.close();
                    }
                } catch (Exception E) {
                }
            }
        }
        return baosPDF;
    }

    public static void main(String[] args) {
        JRIDCardsServlet t = new JRIDCardsServlet();
        try {
            //AQAAAAEAACcQAAAAEIArrQZKcMTdqJzn2PxPOimXDIJds0lQTO8lbMXHXDfAwUyY9ZcFitc6iNircMfM2g==
            getHash("Logath1925;");
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        } catch (InvalidKeySpecException ex) {
            ex.printStackTrace();
        }
    }

    private static String getHash(String text) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] bytes = {0x35, 0x24, 0x76, 0x12};
        MessageDigest m = MessageDigest.getInstance("MD5");
        byte[] digest = m.digest(bytes);
        String hash = new BigInteger(1, digest).toString(16);
        return hash;
    }

    // public List<IdCardDataBean> getReportData(Connection conn, String jasperBatchId) throws Exception {
    //     List<IdCardDataBean> cardData = new ArrayList<>();
    //     String sql = "SELECT * FROM id_card_print_data WHERE jasper_batch_id = ?";
    //     PreparedStatement pstmt = conn.prepareStatement(sql);
    //     pstmt.setString(1, jasperBatchId);
        
    //     try (ResultSet rs = pstmt.executeQuery()) {
            
    //         while (rs.next()) {

    //             IdCardDataBean icd = IdCardDataBean.builder()
    //                 .employer_name(rs.getString("employer_name"))
    //                 .group_number(rs.getString("group_number"))
    //                 .primary_mb_member_key(rs.getString("primary_mb_member_key"))
    //                 .family_id(rs.getString("family_id"))
    //                 .full_name(rs.getString("full_name"))
    //                 .rx_group(rs.getString("rx_group"))
    //                 .medical_eff_date(rs.getString("medical_eff_date"))
    //                 .network_provider(rs.getString("network_provider"))
    //                 .provider_line_1(rs.getString("provider_line_1"))
    //                 .provider_line_2(rs.getString("provider_line_2"))
    //                 .provider_line_3(rs.getString("provider_line_3"))
    //                 .provider_line_4(rs.getString("provider_line_4"))
    //                 .provider_line_5(rs.getString("provider_line_5"))
    //                 .provider_line_6(rs.getString("provider_line_6"))
    //                 .provider_line_7(rs.getString("provider_line_7"))
    //                 .provider_line_8(rs.getString("provider_line_8"))
    //                 .provider_line_9(rs.getString("provider_line_9"))
    //                 .provider_line_10(rs.getString("provider_line_10"))
    //                 .provider_line_11(rs.getString("provider_line_11"))
    //                 .provider_line_12(rs.getString("provider_line_12"))
    //                 .claim_to_1(rs.getString("claim_to_1"))
    //                 .claim_to_2(rs.getString("claim_to_2"))
    //                 .claim_to_3(rs.getString("claim_to_3"))
    //                 .claim_to_4(rs.getString("claim_to_4"))
    //                 .claim_to_5(rs.getString("claim_to_5"))
    //                 .claim_to_6(rs.getString("claim_to_6"))
    //                 .claim_to_7(rs.getString("claim_to_7"))
    //                 .claim_to_8(rs.getString("claim_to_8"))
    //                 .claim_to_9(rs.getString("claim_to_9"))
    //                 .claim_to_10(rs.getString("claim_to_10"))
    //                 .claim_to_11(rs.getString("claim_to_11"))
    //                 .claim_to_12(rs.getString("claim_to_12"))
    //                 .customer_service(rs.getString("customer_service"))
    //                 .web_url(rs.getString("web_url"))
    //                 .dependent_1(rs.getString("dependent_1"))
    //                 .dependent_2(rs.getString("dependent_2"))
    //                 .dependent_3(rs.getString("dependent_3"))
    //                 .dependent_4(rs.getString("dependent_4"))
    //                 .dependent_5(rs.getString("dependent_5"))
    //                 .dependent_6(rs.getString("dependent_6"))
    //                 .dependent_7(rs.getString("dependent_7"))
    //                 .dependent_8(rs.getString("dependent_8"))
    //                 .benefit_desc_1(rs.getString("benefit_desc_1"))
    //                 .benefit_1(rs.getString("benefit_1"))
    //                 .benefit_desc_2(rs.getString("benefit_desc_2"))
    //                 .benefit_2(rs.getString("benefit_2"))
    //                 .benefit_desc_2(rs.getString("benefit_desc_2"))
    //                 .benefit_2(rs.getString("benefit_2"))
    //                 .benefit_desc_3(rs.getString("benefit_desc_3"))
    //                 .benefit_3(rs.getString("benefit_3"))
    //                 .benefit_desc_4(rs.getString("benefit_desc_4"))
    //                 .benefit_4(rs.getString("benefit_4"))
    //                 .benefit_desc_5(rs.getString("benefit_desc_5"))
    //                 .benefit_5(rs.getString("benefit_5"))
    //                 .benefit_desc_6(rs.getString("benefit_desc_6"))
    //                 .benefit_6(rs.getString("benefit_6"))
    //                 .benefit_desc_7(rs.getString("benefit_desc_7"))
    //                 .benefit_7(rs.getString("benefit_7"))
    //                 .benefit_desc_8(rs.getString("benefit_desc_8"))
    //                 .benefit_8(rs.getString("benefit_8"))
    //                 .benefit_desc_9(rs.getString("benefit_desc_9"))
    //                 .benefit_9(rs.getString("benefit_9"))
    //                 .benefit_desc_10(rs.getString("benefit_desc_10"))
    //                 .benefit_10(rs.getString("benefit_10"))
    //                 .benefit_desc_11(rs.getString("benefit_desc_11"))
    //                 .benefit_11(rs.getString("benefit_11"))
    //                 .benefit_desc_12(rs.getString("benefit_desc_12"))
    //                 .benefit_12(rs.getString("benefit_12"))
    //                 .benefit_desc_13(rs.getString("benefit_desc_13"))
    //                 .benefit_13(rs.getString("benefit_13"))
    //                 .benefit_desc_14(rs.getString("benefit_desc_14"))
    //                 .benefit_14(rs.getString("benefit_14"))
    //                 .jasper_batch_id(rs.getString("jasper_batch_id"))
    //                 .build();
    //             cardData.add(icd);
    //         }
    //     }
    //     return cardData;
    // }

}
