<?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/>.

/**
 * Simulatore contabilità
 *
 * @package    mod_mtcontabilita
 * @copyright  2026 Mediatouch 2000 Srl <https://www.mediatouch.it>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @author     Marco Cappuccio <m.cappuccio@mediatouch.it>
 */

use mod_mtcontabilita\mtcontabilita_attempt;

defined('MOODLE_INTERNAL') || die();

/**
 * get_user.
 */
function mtcontabilita_get_user_attempt_unfinished($mtcontabilitaid, $userid) {
    $attempts = mtcontabilita_get_user_attempts($mtcontabilitaid, $userid, 'unfinished', true);
    if ($attempts) {
        return array_shift($attempts);
    } else {
        return false;
    }
}

/**
 * attempt
 */
function mtcontabilita_attempt_save_started($mtcontabilita, $mtcontabilitaobj) {
    global $DB, $USER;

    $adesso = time();
    $attempt = new stdClass();

    if ($numattempt = $DB->get_field('mtcontabilita_attempts', 'MAX(attempt)', ['userid' => $USER->id, 'mtcontabilitaid' => $mtcontabilita->id])) {
        $attempt->attempt = $numattempt + 1;
    } else {
        $attempt->attempt = 1;
    }

    $attempt->mtcontabilitaid = $mtcontabilita->id;
    $attempt->userid = $USER->id;
    $attempt->currentpage = $mtcontabilita->binit ? 0 : 1;
    $attempt->state = mtcontabilita_attempt::IN_PROGRESS;
    $attempt->timestart = $adesso;
    $attempt->timemodified = $adesso;
    $attempt->scoretot = 0;

    $attempt->id = $DB->insert_record('mtcontabilita_attempts', $attempt);

    $attemptdb = $DB->get_record('mtcontabilita_attempts', ['id' => $attempt->id], '*', MUST_EXIST);
    // Params used by the events below.
    $params = [
        'objectid' => $attempt->id,
        'relateduserid' => $attempt->userid,
        'courseid' => $mtcontabilitaobj->course->id,
        'context' => $mtcontabilitaobj->context,
    ];
    // Decide which event we are using.
    $event = \mod_mtcontabilita\event\attempt_started::create($params);
    $event->add_record_snapshot('mtcontabilita_attempts', $attemptdb);
    $event->trigger();

    return $attempt;
}

/**
 * start
 */
function mtcontabilita_start_new_attempt($mtcontabilitaobj, $quba, $attempt, $attemptnumber, $timenow,
                                $questionids = [], $forcedvariantsbyslot = []) {

    $attempt->mtcontabilitaid = $mtcontabilitaobj->id;
    return $attempt;
}

/**
 * Creates an object to represent a new attempt at a mtcontabilita
 *
 * Creates an attempt object to represent an attempt at the mtcontabilita by the current
 * user starting at the current time. The ->id field is not set. The object is
 * NOT written to the database.
 *
 * @param mtcontabilita_settings $mtcontabilitaobj the mtcontabilita object to create an attempt for.
 * @param int $attemptnumber the sequence number for the attempt.
 * @param stdClass|false $lastattempt the previous attempt by this user, if any. Only needed
 *         if $attemptnumber > 1 and $mtcontabilita->attemptonlast is true.
 * @param int $timenow the time the attempt was started at.
 * @param int|null $userid  the id of the user attempting this mtcontabilita.
 *
 * @return stdClass the newly created attempt object.
 */
function mtcontabilita_create_attempt($mtcontabilitaobj, $attemptnumber, $lastattempt, $timenow, $userid = null) {
    global $USER;

    if ($userid === null) {
        $userid = $USER->id;
    }

    if ($attemptnumber == 1 || !$mtcontabilitaobj->attemptonlast) {
        // We are not building on last attempt so create a new attempt.
        $attempt = new stdClass();
        $attempt->mtcontabilita = $mtcontabilitaobj->id;
        $attempt->userid = $userid;
        $attempt->layout = '';
    } else {
        // Build on last attempt.
        if (empty($lastattempt)) {
            throw new \moodle_exception('cannotfindprevattempt', 'mtcontabilita');
        }
        $attempt = $lastattempt;
    }

    $attempt->attempt = $attemptnumber;
    $attempt->timestart = $timenow;
    $attempt->timefinish = 0;
    $attempt->timemodified = $timenow;
    $attempt->timemodifiedoffline = 0;
    $attempt->state = mtcontabilita_attempt::IN_PROGRESS;
    $attempt->currentpage = 0;
    $attempt->sumgrades = null;
    $attempt->gradednotificationsenttime = null;

    return $attempt;
}

/**
 * validate.
 */
function mtcontabilita_validate_new_attempt($mtcontabilitaobj, $forcenew, $page, $redirect) {
    global $DB, $USER;
    // Check capabilities.
    require_capability('mod/mtcontabilita:attempt', $mtcontabilitaobj->context);
    $attemptnumber = null;
    // Se nuovo tentativo. metto abbandonato se non è finito.
    if ($forcenew) {
        $attemptid = $DB->get_field('mtcontabilita_attempts', 'MAX(id)', ['mtcontabilitaid' => $mtcontabilitaobj->mtcontabilitaid, 'userid' => $USER->id]);
        $state = $DB->get_field('mtcontabilita_attempts', 'state', ['id' => $attemptid]);
        if ($state == mtcontabilita_attempt::IN_PROGRESS) {
            $DB->set_field('mtcontabilita_attempts', 'state', mtcontabilita_attempt::ABANDONED, ['id' => $attemptid]);
        }
        $mtcontabilitaobj->attemptonlast = false;
    }
    // Look for an existing attempt.
    $attempts = mtcontabilita_get_user_attempts($mtcontabilitaobj->id, $USER->id, 'all', true);
    $lastattempt = end($attempts);
    // echo __FILE__.__LINE__;var_dump($lastattempt); die();
    // If an in-progress attempt exists, check password then redirect to it.
    if ($lastattempt && ($lastattempt->state == mtcontabilita_attempt::IN_PROGRESS || $lastattempt->state == mtcontabilita_attempt::OVERDUE)) {
        $currentattemptid = $lastattempt->id;
        $messages = [];
        // If the attempt is now overdue, deal with that.
        $mtc = new mtcontabilita_attempt($lastattempt, $mtcontabilitaobj, $mtcontabilitaobj->cm, $mtcontabilitaobj->course);
        // And, if the attempt is now no longer in progress, redirect to the appropriate place.
        if ($lastattempt->state == mtcontabilita_attempt::ABANDONED || $lastattempt->state == mtcontabilita_attempt::FINISHED) {
            if ($redirect) {
                redirect($mtcontabilitaobj->review_url($lastattempt->id));
            } else {
                throw new moodle_exception('attemptalreadyclosed', 'mtcontabilita', $mtcontabilitaobj->view_url());
            }
        }
    } else {
        // L'ultimo tentativo NON è riprendibile: preparo il numero del prossimo tentativo.
        $currentattemptid = null;

        if ($lastattempt) {
            $attemptnumber = $lastattempt->attempt + 1;
        } else {
            $lastattempt = false;
            $attemptnumber = 1;
        }

        $messages = [];

        if ($page == -1) {
            $page = 0;
        }
    }

    return [$currentattemptid, $attemptnumber, $lastattempt, $messages, $page];
}

/**
 * Return a textual summary of the number of attempts that have been made at a particular mtcontabilita,
 * returns '' if no attempts have been made yet, unless $returnzero is passed as true.
 *
 * @param stdClass $mtcontabilita the mtcontabilita object. Only $mtcontabilita->id is used at the moment.
 * @param stdClass $cm the cm object. Only $cm->course, $cm->groupmode and
 *      $cm->groupingid fields are used at the moment.
 * @param bool $returnzero if false (default), when no attempts have been
 *      made '' is returned instead of 'Attempts: 0'.
 * @param int $currentgroup if there is a concept of current group where this method is being called
 *         (e.g. a report) pass it in here. Default 0 which means no current group.
 * @return string a string like "Attempts: 123", "Attemtps 123 (45 from your groups)" or
 *          "Attemtps 123 (45 from this group)".
 */
function mtcontabilita_num_attempt_summary($mtcontabilita, $cm, $returnzero = false, $currentgroup = 0) {
    global $DB, $USER;
    $numattempts = $DB->count_records('mtcontabilita_attempts', ['mtcontabilitaid' => $mtcontabilita->id, 'preview' => 0]);
    if ($numattempts || $returnzero) {
        if (groups_get_activity_groupmode($cm)) {
            $a = new stdClass();
            $a->total = $numattempts;
            if ($currentgroup) {
                $a->group = $DB->count_records_sql('SELECT COUNT(DISTINCT qa.id) FROM ' .
                        '{mtcontabilita_attempts} qa JOIN ' .
                        '{groups_members} gm ON qa.userid = gm.userid ' .
                        'WHERE mtcontabilita = ? AND preview = 0 AND groupid = ?',
                        [$mtcontabilita->id, $currentgroup]);
                return get_string('attemptsnumthisgroup', 'mtcontabilita', $a);
            } else if ($groups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid)) {
                list($usql, $params) = $DB->get_in_or_equal(array_keys($groups));
                $a->group = $DB->count_records_sql('SELECT COUNT(DISTINCT qa.id) FROM ' .
                        '{mtcontabilita_attempts} qa JOIN ' .
                        '{groups_members} gm ON qa.userid = gm.userid ' .
                        'WHERE mtcontabilita = ? AND preview = 0 AND ' .
                        "groupid $usql", array_merge([$mtcontabilita->id], $params));
                return get_string('attemptsnumyourgroups', 'mtcontabilita', $a);
            }
        }
        return get_string('attemptsnum', 'mtcontabilita', $numattempts);
    }
    return '';
}

/**
 * mtcontabilita_get_user_attempts
 *
 * @param int|array $mtcontabilitaids A mtcontabilita ID, or an array of mtcontabilita IDs.
 * @param int $userid the userid.
 * @param string $status 'all', 'finished' or 'unfinished' to control
 * @param bool $includepreviews
 * @return array of all the user's attempts at this mtcontabilita. Returns an empty
 *      array if there are none.
 */
function mtcontabilita_get_user_attempts($mtcontabilitaids, $userid, $status = 'finished', $includepreviews = false) {
    global $DB;

    $params = [];
    switch ($status) {
        case 'all':
            $statuscondition = '';
            break;

        case 'finished':
            $statuscondition = ' AND state IN (:state1, :state2)';
            $params['state1'] = mtcontabilita_attempt::FINISHED;
            $params['state2'] = mtcontabilita_attempt::ABANDONED;
            break;

        case 'unfinished':
            $statuscondition = ' AND state IN (:state1, :state2)';
            $params['state1'] = mtcontabilita_attempt::IN_PROGRESS;
            $params['state2'] = mtcontabilita_attempt::OVERDUE;
            break;
    }

    $mtcontabilitaids = (array) $mtcontabilitaids;
    list($insql, $inparams) = $DB->get_in_or_equal($mtcontabilitaids, SQL_PARAMS_NAMED);
    $params += $inparams;
    $params['userid'] = $userid;

    $previewclause = '';
    if (!$includepreviews) {
        $previewclause = ' AND preview = 0';
    }

    return $DB->get_records_select('mtcontabilita_attempts',
            "mtcontabilitaid $insql AND userid = :userid" . $previewclause . $statuscondition,
            $params, 'mtcontabilitaid, attempt ASC');
}

require_once("$CFG->libdir/pdflib.php");

$path = $CFG->dataroot.'/cache/tcpdf';
if (!file_exists($path)) {
    mkdir($path, 0777, true);
}

/**
 * mypdf
 */
class mypdf extends TCPDF {

    /**
     * header
     */
    public function header() {
    }
}

/**
 * mod_mtcontabilita_pdf
 */
class mod_mtcontabilita_pdf {

    /** @var var */
    private $mtcontabilitaid;
    /** @var var */
    private $tp;

    /**
     * construct
     */
    public function __construct($tp, $mtcontabilitaid) {
        $this->mtcontabilitaid = $mtcontabilitaid;
        $this->tp = $tp;
    }

    /**
     * create
     */
    public function create() {
        global $CFG, $DB;

        require_once("$CFG->libdir/pdflib.php");

        $pdf = new mypdf(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
        $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
        $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
        $pdf->SetAutoPageBreak(true, PDF_MARGIN_BOTTOM);
        $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
        $pdf->SetFont('helvetica', '', 12);
        $pdf->AddPage();

        $html = $DB->get_field('mtcontabilita', 'description', ['id' => $this->mtcontabilitaid]);
        $pdf->writeHTMLCell($pdf->getPageWidth() - PDF_MARGIN_RIGHT - PDF_MARGIN_LEFT, 0, PDF_MARGIN_LEFT, PDF_MARGIN_TOP, $html, 0, 0, false, true, "L");
        $pdf->Output('output.pdf', 'D');
    }
}
