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

/**
 * Library functions for local_kid.
 *
 * @package    local_kid
 */

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

use local_kid\local\access_helper;
use local_kid\local\nav_helper;

/**
 * Adds the plugin's 6 navigation nodes, each filtered by the capability
 * that actually gates the target page — an authenticated user with no
 * system role only ever sees "Vue élève".
 *
 * @param \global_navigation $navigation
 */
function local_kid_extend_navigation(\global_navigation $navigation) {
    $node = $navigation->add(
        get_string('pluginname', 'local_kid'),
        null,
        \navigation_node::TYPE_CONTAINER,
        null,
        'local_kid'
    );
    $node->showinflatnavigation = true;

    foreach (nav_helper::ENTRIES as [$capabilities, $stringkey, $url, $key]) {
        if (!nav_helper::can_access_entry($capabilities)) {
            continue;
        }
        $node->add(
            get_string($stringkey, 'local_kid'),
            new \moodle_url($url),
            \navigation_node::TYPE_CUSTOM,
            null,
            'local_kid_' . $stringkey
        );
    }
}

/**
 * Shared page bootstrap for every local_kid controller: loads the plugin's
 * scoped CSS/font, tags <body> with the class every selector in
 * local_kid.css is scoped under (so the design system never leaks onto any
 * other Moodle page), and turns the page heading into a link back to the
 * dashboard — `core/context_header` renders `heading` unescaped
 * ({{{heading}}}), but `moodle_page::set_heading()` still runs it through
 * `format_string()` by default, which strips tags; `$applyformatting =
 * false` routes it through `clean_text()` instead, which keeps a plain
 * `<a href>` intact.
 *
 * The heading also gets the DSFR "data-visualization" pictogram
 * (artwork/pictograms/digital/data-visualization.svg — not vendored as
 * part of the icons/ set that ships in the DSFR dist bundle's CSS/icon
 * font, so it's copied in separately under thirdparty/dsfr/pictograms/)
 * inlined as raw SVG just before the text, inside the same link. It's read
 * straight from the vendored file and passed through untouched:
 * `set_heading()`'s `$clean = false` skips `clean_text()`/HTMLPurifier
 * entirely, because HTMLPurifier's default config strips `<svg>`/`<style>`/
 * `<use>` as unknown tags — the pictogram's tri-tone colouring
 * (fr-artwork-decorative/minor/major) is hardcoded in its own inline
 * `<style>`, unlike a single-colour icon, so there's no `currentColor`
 * fallback to lose by not sanitising. Safe to skip sanitising here only
 * because the string has no user input in it (a static vendored file plus
 * a getstring and a moodle_url).
 *
 * The DSFR (Système de Design de l'État) stylesheets loaded here are a
 * build-time transform of the upstream vendored files (see
 * thirdparty/dsfr, thirdpartylibs.xml): every selector is prefixed under
 * `.kid-region` — the container {@see \local_kid\output\renderer::render_shell()}
 * wraps all plugin content in on every page — so DSFR's element-level resets
 * (a, table, button, h1-h6, ...) can never reach the surrounding Moodle
 * theme/chrome, which sits outside that container. Loaded on every
 * local_kid page regardless of whether the page's own templates use `fr-*`
 * classes yet: an unmigrated page using only the legacy `kid-*` classes in
 * local_kid.css is unaffected (no selector overlap), so this is safe ahead
 * of the templates being migrated screen by screen.
 *
 * @param \moodle_page $page
 */
function local_kid_setup_page(\moodle_page $page) {
    $page->add_body_class('local-kid-app');
    $page->requires->css('/local/kid/thirdparty/dsfr/dsfr.scoped.css');
    $page->requires->css('/local/kid/thirdparty/dsfr/utility/utility.scoped.css');
    $page->requires->css('/local/kid/styles/local_kid.css');
    $page->requires->js(new \moodle_url('/local/kid/thirdparty/dsfr/dsfr.nomodule.min.js'));
    $icon = file_get_contents(__DIR__ . '/thirdparty/dsfr/pictograms/digital/data-visualization.svg');
    $icon = str_replace('<svg ', '<svg aria-hidden="true" focusable="false" '
        . 'style="width:2.64rem;height:2.64rem;vertical-align:-0.66rem;margin-right:0.66rem;" ', $icon);
    $page->set_heading(\html_writer::link(
        new \moodle_url('/local/kid/pages/dashboard.php'),
        $icon . get_string('pluginname', 'local_kid')
    ), false, false);
}

/**
 * Serves files stored under the plugin's file areas.
 *
 * Only `stagedoc` exists so far: a document is served to staff holding
 * `viewany` (or `teacher` via {@see access_helper}), or to the student who
 * owns the entry — same owner-or-viewany shape as the Phase 7 fiche
 * download will later need, kept simple here since stage documents are
 * never gated on publication status (unlike published fiches).
 *
 * @param \stdClass $course
 * @param \stdClass $cm
 * @param \context $context
 * @param string $filearea
 * @param array $args
 * @param bool $forcedownload
 * @param array $options
 * @return bool
 */
function local_kid_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = []) {
    global $DB, $USER;

    require_login();

    if ($filearea !== 'stagedoc') {
        return false;
    }

    $systemcontext = \context_system::instance();
    $entryid = (int) array_shift($args);
    $filename = array_pop($args);

    $entry = $DB->get_record('local_kid_stage_entry', ['id' => $entryid], '*', IGNORE_MISSING);
    if (!$entry) {
        return false;
    }

    $canviewany = access_helper::has_capability_or_teacher('local/kid:viewany', $systemcontext);
    if (!$canviewany) {
        $student = $DB->get_record('local_kid_student', ['id' => $entry->studentid], '*', IGNORE_MISSING);
        if (!$student || (int) $student->userid !== (int) $USER->id) {
            return false;
        }
    }

    $fs = get_file_storage();
    $file = $fs->get_file($systemcontext->id, 'local_kid', 'stagedoc', $entryid, '/', $filename);
    if (!$file || $file->is_directory()) {
        return false;
    }

    send_stored_file($file, 0, 0, $forcedownload, $options);
}
