<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Evaluation;
use App\Models\EvaluationResult;
use App\Models\ExamMark;
use App\Models\Student;
use App\Models\Subject;
use Illuminate\Http\Request;

/**
 * Supplementary / improvement class — auto-collects, from every class, the
 * students who are scoring below the pass threshold (default 50%) in one or
 * more subjects, so weak learners can be grouped into remedial sessions.
 *
 * The board is organised two ways at once:
 *  - by subject  : "Math needs 8 students" → run one remedial group per subject
 *  - by student  : each struggling student with the list of subjects they fail
 */
class SupplementaryController extends Controller
{
    public function index(Request $request)
    {
        $branchId = $request->header('X-Branch-Id') ?: $request->query('branch_id');
        $classId = $request->query('class_id');
        $threshold = (float) ($request->query('threshold') ?: 50);

        $students = Student::where('status', 'active')
            ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
            ->when($classId, fn ($q) => $q->where('class_id', $classId))
            ->with('schoolClass:id,name')->get()->keyBy('id');
        $ids = $students->keys();

        if ($ids->isEmpty()) {
            return response()->json(['threshold' => $threshold, 'subjects' => [], 'students' => [], 'total' => 0]);
        }

        $subjectNames = Subject::pluck('name', 'id');

        // Collect per (student, subject) percentage from both evaluations and exams.
        // Each source contributes its own average; the two are then blended.
        $evalIds = Evaluation::where('status', 'completed')->pluck('id');
        $buckets = []; // [studentId][subjectId] => ['sum'=>, 'n'=>]

        $accumulate = function ($rows) use (&$buckets) {
            foreach ($rows as $r) {
                if ($r->subject_id === null || $r->marks === null) {
                    continue;
                }
                $max = $r->max_marks ?: 100;
                if ($max <= 0) {
                    continue;
                }
                $pct = min(100, $r->marks / $max * 100);
                $buckets[$r->student_id][$r->subject_id][] = $pct;
            }
        };

        $accumulate(EvaluationResult::whereIn('evaluation_id', $evalIds)
            ->whereIn('student_id', $ids)->whereNotNull('marks')
            ->get(['student_id', 'subject_id', 'marks', 'max_marks']));
        $accumulate(ExamMark::whereIn('student_id', $ids)->whereNotNull('marks')
            ->get(['student_id', 'subject_id', 'marks', 'max_marks']));

        // Build the two views.
        $subjectGroups = []; // subjectId => list of student rows
        $studentRows = [];   // studentId => ['weak' => [...subjects], 'avg' => ]

        foreach ($buckets as $sid => $subjects) {
            if (! isset($students[$sid])) {
                continue;
            }
            $s = $students[$sid];
            foreach ($subjects as $subjId => $pcts) {
                $pct = round(array_sum($pcts) / count($pcts), 1);
                if ($pct >= $threshold) {
                    continue;
                }
                $subjName = $subjectNames[$subjId] ?? '—';
                $row = [
                    'id' => $sid,
                    'name' => $s->full_name ?? '—',
                    'photo' => $s->photo ?? null,
                    'gender' => $s->gender ?? null,
                    'class_name' => $s->schoolClass?->name,
                    'subject' => $subjName,
                    'pct' => $pct,
                ];
                $subjectGroups[$subjId]['name'] = $subjName;
                $subjectGroups[$subjId]['students'][] = $row;

                $studentRows[$sid] ??= [
                    'id' => $sid,
                    'name' => $s->full_name ?? '—',
                    'photo' => $s->photo ?? null,
                    'gender' => $s->gender ?? null,
                    'class_name' => $s->schoolClass?->name,
                    'weak' => [],
                ];
                $studentRows[$sid]['weak'][] = ['subject' => $subjName, 'pct' => $pct];
            }
        }

        // Shape subject groups: sort by neediest (most students) first.
        $subjects = collect($subjectGroups)->map(fn ($g, $id) => [
            'subject_id' => $id,
            'subject' => $g['name'],
            'count' => count($g['students']),
            'students' => collect($g['students'])->sortBy('pct')->values(),
        ])->sortByDesc('count')->values();

        // Shape student rows: worst average weak-subject first, most subjects up top.
        $studentsOut = collect($studentRows)->map(function ($r) {
            $r['weak'] = collect($r['weak'])->sortBy('pct')->values();
            $r['weak_count'] = $r['weak']->count();
            $r['avg'] = round($r['weak']->avg('pct'), 1);
            return $r;
        })->sortByDesc('weak_count')->values();

        return response()->json([
            'threshold' => $threshold,
            'subjects' => $subjects,
            'students' => $studentsOut,
            'total' => $studentsOut->count(),
        ]);
    }
}
