package com.capgemini.reports.formatting;

import com.capgemini.framework.common.SettingsHelper;
import com.capgemini.framework.common.StringHelper;
import com.capgemini.reports.database.manager.MngReport;
import com.capgemini.reports.database.manager.MngReport.RunningReportEntry;
import com.capgemini.reports.exceptions.InvalidInputException;
import com.capgemini.reports.exceptions.NothingToBeShownException;
import org.hibernate.Session;

import java.util.List;

/** This class can generate an html page showing every reports currently running or waiting to be executed that are owned by the logged-in user. */
public class MyReports extends AbstractTableFormatter {
    // User input
    private final String thePageParamStr;

    // Last entries: to be put in additional Tags
    private String paging;
    private long reportCount;
    private final String theUserLogin;

    private static final String BUTTON_END = "</BUTTON>";

    /**
     * Create the some user's 'My Reports' page, passing the page number to be shown as (String) parameter.
     * 
     * @param thePageParamStr the page number
     * @param userLogin the login of the user who wants to know the status of his reports
     */
    public MyReports(final String thePageParamStr, final String userLogin) {
        super();
        this.thePageParamStr = thePageParamStr;
        this.theUserLogin = userLogin == null ? "Invité(e)" : userLogin;
    }

    @Override
    protected String makeTable(Session session) throws InvalidInputException {
        // Prepare data
        MngReport theMngRep = new MngReport();
        this.reportCount = theMngRep.countUserReports(session, theUserLogin);
        int thePageParam = obtainIntegerPageParam(thePageParamStr);
        long pageCount = pageCount(reportCount);

        StringBuilder theTableJsCode = new StringBuilder("var reportArray = new Array();\n");

        // Access the user reports for the current page
        int theLineCount = 0;
        List<RunningReportEntry> theUserReports = theMngRep.searchUserReports(session, theUserLogin, thePageParam);
        if (theUserReports.isEmpty()) {
            throw new NothingToBeShownException("No previous report executions", "Aucun rapport executé");
        }

        for (RunningReportEntry currentReport : theUserReports) {
            String table = "\treportArray[" + theLineCount + "]";
            theTableJsCode.append(StringHelper.toJs(table, currentReport.getReport()));
            theTableJsCode.append(table).append("['requestDate'] = '").append(currentReport.getRequestDate()).append("';");
            theLineCount++;
        }

        // Additional tags preparation
        paging = makePaging(thePageParam, pageCount);

        return theTableJsCode.toString();
    }

    protected static int obtainIntegerPageParam(final String thePageParamStr) throws InvalidInputException {
        if (thePageParamStr != null) {
            try {
                return Integer.parseInt(thePageParamStr);
            } catch (NumberFormatException e) {
                throw new InvalidInputException("Num&eacute;ro de page incorrect", e);
            }
        }
        return 1;
    }

    protected static long pageCount(final long theUserReportCount) {
        int theMaxPageSize = SettingsHelper.getJspPaging();
        return (theUserReportCount - 1) / theMaxPageSize + 1; // Integer division
    }

    protected static String makePaging(final int thePageParam, final long theLastPage) {
        /* Manage page browsing */
        StringBuilder thePaging = new StringBuilder();
        if (theLastPage > 1) {
            for (int i = 1; i <= theLastPage; i++) {
                if (thePaging.length() > 0) {
                    thePaging.append(" - ");
                } else {
                    thePaging.append("<div width=\"90%\" style=\"border-bottom:3px double #EEEEFF;margin-bottom:3px;\"/>&nbsp;</div><b>Pages:</b> ");
                }

                if (i != thePageParam) {
                    thePaging
                            .append("<BUTTON class=\"formButton\" style=\"color:#333355;border:1px solid #333355;width:28px;padding:1px;\" onclick=\"GoPage(")
                            .append(i).append(")\">").append(i).append(BUTTON_END);
                } else {
                    thePaging.append("<BUTTON class=\"formButton\" style=\"color:#22AA22;border:1px solid #338833;width:28px;padding:1px;\">")
                            .append(i).append(BUTTON_END);
                }
            }
        }
        return thePaging.toString();
    }

    @Override
    protected String successPageTemplateLocation() {
        return "/html/myReports/my_reports_success.html";
    }

    @Override
    protected String failedPageTemplateLocation() {
        return "/html/myReports/my_reports_failed.html";
    }

    @Override
    protected void addOptionalTags(Session session) {
        this.setTagValue("PAGING", paging == null ? "" : paging);
        addUserTags();
    }

    @Override
    protected void addOptionalErrorTags() {
        addUserTags();
    }

    private void addUserTags() {
        this.setTagValue("USER_LOGIN", theUserLogin == null ? "" : theUserLogin);
        this.setTagValue("USER_REPORT_COUNT", Long.toString(reportCount));
    }

}
