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

namespace local_kid\external;

use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use local_kid\local\access_helper;
use local_kid\local\capp_repository;
use local_kid\local\competency_repository;
use local_kid\local\eval_repository;
use local_kid\local\niveau_repository;
use local_kid\local\stage_repository;
use local_kid\local\student_nav_helper;
use local_kid\local\workflow_service;
use local_kid\output\capp_grid_page;
use local_kid\output\eval_grid_page;
use local_kid\output\stage_grid_page;

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

require_once($GLOBALS['CFG']->dirroot . '/local/kid/classes/form/entry_grid_form.php');
require_once($GLOBALS['CFG']->dirroot . '/local/kid/classes/form/capp_grid_form.php');

/**
 * Re-renders the student-mode fragment (student nav header + workflow +
 * form) of one of the three data-entry screens (Évaluations, Stages, CAPP)
 * for a different student, so the screen's header (selector, previous/next,
 * position counter — {@see student_nav_helper}) can switch student without
 * a full page reload. Read-only: mirrors exactly the studentid branch of
 * the matching controller (pages/evaluations.php, pages/stages.php,
 * pages/capp.php) — saving is still a normal form POST to that controller.
 * Sole exception: the capp branch also mirrors pages/capp.php's one-time
 * commentaire seeding (capp_repository::seed_commentaires_from_sources()),
 * an idempotent no-op once a competency already has a CAPP commentaire —
 * needed so switching student via this endpoint shows the same pre-filled
 * state as a full page load would.
 */
class get_grid_student_view extends external_api {

    public static function execute_parameters(): external_function_parameters {
        return new external_function_parameters([
            'screen' => new external_value(PARAM_ALPHA, 'evaluations, stages or capp'),
            'itemid' => new external_value(PARAM_INT, 'evalid / stageid / sessionid'),
            'studentid' => new external_value(PARAM_INT, 'local_kid_student.id to display'),
        ]);
    }

    public static function execute(string $screen, int $itemid, int $studentid): array {
        global $PAGE;

        ['screen' => $screen, 'itemid' => $itemid, 'studentid' => $studentid] = self::validate_parameters(
            self::execute_parameters(),
            ['screen' => $screen, 'itemid' => $itemid, 'studentid' => $studentid]
        );

        $context = \context_system::instance();
        self::validate_context($context);
        access_helper::require_capability_or_teacher('local/kid:view', $context);

        if (!student_nav_helper::is_valid_screen($screen)) {
            throw new \moodle_exception('invalidrecord', 'error');
        }

        $renderer = $PAGE->get_renderer('local_kid');

        switch ($screen) {
            case 'evaluations':
                $html = self::render_evaluations($renderer, $itemid, $studentid);
                break;
            case 'stages':
                $html = self::render_stages($renderer, $itemid, $studentid);
                break;
            case 'capp':
                $html = self::render_capp($renderer, $itemid, $studentid);
                break;
            default:
                throw new \moodle_exception('invalidrecord', 'error');
        }

        return ['html' => $html];
    }

    private static function render_evaluations(\local_kid\output\renderer $renderer, int $evalid, int $studentid): string {
        $eval = eval_repository::get($evalid);
        if (!$eval) {
            throw new \moodle_exception('invalidrecord', 'error');
        }
        $entry = eval_repository::get_entry_for_student($evalid, $studentid);
        if (!$entry) {
            throw new \moodle_exception('invalidrecord', 'error');
        }

        $form = new \local_kid_entry_grid_form(
            new \moodle_url('/local/kid/pages/evaluations.php', ['evalid' => $evalid, 'studentid' => $studentid]),
            [
                'competencies' => eval_repository::get_competencies($evalid),
                'niveaux' => niveau_repository::get_all(),
                'results' => eval_repository::get_results((int) $entry->id),
                'commenthistory' => \local_kid\local\comment_history_service::get_for_entry('eval', (int) $entry->id),
                'historycontext' => get_string('nav_evaluations', 'local_kid') . ' · '
                    . \local_kid\local\promotion_repository::get_student_fullname($studentid),
            ]
        );
        $form->set_data(['entryid' => $entry->id]);

        return $renderer->render_eval_grid_student(new eval_grid_page($eval, $studentid, $form->render()));
    }

    private static function render_stages(\local_kid\output\renderer $renderer, int $stageid, int $studentid): string {
        $stage = stage_repository::get($stageid);
        if (!$stage) {
            throw new \moodle_exception('invalidrecord', 'error');
        }
        $entry = stage_repository::get_entry_for_student($stageid, $studentid);
        if (!$entry) {
            throw new \moodle_exception('invalidrecord', 'error');
        }

        $readonly = $entry->workflowstatus === workflow_service::STATUS_FINALISE
            || !access_helper::has_capability_or_teacher('local/kid:evaluate_stage', \context_system::instance());

        $form = new \local_kid_entry_grid_form(
            new \moodle_url('/local/kid/pages/stages.php', ['stageid' => $stageid, 'studentid' => $studentid]),
            [
                'competencies' => stage_repository::get_scope_competencies($stage),
                'niveaux' => niveau_repository::get_all(),
                'results' => stage_repository::get_results((int) $entry->id),
                'commenthistory' => \local_kid\local\comment_history_service::get_for_entry('stage', (int) $entry->id),
                'historycontext' => get_string('nav_stages', 'local_kid') . ' · '
                    . \local_kid\local\promotion_repository::get_student_fullname($studentid),
                'showglobalcomment' => true,
                'readonly' => $readonly,
            ]
        );
        $form->set_data(['entryid' => $entry->id, 'commentaireglobal' => $entry->commentaireglobal]);

        return $renderer->render_stage_grid_student(new stage_grid_page($stage, $studentid, $form->render()));
    }

    private static function render_capp(\local_kid\output\renderer $renderer, int $sessionid, int $studentid): string {
        $session = capp_repository::get_session($sessionid);
        if (!$session) {
            throw new \moodle_exception('invalidrecord', 'error');
        }
        $entry = capp_repository::get_entry_for_student($sessionid, $studentid);
        if (!$entry) {
            throw new \moodle_exception('invalidrecord', 'error');
        }

        $competencies = competency_repository::get_active_for_promotion((int) $session->promotionid);
        $competencylabels = [];
        $consultative = [];
        foreach ($competencies as $competency) {
            $competencylabels[$competency->id] = competency_repository::label($competency);
            $consultative[$competency->id] = [
                'eval' => capp_repository::get_consultative_eval_data($sessionid, $studentid, (int) $competency->id),
                'stage' => capp_repository::get_consultative_stage_data($sessionid, $studentid, (int) $competency->id),
            ];
        }

        capp_repository::seed_commentaires_from_sources($sessionid, $studentid, (int) $entry->id, array_map(fn($c) => (int) $c->id, $competencies));

        $form = new \local_kid_capp_grid_form(
            new \moodle_url('/local/kid/pages/capp.php', ['sessionid' => $sessionid, 'studentid' => $studentid]),
            [
                'competencies' => $competencylabels,
                'niveaux' => niveau_repository::get_all(),
                'results' => capp_repository::get_results((int) $entry->id),
                'consultative' => $consultative,
                'commenthistory' => \local_kid\local\comment_history_service::get_for_entry('capp', (int) $entry->id),
                'historycontext' => get_string('nav_capp', 'local_kid') . ' · '
                    . \local_kid\local\promotion_repository::get_student_fullname($studentid),
            ]
        );
        $form->set_data([
            'entryid' => $entry->id,
            'appreciationglobale' => $entry->appreciationglobale,
        ]);

        return $renderer->render_capp_grid_student(new capp_grid_page($session, $studentid, $form->render()));
    }

    public static function execute_returns(): external_single_structure {
        return new external_single_structure([
            'html' => new external_value(PARAM_RAW, 'Rendered HTML fragment for [data-region="kid-grid-student"]'),
        ]);
    }
}
