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

/**
 * Read-only consolidated data for the dashboard's remaining sub-views
 * (Vue d'ensemble, Vue globale). The former cross-tab sub-views
 * (Compétences/Stages/Évaluations/CAPP/Évolution) and their shared
 * matrix-building methods were removed 2026-08-13 — the Comparateur de
 * bilans (comparateur_repository.php) replaces them with a single
 * cross-domain flatten function.
 *
 * @package    local_kid
 */

namespace local_kid\local;

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

class dashboard_repository {

    // ─── Vue d'ensemble ─────────────────────────────────────────────────

    public static function overview(int $promotionid): array {
        $students = promotion_repository::get_active_students($promotionid);
        $sessions = capp_repository::get_active_sessions_for_promotion($promotionid);

        $evalids = array_keys(array_filter(
            eval_repository::get_for_promotion($promotionid),
            fn($e) => (bool) $e->active
        ));
        $stageids = array_keys(array_filter(
            stage_repository::get_for_promotion($promotionid),
            fn($s) => (bool) $s->active
        ));

        $evalstocomplete = self::count_not_finalised('local_kid_eval_entry', 'evalid', $evalids);
        $stagestocomplete = self::count_not_finalised('local_kid_stage_entry', 'stageid', $stageids);

        $sessionids = array_map(fn($s) => $s->id, $sessions);
        $capptocomplete = self::count_not_finalised('local_kid_capp_entry', 'sessionid', $sessionids);
        $cappfinalised = empty($sessionids) ? 0 : self::count_by_status('local_kid_capp_entry', 'sessionid', $sessionids, 'finalise');

        $studentrows = [];
        foreach ($students as $student) {
            $cappstatuses = [];
            foreach ($sessions as $session) {
                $entry = capp_repository::get_entry_for_student((int) $session->id, (int) $student->studentid);
                $cappstatuses[] = [
                    'code' => format_string($session->code),
                    'statusbadge' => $entry ? workflow_service::render_status_badge($entry->workflowstatus) : '',
                ];
            }
            $studentrows[] = [
                'id' => (int) $student->studentid,
                'name' => fullname($student),
                'cappstatuses' => $cappstatuses,
                'openurl' => (new \moodle_url('/local/kid/pages/student.php', [
                    'studentid' => $student->studentid,
                ]))->out(false),
            ];
        }

        return [
            'studentcount' => count($students),
            'evalstocomplete' => $evalstocomplete,
            'stagestocomplete' => $stagestocomplete,
            'capptocomplete' => $capptocomplete,
            'cappfinalised' => $cappfinalised,
            'sessioncodes' => array_values(array_map(fn($s) => format_string($s->code), $sessions)),
            'students' => $studentrows,
        ];
    }

    /**
     * Cross-promotion overview for administrators — the same aggregate
     * counters as overview() but one row per promotion (active or not),
     * so a Scolarité/manager account has something useful to land on
     * before picking any one promotion.
     */
    public static function global_overview(): array {
        $promotions = promotion_repository::get_all();

        $rows = [];
        foreach ($promotions as $promotion) {
            $promotionid = (int) $promotion->id;
            $students = promotion_repository::get_active_students($promotionid);
            $sessions = capp_repository::get_active_sessions_for_promotion($promotionid);

            $evalids = array_keys(array_filter(
                eval_repository::get_for_promotion($promotionid),
                fn($e) => (bool) $e->active
            ));
            $stageids = array_keys(array_filter(
                stage_repository::get_for_promotion($promotionid),
                fn($s) => (bool) $s->active
            ));
            $sessionids = array_map(fn($s) => $s->id, $sessions);

            $rows[] = [
                'id' => $promotionid,
                'name' => format_string($promotion->name),
                'active' => (bool) $promotion->active,
                'cohortlinked' => (bool) $promotion->moodlecohortid,
                'studentcount' => count($students),
                'evalstocomplete' => self::count_not_finalised('local_kid_eval_entry', 'evalid', $evalids),
                'stagestocomplete' => self::count_not_finalised('local_kid_stage_entry', 'stageid', $stageids),
                'capptocomplete' => self::count_not_finalised('local_kid_capp_entry', 'sessionid', $sessionids),
                'cappfinalised' => empty($sessionids) ? 0 : self::count_by_status('local_kid_capp_entry', 'sessionid', $sessionids, 'finalise'),
                'openurl' => (new \moodle_url('/local/kid/pages/dashboard.php', ['promotionid' => $promotionid]))->out(false),
            ];
        }

        return [
            'promotioncount' => count($rows),
            'activecount' => count(array_filter($rows, fn($r) => $r['active'])),
            'totalstudents' => array_sum(array_column($rows, 'studentcount')),
            'promotions' => $rows,
        ];
    }

    private static function count_not_finalised(string $table, string $fk, array $ids): int {
        global $DB;
        if (empty($ids)) {
            return 0;
        }
        [$insql, $params] = $DB->get_in_or_equal($ids);
        $params[] = 'finalise';
        return (int) $DB->count_records_select($table, "$fk $insql AND workflowstatus <> ?", $params);
    }

    private static function count_by_status(string $table, string $fk, array $ids, string $status): int {
        global $DB;
        if (empty($ids)) {
            return 0;
        }
        [$insql, $params] = $DB->get_in_or_equal($ids);
        $params[] = $status;
        return (int) $DB->count_records_select($table, "$fk $insql AND workflowstatus = ?", $params);
    }
}
