<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * utility class for DTA submission plugin result display
 *
 * @package assignsubmission_dta
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class view_submission_utils {

    /**
     * Broadly used in logic, parametrized for easier change.
     */
    const COMPONENT_NAME = "assignsubmission_dta";

    /**
     * generates a short summary html
     *
     * @param int $assignmentid assignment
     * @param int $submissionid submission to create a report for
     * @return string html
     */
    public static function generatesummaryhtml(
        int $assignmentid,
        int $submissionid
    ): string {

        // Fetch data.
        $summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid);
        $html = "";

        // Calculate success rate, if no unknown result states or compilation errors.
        $successrate = "?";
        if ($summary->unknownCount() == 0 && $summary->compilationErrorCount() == 0) {
            $successrate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 );
        }

        // Generate html.
        $html .= $summary->successfulCount() . "/";
        $html .= ($summary->compilationErrorCount() == 0 && $summary->unknownCount() == 0)
            ? $summary->resultCount() . " (" . $successrate . "%)"
                : "?";
        $html .= get_string("tests_successful", self::COMPONENT_NAME) . "<br />";

        if ($summary->compilationErrorCount() > 0) {
            $html .= $summary->compilationErrorCount() . get_string("compilation_errors", self::COMPONENT_NAME) . "<br />";
        }

        if ($summary->unknownCount() > 0) {
            $html .= $summary->unknownCount() . get_string("unknown_state", self::COMPONENT_NAME) . "<br />";
        }

        $showncompetencies = explode(";", $summary->successfultestcompetencies);
        $overallcompetencies = explode(";", $summary->overalltestcompetencies);

        $tmp = "";
        for ($index = 0, $size = count($showncompetencies); $index < $size; $index++) {
            $shown = $showncompetencies[$index];
            $comp = $overallcompetencies[$index];
            // If the competency was actually assessed by the assignment and tests, add a summary entry.
            if ($shown != "0") {
                $tmp .= get_string("comp" . $index, self::COMPONENT_NAME) .
                " " . 100 * floatval($shown) / floatval($comp) . "% " . "<br />";
            }
        }

        $html .= get_string("success_competencies", self::COMPONENT_NAME) . "<br />" . $tmp . "<br />";

        return html_writer::div($html, "dtaSubmissionSummary");
    }

    /**
 * Generiert die detaillierte HTML-Ansicht, einschließlich Zusammenfassung, Kompetenzen, Details und Empfehlungen.
 *
 * @param int $assignmentid Assignment-ID
 * @param int $submissionid Submission-ID, für die der Bericht erstellt wird
 * @return string HTML-Code
 */
public static function generatedetailhtml(
    int $assignmentid,
    int $submissionid
): string {

    // HTML-Inhalt initialisieren
    $html = "";

    // Daten abrufen
    $summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid);

    // CSS-Klassen und HTML-Attributarrays definieren
    $tableheaderrowattributes = ["class" => "dtaTableHeaderRow"];
    $tablerowattributes = ["class" => "dtaTableRow"];
    $attributes = ["class" => "dtaTableData"];
    $unknownattributes = 'dtaResultUnknown';
    $successattributes = 'dtaResultSuccess';
    $failureattributes = 'dtaResultFailure';
    $compilationerrorattributes = 'dtaResultCompilationError';

    // **Zusammenfassungstabelle erstellen**
    // Kopfzeile
    $tmp = "";
    $tmp .= html_writer::tag("th", get_string("summary", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
    $tmp .= html_writer::empty_tag("th", ["class" => "dtaTableHeader"]);
    $header = html_writer::tag("tr", $tmp, $tableheaderrowattributes);
    $header = html_writer::tag("thead", $header);

    // Tabellenkörper
    $body = "";

    // Gesamtanzahl
    $tmp = "";
    $tmp .= html_writer::tag("td", get_string("total_items", self::COMPONENT_NAME), $attributes);
    $tmp .= html_writer::tag("td", $summary->resultCount(), $attributes);

    $resultrowattributes = $tablerowattributes;
    $resultrowattributes['class'] .= " " . $unknownattributes;

    $body .= html_writer::tag("tr", $tmp, $resultrowattributes);

    // Erfolgreiche Tests
    $tmp = "";
    $tmp .= html_writer::tag("td", get_string("tests_successful", self::COMPONENT_NAME), $attributes);
    $tmp .= html_writer::tag("td", $summary->successfulCount(), $attributes);

    $resultrowattributes = $tablerowattributes;
    $successrate = "?";

    if ($summary->unknownCount() > 0 || $summary->compilationErrorCount() > 0) {
        $resultrowattributes['class'] .= " " . $unknownattributes;
    } else {
        $successrate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 );
        if ($successrate < 50) {
            $resultrowattributes['class'] .= " " . $compilationerrorattributes;
        } else if ($successrate < 75) {
            $resultrowattributes['class'] .= " " . $failureattributes;
        } else {
            $resultrowattributes['class'] .= " " . $successattributes;
        }
    }
    $body .= html_writer::tag("tr", $tmp, $resultrowattributes);

    // Fehlgeschlagene Tests
    $tmp = "";
    $tmp .= html_writer::tag("td", get_string("failures", self::COMPONENT_NAME), $attributes);
    $tmp .= html_writer::tag("td", $summary->failedCount(), $attributes);

    $resultrowattributes = $tablerowattributes;
    if ($summary->failedCount() > 0) {
        $resultrowattributes['class'] .= " " . $failureattributes;
    } else {
        $resultrowattributes['class'] .= " " . $successattributes;
    }
    $body .= html_writer::tag("tr", $tmp, $resultrowattributes);

    // Kompilierungsfehler
    $tmp = "";
    $tmp .= html_writer::tag("td", get_string("compilation_errors", self::COMPONENT_NAME), $attributes);
    $tmp .= html_writer::tag("td", $summary->compilationErrorCount(), $attributes);

    $resultrowattributes = $tablerowattributes;
    if ($summary->compilationErrorCount() > 0) {
        $resultrowattributes['class'] .= " " . $compilationerrorattributes;
    } else {
        $resultrowattributes['class'] .= " " . $successattributes;
    }
    $body .= html_writer::tag("tr", $tmp, $resultrowattributes);

    // Unbekannter Status
    $tmp = "";
    $tmp .= html_writer::tag("td", get_string("unknown_state", self::COMPONENT_NAME), $attributes);
    $tmp .= html_writer::tag("td", $summary->unknownCount(), $attributes);

    $resultrowattributes = $tablerowattributes;
    if ($summary->unknownCount() > 0) {
        $resultrowattributes['class'] .= " " . $unknownattributes;
    } else {
        $resultrowattributes['class'] .= " " . $successattributes;
    }
    $body .= html_writer::tag("tr", $tmp, $resultrowattributes);

    // Erfolgsrate
    $tmp = "";
    $tmp .= html_writer::tag("td", html_writer::tag("b", get_string("success_rate", self::COMPONENT_NAME)), $attributes);
    $tmp .= html_writer::tag(
        "td",
        html_writer::tag("b", $summary->successfulCount()
            . "/" . (($summary->compilationErrorCount() == 0 && $summary->unknownCount() == 0) ? $summary->resultCount()
            . " (" . $successrate . "%)"
                : "?")),
        $attributes);

    $resultrowattributes = $tablerowattributes;
    if ($summary->unknownCount() > 0 || $summary->compilationErrorCount() > 0) {
        $resultrowattributes['class'] .= " " . $unknownattributes;
    } else {
        if ($successrate < 50) {
            $resultrowattributes['class'] .= " " . $compilationerrorattributes;
        } else if ($successrate < 75) {
            $resultrowattributes['class'] .= " " . $failureattributes;
        } else {
            $resultrowattributes['class'] .= " " . $successattributes;
        }
    }
    $body .= html_writer::tag("tr", $tmp, $resultrowattributes);

    // Tabelle zusammenstellen
    $body = html_writer::tag("tbody", $body);
    $table = html_writer::tag("table", $header . $body, ["class" => "dtaTable"]);

    $html .= $table;

    // **Abstand zwischen Tabellen**
    $html .= html_writer::empty_tag("div", ["class" => "dtaSpacer"]);

    // **Kompetenzbewertungstabelle erstellen**
    $body = "";
    $tmp = "";
    $tmp .= html_writer::tag("th", get_string("competencies", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
    $tmp .= html_writer::empty_tag("th", ["class" => "dtaTableHeader"]);
    $header = html_writer::tag("tr", $tmp, $tableheaderrowattributes);
    $header = html_writer::tag("thead", $header);

    $showncompetencies = explode(";", $summary->successfultestcompetencies);
    $overallcompetencies = explode(";", $summary->overalltestcompetencies);

    for ($index = 0, $size = count($overallcompetencies); $index < $size; $index++) {
        $comp = $overallcompetencies[$index];
        $shown = $showncompetencies[$index];
        // Kompetenz wird nur hinzugefügt, wenn sie bewertet wurde
        if ($comp != "0") {
            $resultrowattributes = $tablerowattributes;
            $tmp = "";
            $tmp .= html_writer::tag("td", get_string("comp" . $index, self::COMPONENT_NAME), $attributes);
            $tmp .= html_writer::tag("td", 100 * floatval($shown) / floatval($comp) . "% " .
                "(" . $shown . " / " . $comp . ")", $attributes);
            $tmp .= html_writer::tag("td", get_string("comp_expl" . $index, self::COMPONENT_NAME), $attributes);

            $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
        }
    }
    $body = html_writer::tag("tbody", $body);
    $html .= html_writer::tag("table", $header . $body, ["class" => "dtaTable"]);

    // **Abstand zwischen Tabellen**
    $html .= html_writer::empty_tag("div", ["class" => "dtaSpacer"]);

    // **Detailtabelle erstellen**
    $tmp = "";
    $tmp .= html_writer::tag("th", get_string("details", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
    $tmp .= html_writer::empty_tag("th", ["class" => "dtaTableHeader"]);
    $header = html_writer::tag("tr", $tmp, $tableheaderrowattributes);
    $header = html_writer::tag("thead", $header);

    $body = "";
    $spacerrow = null;
    foreach ($summary->results as $r) {
        // Abstand zwischen den Ergebnissen
        if (!is_null($spacerrow)) {
            $body .= $spacerrow;
        }

        $resultrowattributes = $tablerowattributes;

        // CSS-Klasse basierend auf dem Status des Ergebnisses hinzufügen
        if ($r->state == 0) {
            $resultrowattributes['class'] .= ' dtaResultUnknown';
        } else if ($r->state == 1) {
            $resultrowattributes['class'] .= ' dtaResultSuccess';
        } else if ($r->state == 2) {
            $resultrowattributes['class'] .= ' dtaResultFailure';
        } else if ($r->state == 3) {
            $resultrowattributes['class'] .= ' dtaResultCompilationError';
        }

        $tmp = "";
        $tmp .= html_writer::tag("td", get_string("package_name", self::COMPONENT_NAME), $attributes);
        $tmp .= html_writer::tag("td", $r->packagename, $attributes);
        $tmp .= html_writer::tag("td", get_string("unit_name", self::COMPONENT_NAME), $attributes);
        $tmp .= html_writer::tag("td", $r->classname, $attributes);
        $tmp .= html_writer::tag("td", get_string("test_name", self::COMPONENT_NAME), $attributes);
        $tmp .= html_writer::tag("td", $r->name, $attributes);
        $body .= html_writer::tag("tr", $tmp, $resultrowattributes);

        $tmp = "";
        $tmp .= html_writer::tag("td", get_string("status", self::COMPONENT_NAME), $attributes);
        $tmp .= html_writer::tag("td", DtaResult::getStateName($r->state), $attributes);
        $body .= html_writer::tag("tr", $tmp, $resultrowattributes);

        // Zusätzliche Informationen für nicht erfolgreiche Zustände
        if ($r->state != 1) {
            $tmp = "";
            $tmp .= html_writer::tag("td", get_string("failure_type", self::COMPONENT_NAME), $attributes);
            $tmp .= html_writer::tag("td", $r->failureType, $attributes);
            $body .= html_writer::tag("tr", $tmp, $resultrowattributes);

            $tmp = "";
            $tmp .= html_writer::tag("td", get_string("failure_reason", self::COMPONENT_NAME), $attributes);
            $tmp .= html_writer::tag("td", $r->failureReason, $attributes);
            $body .= html_writer::tag("tr", $tmp, $resultrowattributes);

            // Zeilennummer anzeigen, falls vorhanden
            if (!is_null($r->lineNumber) && $r->lineNumber > 0) {
                $tmp = "";
                $tmp .= html_writer::tag("td", get_string("line_no", self::COMPONENT_NAME), $attributes);
                $tmp .= html_writer::tag("td", $r->lineNumber, $attributes);
                $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
            }

            // Spaltennummer anzeigen, falls vorhanden
            if (!is_null($r->columnNumber) && $r->columnNumber > 0) {
                $tmp = "";
                $tmp .= html_writer::tag("td", get_string("col_no", self::COMPONENT_NAME), $attributes);
                $tmp .= html_writer::tag("td", $r->columnNumber, $attributes);
                $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
            }

            // Position anzeigen, falls vorhanden
            if (!is_null($r->position) && $r->position > 0) {
                $tmp = "";
                $tmp .= html_writer::tag("td", get_string("pos", self::COMPONENT_NAME), $attributes);
                $tmp .= html_writer::tag("td", $r->position, $attributes);
                $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
            }

            // Stacktrace anzeigen
            $tmp = "";
            $tmp .= html_writer::tag("td", get_string("stacktrace", self::COMPONENT_NAME), $attributes);
            $tmp .= html_writer::tag("td", html_writer::tag("details", $r->stacktrace, ["class" => "dtaStacktraceDetails"]), $attributes);
            $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
        }

        // Spacerrow für den nächsten Durchlauf setzen
        if (is_null($spacerrow)) {
            $spacerrow = html_writer::empty_tag("tr", ["class" => "dtaTableSpacer"]);
        }
    }
    $body = html_writer::tag("tbody", $body);
    $html .= html_writer::tag("table", $header . $body, ["class" => "dtaTable"]);

    // **Abstand zwischen Detailtabelle und Empfehlungstabelle**
    $html .= html_writer::empty_tag("div", ["class" => "dtaSpacer"]);

    // **Empfehlungstabelle hinzufügen**
    // Empfehlungen für die Submission abrufen
    $recommendations = DbUtils::get_recommendations_from_database($assignmentid, $submissionid);

    if (!empty($recommendations)) {
        // Überschrift für Empfehlungen
        $html .= html_writer::tag('h3', get_string('recommendations', self::COMPONENT_NAME));

        // Tabellenkopf für Empfehlungen
        $tableheader = "";
        $tableheader .= html_writer::tag("th", get_string("topic", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
        $tableheader .= html_writer::tag("th", get_string("exercise_name", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
        $tableheader .= html_writer::tag("th", get_string("url", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
        $tableheader .= html_writer::tag("th", get_string("difficulty", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
        $tableheader .= html_writer::tag("th", get_string("score", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);

        $tableheader = html_writer::tag("tr", $tableheader, ["class" => "dtaTableHeaderRow"]);
        $tableheader = html_writer::tag("thead", $tableheader);

        // Tabellenkörper für Empfehlungen
        $tablebody = "";
        foreach ($recommendations as $recommendation) {
            $tablerow = "";
            $tablerow .= html_writer::tag("td", $recommendation->topic, $attributes);
            $tablerow .= html_writer::tag("td", $recommendation->exercise_name, $attributes);
            $tablerow .= html_writer::tag("td", html_writer::link($recommendation->url, $recommendation->url), $attributes);
            $tablerow .= html_writer::tag("td", $recommendation->difficulty, $attributes);
            $tablerow .= html_writer::tag("td", $recommendation->score, $attributes);

            $tablebody .= html_writer::tag("tr", $tablerow, $tablerowattributes);
        }
        $tablebody = html_writer::tag("tbody", $tablebody);

        // Empfehlungstabelle zusammenstellen
        $html .= html_writer::tag("table", $tableheader . $tablebody, ["class" => "dtaTable"]);
    }

    // Abschließendes Div für die gesamte HTML-Ausgabe
    $html = html_writer::div($html, "dtaSubmissionDetails");

    return $html;
}


}