<?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\output;

use local_kid\local\access_helper;
use local_kid\local\capp_rapport_builder;
use local_kid\local\capp_repository;
use local_kid\local\niveau_repository;
use local_kid\local\student_nav_helper;
use local_kid\local\workflow_service;

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

/**
 * Two display modes for one CAPP session: the whole-promotion summary table
 * (no student selected) and a single student's grid (studentid given). The
 * grid <form> itself is rendered separately by the page controller
 * (moodleform HTML is not template-friendly) and passed in as raw content.
 */
class capp_grid_page implements \renderable, \templatable {

    protected \stdClass $session;
    protected ?int $studentid;
    protected string $formhtml;
    protected string $mode;
    protected ?array $conflict;

    public function __construct(\stdClass $session, ?int $studentid, string $formhtml = '', string $mode = 'saisie', ?array $conflict = null) {
        $this->session = $session;
        $this->studentid = $studentid;
        $this->formhtml = $formhtml;
        $this->mode = $mode;
        $this->conflict = $conflict;
    }

    public function export_for_template(\renderer_base $output): array {
        $context = \context_system::instance();
        $entries = capp_repository::get_entries_for_session((int) $this->session->id);
        $previoussession = capp_repository::get_previous_session((int) $this->session->id);
        $canexport = access_helper::has_capability_or_teacher('local/kid:view', $context);
        $canevaluate = has_capability('local/kid:evaluate_capp', $context);
        $canpublishcap = has_capability('local/kid:publish_capp', $context);
        // Le livret PDF (page de garde + Bilan général + fiches) est gardé
        // par local/kid:evaluate_capp — mêmes titulaires que la Vue
        // d'ensemble du CAPP (capp_picker_page), jamais l'élève — pas
        // canexport (qui inclut le personnel INSP lecteur, trop large ici).
        $cancapprapport = $canevaluate;

        $steps = [
            ['id' => workflow_service::STATUS_SAISIE, 'label' => get_string('workflow_saisie', 'local_kid')],
            ['id' => workflow_service::STATUS_VALIDE, 'label' => get_string('workflow_valide', 'local_kid')],
            ['id' => workflow_service::STATUS_FINALISE, 'label' => get_string('workflow_finalise', 'local_kid')],
        ];

        if ($this->studentid === null) {
            $rows = [];
            $finalisedcount = 0;
            $publishedcount = 0;
            foreach ($entries as $entry) {
                if ($entry->workflowstatus === workflow_service::STATUS_FINALISE) {
                    $finalisedcount++;
                }
                if ($entry->published) {
                    $publishedcount++;
                }
                $rows[] = [
                    'studentid' => (int) $entry->studentid,
                    'name' => $entry->lastname . ' ' . $entry->firstname,
                    'statusbadge' => workflow_service::render_status_badge($entry->workflowstatus),
                    'publishedlabel' => $entry->published ? get_string('published_yes', 'local_kid') : get_string('published_no', 'local_kid'),
                    'publishedclass' => $entry->published ? 'fr-badge fr-badge--success' : 'fr-badge',
                    'openurl' => (new \moodle_url('/local/kid/pages/capp.php',
                        ['sessionid' => $this->session->id, 'studentid' => $entry->studentid]))->out(false),
                ];
            }
            $importmode = $canevaluate && $this->mode === 'import';
            $bilanmode = $canevaluate && $this->mode === 'bilan';
            $data = [
                'summarymode' => true,
                'libelle' => format_string($this->session->code . ' — ' . $this->session->libelle),
                'rows' => $rows,
                'hasrows' => !empty($rows),
                'studentcount' => count($entries),
                'finalisedcount' => $finalisedcount,
                'publishedcount' => $publishedcount,
                'canbulkpublish' => $canpublishcap,
                'cancapprapport' => $cancapprapport,
                'hasbulkactions' => $canexport || $canpublishcap || $cancapprapport,
                'bulkscreen' => 'capp',
                'bulkitemid' => (int) $this->session->id,
                'sesskey' => sesskey(),
                'hasprevious' => (bool) $previoussession && $canevaluate,
                'canexport' => $canexport,
                'canimport' => $canevaluate,
                'importmode' => $importmode,
                'bilanmode' => $bilanmode,
                'bilan' => $bilanmode ? self::build_bilan_view((int) $this->session->id) : null,
                'tabs' => [
                    [
                        'label' => get_string('capp_rapport_bilan_heading', 'local_kid'),
                        'url' => (new \moodle_url('/local/kid/pages/capp.php',
                            ['sessionid' => $this->session->id, 'mode' => 'bilan']))->out(false),
                        'isactive' => $bilanmode,
                    ],
                    [
                        'label' => get_string('capp_mode_saisie', 'local_kid'),
                        'url' => (new \moodle_url('/local/kid/pages/capp.php',
                            ['sessionid' => $this->session->id, 'mode' => 'saisie']))->out(false),
                        'isactive' => !$importmode && !$bilanmode,
                    ],
                    [
                        'label' => get_string('capp_mode_import', 'local_kid'),
                        'url' => (new \moodle_url('/local/kid/pages/capp.php',
                            ['sessionid' => $this->session->id, 'mode' => 'import']))->out(false),
                        'isactive' => $importmode,
                    ],
                ],
                'templatecompetencesurl' => (new \moodle_url('/local/kid/pages/capp_template_competences.php',
                    ['sessionid' => $this->session->id]))->out(false),
                'importcompetencesurl' => (new \moodle_url('/local/kid/pages/capp_import_competences.php',
                    ['sessionid' => $this->session->id]))->out(false),
                'templateappreciationsurl' => (new \moodle_url('/local/kid/pages/capp_template_appreciations.php',
                    ['sessionid' => $this->session->id]))->out(false),
                'importappreciationsurl' => (new \moodle_url('/local/kid/pages/capp_import_appreciations.php',
                    ['sessionid' => $this->session->id]))->out(false),
            ];
            if ($previoussession) {
                $data['previouslabel'] = format_string($previoussession->code);
                $data['recoverbulkurl'] = (new \moodle_url('/local/kid/pages/capp_recover.php',
                    ['sessionid' => $this->session->id, 'sesskey' => sesskey()]))->out(false);
            }
            return $data;
        }

        $entry = capp_repository::get_entry_for_student((int) $this->session->id, $this->studentid);
        $steppositions = array_values(array_map(function ($step, $i) use ($entry) {
            $order = [workflow_service::STATUS_SAISIE, workflow_service::STATUS_VALIDE, workflow_service::STATUS_FINALISE];
            $currentidx = array_search($entry->workflowstatus, $order, true);
            return [
                'label' => $step['label'],
                'position' => $i + 1,
                'isdone' => $i < $currentidx,
                'isactive' => $i === $currentidx,
                'islast' => $i === count($order) - 1,
            ];
        }, $steps, array_keys($steps)));

        $data = [
            'summarymode' => false,
            'libelle' => format_string($this->session->code . ' — ' . $this->session->libelle),
            'studentnav' => student_nav_helper::build('capp', (int) $this->session->id,
                (int) $this->session->promotionid, $this->studentid),
            'steps' => $steppositions,
            'formhtml' => $this->formhtml,
            'conflictjson' => $this->conflict ? json_encode($this->conflict) : null,
            'workflowstatus' => $entry->workflowstatus,
            'ispublished' => (bool) $entry->published,
            'canvalidate' => $entry->workflowstatus === workflow_service::STATUS_SAISIE && $canevaluate,
            'canfinalise' => $entry->workflowstatus === workflow_service::STATUS_VALIDE && $canevaluate,
            'canreopen' => ($entry->workflowstatus === workflow_service::STATUS_FINALISE || $entry->published) && $canevaluate,
            'validateurl' => $this->action_url('valider'),
            'finaliseurl' => $this->action_url('finaliser'),
            'reopenurl' => $this->action_url('reopen'),
            'backurl' => (new \moodle_url('/local/kid/pages/capp.php',
                ['sessionid' => $this->session->id, 'mode' => 'saisie']))->out(false),
            'hasprevious' => (bool) $previoussession && $canevaluate,
            'canexport' => $canexport,
        ];
        if ($previoussession) {
            $data['previouslabel'] = format_string($previoussession->code);
            $data['recoveroneurl'] = (new \moodle_url('/local/kid/pages/capp_recover.php', [
                'sessionid' => $this->session->id, 'studentid' => $this->studentid, 'sesskey' => sesskey(),
            ]))->out(false);
        }
        if ($canexport) {
            $data['fichestudenturl_docx'] = (new \moodle_url('/local/kid/pages/fiche_download.php', [
                'studentid' => $this->studentid, 'promotionid' => $this->session->promotionid, 'format' => 'docx',
            ]))->out(false);
            $data['fichestudenturl_pdf'] = (new \moodle_url('/local/kid/pages/fiche_download.php', [
                'studentid' => $this->studentid, 'promotionid' => $this->session->promotionid, 'format' => 'pdf',
            ]))->out(false);
        }
        return $data;
    }

    /**
     * Same count table as the CAPP livret PDF's "Bilan général" section
     * (pdf_service::build_capp_bilan_html()), reshaped for
     * templates/capp_grid.mustache: mustache can't index a row by a
     * dynamic column key, so each row carries its counts as an ordered
     * `cells` list matching `cols`' order — same pattern as
     * comparateur_page.php's student cards.
     *
     * @return array{studentcount:int, cols:array, rows:array}
     */
    private static function build_bilan_view(int $sessionid): array {
        $bilan = capp_rapport_builder::build_bilan_table($sessionid);

        $colkeys = ['nonobserve', 'nonacquis', 'encours', 'acquisdla'];
        $cols = array_map(function ($key) {
            $colors = niveau_repository::bucket_colors($key);
            return [
                'label' => get_string('capp_rapport_col_' . $key, 'local_kid'),
                'bgcolor' => $colors['bg'],
                'fgcolor' => $colors['fg'],
            ];
        }, $colkeys);

        $rows = array_map(fn($row) => [
            'libelle' => $row->libelle,
            'cells' => array_map(fn($key) => ['value' => (int) $row->$key], $colkeys),
        ], $bilan->rows);

        return [
            'studentcount' => $bilan->studentcount,
            'cols' => $cols,
            'rows' => $rows,
        ];
    }

    private function action_url(string $action): string {
        return (new \moodle_url('/local/kid/pages/capp_workflow_action.php', [
            'sessionid' => $this->session->id, 'studentid' => $this->studentid, 'action' => $action, 'sesskey' => sesskey(),
        ]))->out(false);
    }

}
