<?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();

/**
 * import
 */
class mtcontabilita_import {

    /** @var session. */
    private $stdfields;
    /** @var session. */
    private $lang;

    /**
     * construct
     */
    public function __construct($stdfields) {
        $this->stdfields = $stdfields;
        $this->lang = strtoupper(current_language());
    }

    /**
     * Natura = Titologia
     */
    /**
 * Natura = Tipologia
 */
public function get_nature_check() {
    return [
        "costi di esercizio",
        "costi d'esercizio",
        "costi",
        "costo d'esercizio",
        "costo di esercizio",
        "costo",

        "ricavi di esercizio",
        "ricavi d'esercizio",
        "ricavi",
        "ricavo di esercizio",
        "ricavo d'esercizio",
        "ricavo",

        "attivo",
        "att",
        "attività",
        "attivita",
        "attivit",

        "passivo",
        "pass",
        "passività",
        "passivita",
        "passivit",

        "patrimonio netto",
        "patrimonionetto",
        "pn",

        // EN
        "cost",
        "revenue",
        "revenues",
        "activities",
        "liabilities",
        "liability",
        "asset",
        "assets",
        "equity",
        "expenses",
    ];
}

    /**
     * get_scheme
     */
    public function get_scheme_check() {
        return ["ce" => "ce", "sp" => "sp",
            "is" => "ce", "bs" => "sp"];
    }

    /**
     * get check
     */
    public function get_macroclasse_check($nature) {
        global $DB;
        if ($this->lang == "IT") {
            return $DB->get_fieldset('mtcontabilita_listmc', 'macroclasse', ['nature' => $nature]);
        } else {
            return [];
        }
    }

    /**
     * lang check
     */
    private function get_lang_check() {
        return ['it', 'en'];
    }

    /**
     * validate
     */
    public function validate(csv_import_reader $cir, moodle_url $returnurl) {
        global $DB;
        $columns = $cir->get_columns();
        if (empty($columns)) {
            $cir->close();
            $cir->cleanup();
            redirect('index.php');
        }
        $processed = $columns;
        return [$processed];
    }

    /**
     * result
     */
    public function result($cir, $filecolumns, $cid) {
        global $DB, $USER;

        $linenum  = 1;
        $recordnew  = 0;
        $recordupt  = 0;
        $skipped = '';
        $n = 4;
        $this->stdfields[0] = 'line';
        $this->stdfields[1] = get_string('denominazioneconto', 'mtcontabilita');
        $this->stdfields[2] = get_string('scheme', 'mtcontabilita');
        $this->stdfields[3] = get_string('nature', 'mtcontabilita');
        $this->stdfields[4] = get_string('macroclasse', 'mtcontabilita');
        $n = 5;
        $this->stdfields[$n] = 'Lang';
        $this->stdfields[$n + 1] = 'status';
        $upt = new mtcplperform_tracciamento($this->stdfields);
        $upt->start();
        $adesso = time();

        $columnkeys = array_map([$this, 'normalize_csv_value'], $filecolumns);
        $langindex = array_search('lang', $columnkeys, true);
        if ($langindex === false) {
            $langindex = 4;
        }
        $macroclasseindex = ($langindex === 3) ? null : 3;

        // **************************************************************************************
        // Cicla tutte le linee del CSV e scrive i dati                                         *
        // **************************************************************************************
        while ($line = $cir->next()) {
            $account = $line[0] ?? '';
            $scheme = $line[1] ?? '';
            $nature = $line[2] ?? '';
            $macroclasse = ($macroclasseindex === null) ? '' : ($line[$macroclasseindex] ?? '');
            $lang = $line[$langindex] ?? '';

            $upt->flush();
            $linenum++;
            $upt->track('line', $linenum);
            $upt->track($this->stdfields[1], $account); // Conto.
            $upt->track($this->stdfields[2], $scheme); // Schema.
            $upt->track($this->stdfields[3], $nature); // Tipologia.
            $upt->track($this->stdfields[4], $macroclasse); // Cod civil.
            $upt->track($this->stdfields[5], $lang); // Lang.
            // **********************************
            $new = [];
            $new['name'] = $account;
            // NATURE/ TIPOLOGIA.
            $val = $this->normalize_csv_value($nature);// $val = mb_strtolower($line[2], 'UTF-8');
            $acheck = $this->get_nature_check();
            if ($val != "") {
                if (in_array($val, $acheck)) {
                    switch ($val) {
    case "cost":
    case "costo":
    case "costo di esercizio":
    case "costo d'esercizio":
    case "costi":
    case "costi di esercizio":
    case "costi d'esercizio":
    case "expenses":
        $new['nature'] = 1;
        break;

    case "revenue":
    case "ricavo":
    case "ricavo di esercizio":
    case "ricavo d'esercizio":
    case "ricavi":
    case "ricavi di esercizio":
    case "ricavi d'esercizio":
    case "revenues":
        $new['nature'] = 2;
        break;

    case "attivo":
    case "att":
    case "activities":
    case "attività":
    case "attivit":
    case "attivita":
    case "assets":
    case "asset":
        $new['nature'] = 3;
        break;

    case "passivo":
    case "pass":
    case "passività":
    case "passivita":
    case "passivit":
    case "liabilities":
    case "liability":
        $new['nature'] = 4;
        break;

    case "patrimonio netto":
    case "patrimonionetto":
    case "equity":
    case "pn":
        $new['nature'] = 5;
        break;
}
                } else {
                    $new['nature'] = 0;
                    $upt->track('status', get_string('nature_err', 'mtcontabilita'), 'error');
                    $skipped++;
                    continue;
                }
            }
            // SCHEME.
            $val = $this->normalize_csv_value($scheme); //$val = mb_strtolower($line[1], 'UTF-8');
            $acheck = $this->get_scheme_check();
            if (array_key_exists($val, $acheck)) {
                // if (
                //     ($acheck[$val] == "ce" && ($new['nature'] == "1" || $new['nature'] == "2")) ||
                //     ($acheck[$val] == "sp" && ($new['nature'] == "3" || $new['nature'] == "4") || $new['nature'] == "5")
                //     ) {
                //     $new['scheme'] = $acheck[$val];
                // } else {
                //     $upt->track('status', 'Combinazione schema/tipologia non consentita', 'error');
                //     $skipped++;
                //     continue;
                // }
if (
    ($acheck[$val] == "ce" && ($new['nature'] == "1" || $new['nature'] == "2")) ||
    ($acheck[$val] == "sp" && ($new['nature'] == "3" || $new['nature'] == "4" || $new['nature'] == "5"))
) {
    $new['scheme'] = $acheck[$val];
} else {
    $upt->track('status', 'Combinazione schema/tipologia non consentita', 'error');
    $skipped++;
    continue;
}
            } else {
                $upt->track('status', get_string('scheme_err', 'mtcontabilita'), 'error');
                $skipped++;
                continue;
            }
            // MACROCLASSE.
            $val = mb_strtoupper(trim((string)$macroclasse), 'UTF-8'); //$val = mb_strtoupper($line[3], 'UTF-8');
            $acheck = $this->get_macroclasse_check($new['nature']);
            if (in_array($val, $acheck) || $val == "") {
                $new['macroclasse'] = $val;
            } else {
                $upt->track('status', get_string('macroclasse_err', 'mtcontabilita'), 'error');
                $skipped++;
                continue;
            }
            // Lang.
            $val = $this->normalize_csv_value($lang); //$val = mb_strtolower($line[4], 'UTF-8');
            $acheck = $this->get_lang_check();
            if (!in_array($val, $acheck)) {
                $upt->track('status', get_string('lang_err', 'mtcontabilita'), 'error');
                $skipped++;
                continue;
            } else {
                $new['lang'] = $val;
            }
            // Altri valori.
            $new['usercreated'] = $USER->id;
            $new['timecreated'] = $adesso;
            $new['courseid'] = $cid;
            if ($id = $DB->get_field('mtcontabilita_list', 'id', ['name' => $new['name'], 'courseid' => $cid])) {
                $new['id'] = $id;
                $DB->update_record('mtcontabilita_list', (object)$new);
                $recordupt++;
            } else {
                $DB->insert_record('mtcontabilita_list', (object)$new);
                $recordnew++;
            }
            foreach ($this->stdfields as $field) {
                if (isset($formdata->$field)) {
                    // process templates.
                    $riga->$field = uu_process_template($formdata->$field, $new);
                    $formdefaults[$field] = true;
                    if (in_array($field, $upt->columns)) {
                        $upt->track($field, s($new->$field), 'normal');
                    }
                }
            }
        }
        $rit = array($skipped, $recordnew, $recordupt);
        $upt->close();

        $params = [
            'context' => context_course::instance($cid),
            'objectid' => $cid,
        ];
        $event = \mod_mtcontabilita\event\import_list::create($params);
        $event->trigger();

        return $rit;
    }

/**
 * Normalizza un valore importato dal CSV.
 *
 * @param string|null $value
 * @return string
 */
private function normalize_csv_value($value) {
    $value = (string)$value;
    $value = trim($value);

    // Normalizza unicode se disponibile.
    if (class_exists('Normalizer')) {
        $value = \Normalizer::normalize($value, \Normalizer::FORM_C);
    }

    // Riduce spazi multipli a uno.
    $value = preg_replace('/\s+/u', ' ', $value);

    return mb_strtolower($value, 'UTF-8');
}

}

/**
 * mtcplperform_tracciamento class
 */
class mtcplperform_tracciamento {

    /** @var row */
    private $_row;
    /** @var row */
    public $columns;

    /**
     * construct
     */
    public function __construct($stdfields) {
        $this->columns = $stdfields;
    }

    /**
     * start
     */
    public function start() {
        echo '<table id="tab" class="generaltable flexible-wrap" summary="summary">';
        echo '<tr class="heading r0">';
        for ($i = 0; $i < count($this->columns); $i++) {
            echo '<th class="header c'.$i.'" scope="col">'.$this->columns[$i].'</th>';
        }
        echo '</tr>';
        $this->_row = null;
    }

    /**
     * flush
     */
    public function flush() {
        if (empty($this->_row) || empty($this->_row['line']['normal'])) {
            $this->_row = array();
            foreach ($this->columns as $col) {
                $this->_row[$col] = array('normal' => '', 'info' => '', 'warning' => '', 'error' => '');
            }
            return;
        }
        $ci = 0;
        $ri = 1;
        echo '<tr class="r'.$ri.'">';
        foreach ($this->_row as $key => $field) {
            foreach ($field as $type => $content) {
                if ($field[$type] !== '') {
                    $field[$type] = '<span class="uu'.$type.'">'.$field[$type].'</span>';
                } else {
                    unset($field[$type]);
                }
            }
            echo '<td class="cell c'.$ci++.'">';
            echo !empty($field) ? implode('<br />', $field) : '&nbsp;';
            echo '</td>';
        }
        echo '</tr>';
        foreach ($this->columns as $col) {
            $this->_row[$col] = array('normal' => '', 'info' => '', 'warning' => '', 'error' => '');
        }
    }

    /**
     * track
     */
    public function track($col, $msg, $level = 'normal', $merge = true) {
        if (empty($this->_row)) {
            $this->flush();
        }
        if (!in_array($col, $this->columns)) {
            debugging('Incorrect column:'.$col);
            return;
        }
        if ($merge) {
            if ($this->_row[$col][$level] != '') {
                $this->_row[$col][$level] .= '<br />';
            }
            $this->_row[$col][$level] .= $msg;
        } else {
            $this->_row[$col][$level] = $msg;
        }
    }

    /**
     * close
     */
    public function close() {
        $this->flush();
        echo '</table>';
    }
}
