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

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

/**
 * mtcontabilita class
 */
class mtcontabilita {

    /**
     * construct
     */
    public function __construct() {
    }

    /**
     * MACROCLASSE ELEMENTI.
     */
    public function get_macroclasse_opt() {
        $rit = [
            "# Valore della produzione" => [
                "A1" => "A1) Valore della produzione - ricavi delle vendite e delle prestazioni",
                "A2" => "A2) Valore della produzione - variazione delle rimanenze di prodotti in corso di lavorazione, semilavorati e finiti",
                "A3" => "A3) Valore della produzione - variazione dei lavori in corso di lavorazione",
                "A4" => "A4) Valore della produzione - incrementi di immobilizzazioni per lavori interni",
                "A5" => "A5) Valore della produzione - altri ricavi e proventi",
            ],

            "# Costi della produzione" => [
                "B6"  => "B6) Costi della produzione - per materie prime, sussidiarie, di consumo e merci",
                "B7"  => "B7) Costi della produzione - per servizi",
                "B8"  => "B8) Costi della produzione - per godimento beni di terzi",
                "B9"  => "B9) Costi della produzione - per il personale",
                "B10" => "B10) Costi della produzione - ammortamenti e svalutazioni",
                "B11" => "B11) Costi della produzione - variazione delle rimanenze di materie prime, sussidiarie, di consumo e merci",
                "B12" => "B12) Costi della produzione - accantonamenti per rischi",
                "B13" => "B13) Costi della produzione - altri accantonamenti",
                "B14" => "B14) Costi della produzione - oneri diversi di gestione",
            ],

            "# Proventi e oneri finanziari" => [
                "C15"     => "C15) Proventi finanziari - proventi da partecipazioni",
                "C16"     => "C16) Altri proventi finanziari",
                "C17"     => "C17) Interessi e altri oneri finanziari",
                "C17-bis" => "C17-bis) Utili e perdite su cambi",
            ],

            "# Rettifiche di valore di attività e passività finanziarie" => [
                "D18" => "D18) Rivalutazioni",
                "D19" => "D19) Svalutazioni",
            ],

            "# Imposte sul reddito d'esercizio" => [
                "E20" => "E20) Proventi e oneri straordinari - proventi con separata indicazione delle plusvalenze",
                "E21" => "E21) Proventi e oneri straordinari - oneri con separata indicazione delle minusvalenze",
                "E22" => "E22) Imposte sul reddito dell'esercizio",
            ],
        ];
        return $rit;
    }

    /**
     * get_scheme_list
     */
    public function get_scheme_list($val = -1) {
        if ($val == 0) {
            return "";
        }
        $rit = [
              '' => get_string('choose'),
            'ce' => get_string('ce', 'mtcontabilita'),
            'sp' => get_string('sp', 'mtcontabilita'),
        ];
        if ($val != -1) {
            return $rit[$val];
        }
        return $rit;
    }

    /**
     * get_nature_list
     */
    public function get_nature_list($val = -1, $scheme = "") {
        if ($val == 0) {
            return "";
        }
        if ($scheme != "") {
            switch ($scheme) {
                case "ce":
                    $rit = [
                        '' => get_string('choose'),
                        1 => get_string('n1', 'mtcontabilita'),
                        2 => get_string('n2', 'mtcontabilita'),
                    ];

                    break;
                case "sp":
                    $rit = [
                        '' => get_string('choose'),
                        3 => get_string('n3', 'mtcontabilita'),
                        4 => get_string('n4', 'mtcontabilita'),
                        5 => get_string('n5', 'mtcontabilita'),
                    ];

                    break;
            }
        } else {
            $rit = [
                '' => get_string('choose'),
                1 => get_string('n1', 'mtcontabilita'),
                2 => get_string('n2', 'mtcontabilita'),
                3 => get_string('n3', 'mtcontabilita'),
                4 => get_string('n4', 'mtcontabilita'),
                5 => get_string('n5', 'mtcontabilita'),
            ];
        }
        if ($val != -1) {
            return $rit[$val];
        }
        return $rit;
    }

    /**
     * get_nature_list2
     */
    public function get_nature_list2($tp) {
        $rit = ['' => get_string('choose')];
        switch ($tp) {
            case "CE":
                $rit[1] = get_string('n1', 'mtcontabilita');
                $rit[2] = get_string('n2', 'mtcontabilita');
                break;
            case "SP":
                $rit[3] = get_string('n3', 'mtcontabilita');
                $rit[4] = get_string('n4', 'mtcontabilita');
                break;
            case "PN":
                $rit[5] = get_string('n5', 'mtcontabilita');
                break;
        }
        return $rit;
    }

    /**
     * get_macroclasse_list
     */
    public function get_macroclasse_list($val = -1) {
        global $DB;
        if ($val == 0 || $val == "") {
            return "";
        }
        $rit = $DB->get_records_menu('mtcontabilita_listmc', [], 'sortorder ASC', 'macroclasse,description');
        if ($val != -1) {
            return $rit[$val];
        }
        return $rit;
    }

    /**
     * get_legend
     */
    public function get_legend($user, $mtcontabilita, $cid) {
        $isadmin = is_siteadmin($user);

        $context = context_course::instance($cid);

        if ($isadmin || has_capability('mod/mtcontabilita:addinstance', $context)) {
            $html = "<ul>";
            $html .= '<li>'.get_string('type', 'mtcontabilita').': '.$this->get_opt_tipologia($mtcontabilita->type).'</li>';
            $html .= '<li>'.get_string('inline', 'mtcontabilita').': '.$this->get_opt_yn($mtcontabilita->inline).'</li>';
            $html .= '<li>'.get_string('resume', 'mtcontabilita').': '.$this->get_opt_yn($mtcontabilita->resume).'</li>';
            $html .= '<li>'.get_string('attempt', 'mtcontabilita').': '.$this->get_opt_tentativi($mtcontabilita->attempt).'</li>';
            $html .= '<li>'.get_string('timelimit', 'quiz').': '.$this->get_opt_timelimit($mtcontabilita->timelimit).'</li>';
            $html .= "</ul>";
            echo $html;
        }
    }

    /**
     * get_opt_tipologia
     */
    public function get_opt_tipologia($sel = '') {
        $opt = ['' => get_string('choose'), 0 => get_string('type0', 'mtcontabilita'), 1 => get_string('type1', 'mtcontabilita')];
        if ($sel != "") {
            return $opt[$sel];
        }
        return $opt;
    }

    /**
     * get_opt_yn
     */
    public function get_opt_yn($sel = '') {
        $opt = ['' => get_string('choose'), 0 => get_string('no'), 1 => get_string('yes')];
        if ($sel != "") {
            return $opt[$sel];
        }
        return $opt;
    }

    /**
     * get_opt_tentativi
     */
    public function get_opt_tentativi($sel = '') {
        $opt = [];
        for ($i = 0; $i <= 10; $i++) {
            $opt[$i] = $i;
        }
        $opt[0] = get_string('illimitato', 'mtcontabilita');

        if ($sel != "") {
            return $opt[$sel];
        }
        return $opt;
    }

    /**
     * get_opt_timelimit
     */
    private function get_opt_timelimit($val) {
        if ($val > 0) {
            return $this->format_time_hms($val);
        } else {
            return get_string('illimitato', 'mtcontabilita');
        }
    }

    /**
     * format_time_hms
     */
    private function format_time_hms($seconds) {
        $seconds = (int)$seconds;

        if ($seconds < 60) {
            // Solo secondi
            return $seconds . ' ' . ($seconds == 1 ? 'secondo' : 'secondi');
        } else if ($seconds < 3600) {
            // Meno di un'ora
            $minutes = intdiv($seconds, 60);
            $rest = $seconds % 60;

            $out = $minutes . ' ' . ($minutes == 1 ? 'minuto' : 'minuti');

            if ($rest > 0) {
                $out .= ' e ' . $rest . ' ' . ($rest == 1 ? 'secondo' : 'secondi');
            }

            return $out;
        } else {
            // Un'ora o più
            $hours = intdiv($seconds, 3600);
            $minutes = intdiv($seconds % 3600, 60);
            $rest = $seconds % 60;

            $parts = [];
            $parts[] = $hours . ' ' . ($hours == 1 ? 'ora' : 'ore');

            if ($minutes > 0) {
                $parts[] = $minutes . ' ' . ($minutes == 1 ? 'minuto' : 'minuti');
            }

            if ($rest > 0) {
                $parts[] = $rest . ' ' . ($rest == 1 ? 'secondo' : 'secondi');
            }

            return implode(', ', $parts);
        }
    }
}

/**
 * Ritorna info tempo per un attempt: timestart, timelimit (sec), deadline, secondsleft, overdue.
 *
 * @param int $attemptid
 * @return array
 */
function mtc_timeinfo_for_attempt(int $attemptid): array {
    global $DB;

    $attempt = $DB->get_record('mtcontabilita_attempts', ['id' => $attemptid], '*', MUST_EXIST);
    $mtc = $DB->get_record('mtcontabilita', ['id' => $attempt->mtcontabilitaid], 'id,timelimit', MUST_EXIST);

    $timestart = (int)$attempt->timestart;
    $timelimit = max(0, (int)$mtc->timelimit); // già in secondi (dal duration element)
    $deadline  = $timelimit > 0 ? ($timestart + $timelimit) : 0;
    $now       = time();
    $left      = $timelimit > 0 ? ($deadline - $now) : PHP_INT_MAX;

    return [
        'timestart'    => $timestart,
        'timelimit'    => $timelimit,
        'deadline'     => $deadline,
        'secondsleft'  => $left,
        'overdue'      => ($timelimit > 0 && $left <= 0),
    ];
}
