package org.commcare.print;

import org.commcare.cases.entity.Entity;
import org.commcare.graph.model.GraphData;
import org.commcare.graph.util.GraphException;
import org.commcare.suite.model.DetailField;
import org.commcare.util.DetailFieldPrintInfo;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import java.io.Serializable;

/**
 * Represents a single DetailField whose information may be used to populate a placeholder in a
 * print template for a Detail
 *
 * Created by amstone326 on 3/2/17.
 */
public class PrintableDetailField implements Serializable {

    private static final int GRAPH_WIDTH = 750;
    private static final int GRAPH_HEIGHT = 375;

    private String valueString;
    private String fieldForm;

    public PrintableDetailField(DetailFieldPrintInfo printInfo) {
        DetailField field = printInfo.field;
        Entity entity = printInfo.entity;
        int fieldIndex = printInfo.index;

        this.fieldForm = field.getTemplateForm();
        String fieldAsString = entity.getFieldString(fieldIndex);
        if ("".equals(fieldAsString) || fieldAsString == null) {
            // this field can't be automatically represented as a string
            if (isGraphDetailField()) {
                parseGraphPrintData(entity, field, fieldIndex);
            } else {
                // this field is of some other form for which printing is currently not supported
                this.valueString = "";
            }
        } else {
            this.valueString = fieldAsString;
        }
    }

    private void parseGraphPrintData(Entity entity, DetailField field, int fieldIndex) {
        try {
            Object evaluatedField = entity.getField(fieldIndex);
            String graphTitle = field.getHeader().evaluate();
            if ("".equals(graphTitle) || graphTitle == null) {
                // DO NOT CHANGE THIS -- Workaround to address the fact that a graph will not
                // render properly if the 'chart-title' <div> is empty
                graphTitle = " ";
            }
            String fullGraphHtml = ((GraphData)evaluatedField).getGraphHTML(graphTitle);
            this.valueString = fullGraphHtml;
        } catch (GraphException e) {
            this.valueString = "<p>ERROR ENCOUNTERED WHILE TRYING TO PRINT GRAPH</p>";
        }
    }

    public String getFormattedValueString() {
        if (isGraphDetailField()) {
            return createIframeForGraphHtml(valueString);
        } else {
            // Replace any ascii new line characters generated by HQ with html break tag
            return valueString.replaceAll("\\x0A", "<br>");
        }
    }

    private static String createIframeForGraphHtml(String fullGraphHtml) {
        return "<iframe srcdoc=\""
                + scrubHtmlStringForUseAsAttribute(addStyleAttributes(fullGraphHtml))
                + "\" height=\"" + GRAPH_HEIGHT + "\" width=\"" + GRAPH_WIDTH + "\"></iframe>";
    }

    private static String scrubHtmlStringForUseAsAttribute(String htmlString) {
        return htmlString.replace("\"", "\'");
    }

    private static String addStyleAttributes(String htmlString) {
        Document graphDoc = Jsoup.parse(htmlString);
        Element htmlNode = graphDoc.getElementsByTag("html").get(0);
        htmlNode.attr("style", "height: 100%");
        Element bodyNode = graphDoc.getElementsByTag("body").get(0);
        bodyNode.attr("style", "height: 90%; margin:0;");
        return graphDoc.html();
    }

    public boolean isGraphDetailField() {
        return "graph".equals(fieldForm);
    }

    public boolean isPrintSupported() {
        return !"".equals(valueString);
    }

}

@@ -2280,62 +2280,69 @@
 g = 
+String.format(
 %22%3Cp%3E
+AN 
 ERROR 
-ENCOUNTERED WHILE TRYING TO PRINT GRAPH%3C/p%3E%22
+OCCURRED: %25s%3C/p%3E%22, e.getMessage())
 ;%0A  

add exception message to error value