<?php
declare(strict_types=1);
require_once __DIR__ . '/tp_auth.php';
require_once dirname(__DIR__, 2) . '/lib/sba_engine.php';

$teacher_id = tp_require_auth();
$method     = $_SERVER['REQUEST_METHOD'];
$conn       = getDBConnection();
$ay         = (string)(getSettingValue('academic_year') ?? date('Y'));
$term       = (string)(getSettingValue('current_term')  ?? '');

// ── GET: students + current scores for a class+subject ─────────────────────
if ($method === 'GET') {
    $class_name = trim($_GET['class']   ?? '');
    $subject_id = (int)($_GET['subject'] ?? 0);

    // Primary: check class_subjects (has configured score weights)
    $stmt = $conn->prepare(
        "SELECT cs.class_score_percent, cs.exam_score_percent,
                cs.max_class_score,    cs.max_exam_score,
                s.subject_name
           FROM class_subjects cs
           JOIN subjects s ON s.id = cs.subject_id
          WHERE cs.class_name = ? AND cs.subject_id = ? AND cs.teacher_id = ?"
    );
    $stmt->bind_param('sii', $class_name, $subject_id, $teacher_id);
    $stmt->execute();
    $cs_row = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $use_defaults = false;
    if (!$cs_row) {
        // Fallback: timetable-only assignment (subject/visiting teachers)
        $stmt = $conn->prepare(
            "SELECT 1 FROM timetable_slots
              WHERE class_name = ? AND subject_id = ? AND teacher_id = ? AND academic_year = ?
              LIMIT 1"
        );
        $stmt->bind_param('siis', $class_name, $subject_id, $teacher_id, $ay);
        $stmt->execute();
        $allowed = $stmt->get_result()->num_rows > 0;
        $stmt->close();

        if (!$allowed) {
            tp_json(false, null, 'Subject not assigned to you for this class.');
        }

        // Use default Ghana Basic Education weights (30/70)
        $use_defaults = true;
        $stmt = $conn->prepare("SELECT subject_name FROM subjects WHERE id = ? LIMIT 1");
        $stmt->bind_param('i', $subject_id);
        $stmt->execute();
        $subrow = $stmt->get_result()->fetch_assoc();
        $stmt->close();

        $cs_row = [
            'subject_name'        => $subrow['subject_name'] ?? '',
            'max_class_score'     => 100.0,
            'max_exam_score'      => 100.0,
            'class_score_percent' => 30,
            'exam_score_percent'  => 70,
        ];
    }

    // Students
    $stmt = $conn->prepare(
        "SELECT st.id, st.student_id, st.first_name, st.last_name, st.photo_path,
                COALESCE(sc.class_score, 0)  AS class_score,
                COALESCE(sc.exam_score,  0)  AS exam_score,
                COALESCE(sc.total_score, 0)  AS total_score,
                COALESCE(sc.grade,       '')  AS grade,
                COALESCE(sc.remark,      '')  AS remark
           FROM students st
           LEFT JOIN scores sc ON sc.student_id = st.id
                               AND sc.subject_id = ?
                               AND sc.term        = ?
                               AND sc.academic_year = ?
          WHERE st.class = ? AND st.status = 'active'
          ORDER BY st.first_name, st.last_name"
    );
    $stmt->bind_param('isss', $subject_id, $term, $ay, $class_name);
    $stmt->execute();
    $students = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    $stmt->close();

    foreach ($students as &$s) {
        $s['photo_url'] = $s['photo_path']
            ? '../../' . ltrim($s['photo_path'], '/')
            : '../../assets/images/default-student.png';
    }
    unset($s);

    tp_json(true, [
        'class_name'         => $class_name,
        'subject_id'         => $subject_id,
        'subject_name'       => $cs_row['subject_name'],
        'max_class_score'    => (float)$cs_row['max_class_score'],
        'max_exam_score'     => (float)$cs_row['max_exam_score'],
        'class_score_pct'    => (int)$cs_row['class_score_percent'],
        'exam_score_pct'     => (int)$cs_row['exam_score_percent'],
        'students'           => $students,
        'term'               => $term,
        'academic_year'      => $ay,
    ]);
}

// ── POST: save scores ──────────────────────────────────────────────────────
if ($method === 'POST') {
    $input      = json_decode(file_get_contents('php://input'), true) ?? [];
    $class_name = trim((string)($input['class_name'] ?? ''));
    $subject_id = (int)($input['subject_id'] ?? 0);
    $records    = (array)($input['records'] ?? []);  // [{student_id, class_score, exam_score}]

    // Validate
    $stmt = $conn->prepare(
        "SELECT cs.max_class_score, cs.max_exam_score,
                cs.class_score_percent, cs.exam_score_percent
           FROM class_subjects cs
          WHERE cs.class_name = ? AND cs.subject_id = ? AND cs.teacher_id = ?"
    );
    $stmt->bind_param('sii', $class_name, $subject_id, $teacher_id);
    $stmt->execute();
    $cs_row = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    if (!$cs_row) {
        // Fallback: timetable-only assignment (visiting / subject-based teachers)
        $stmt = $conn->prepare(
            "SELECT 1 FROM timetable_slots
              WHERE class_name = ? AND subject_id = ? AND teacher_id = ? AND academic_year = ?
              LIMIT 1"
        );
        $stmt->bind_param('siis', $class_name, $subject_id, $teacher_id, $ay);
        $stmt->execute();
        $allowed = $stmt->get_result()->num_rows > 0;
        $stmt->close();

        if (!$allowed) {
            tp_json(false, null, 'Not authorised to enter marks for this class/subject.');
        }

        // Use Ghana Basic Education default weights (30/70)
        $cs_row = [
            'max_class_score'     => 100.0,
            'max_exam_score'      => 100.0,
            'class_score_percent' => 30,
            'exam_score_percent'  => 70,
        ];
    }

    $max_cs = (float)$cs_row['max_class_score'];
    $max_es = (float)$cs_row['max_exam_score'];
    $cs_pct = (int)$cs_row['class_score_percent'];
    $es_pct = (int)$cs_row['exam_score_percent'];

    // Load grade boundaries for this class
    $gb_stmt = $conn->prepare(
        "SELECT grade, remark, min_score, max_score
           FROM grade_boundaries
          WHERE (class_name = ? OR class_name = 'default')
            AND (academic_year = ? OR academic_year IS NULL)
          ORDER BY min_score DESC"
    );
    $gb_stmt->bind_param('ss', $class_name, $ay);
    $gb_stmt->execute();
    $grade_bounds = $gb_stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    $gb_stmt->close();

    $save_stmt = $conn->prepare(
        "INSERT INTO scores
           (student_id, subject_id, class_name, class_score, exam_score,
            raw_class_score, raw_exam_score,
            weighted_class_score, weighted_exam_score,
            total_score, grade, remark, term, academic_year)
         VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)
         ON DUPLICATE KEY UPDATE
           class_name           = VALUES(class_name),
           class_score          = VALUES(class_score),
           exam_score           = VALUES(exam_score),
           raw_class_score      = VALUES(raw_class_score),
           raw_exam_score       = VALUES(raw_exam_score),
           weighted_class_score = VALUES(weighted_class_score),
           weighted_exam_score  = VALUES(weighted_exam_score),
           total_score          = VALUES(total_score),
           grade                = VALUES(grade),
           remark               = VALUES(remark),
           updated_at           = NOW()"
    );

    // When SBA components exist for this class-subject, the continuous-assessment
    // score is derived from the component roll-up — the lump field is ignored so
    // the two entry paths cannot disagree.
    $sba_components = sbaGetComponents($conn, $class_name, $subject_id, $term, $ay);
    $use_sba_ca = !empty($sba_components);

    $saved = 0;
    foreach ($records as $rec) {
        $sid = (int)($rec['student_id'] ?? 0);
        if ($sid <= 0) continue;

        if ($use_sba_ca) {
            $rolled = sbaRolledUpClassScore($conn, $sid, $sba_components, $max_cs);
            $raw_cs = $rolled !== null ? $rolled : min((float)($rec['class_score'] ?? 0), $max_cs);
        } else {
            $raw_cs = min((float)($rec['class_score'] ?? 0), $max_cs);
        }
        $raw_es = min((float)($rec['exam_score']  ?? 0), $max_es);

        $w_cs    = $max_cs > 0 ? ($raw_cs / $max_cs) * $cs_pct : 0;
        $w_es    = $max_es > 0 ? ($raw_es / $max_es) * $es_pct : 0;
        $total   = round($w_cs + $w_es, 2);

        // Determine grade
        $grade  = 'W'; $remark = 'Weak';
        foreach ($grade_bounds as $gb) {
            if ($total >= (float)$gb['min_score'] && $total <= (float)$gb['max_score']) {
                $grade  = $gb['grade'];
                $remark = $gb['remark'];
                break;
            }
        }

        $save_stmt->bind_param(
            'iisdddddddssss',
            $sid, $subject_id, $class_name,
            $raw_cs, $raw_es,
            $raw_cs, $raw_es,
            $w_cs, $w_es,
            $total, $grade, $remark,
            $term, $ay
        );
        $save_stmt->execute();
        $saved++;
    }
    $save_stmt->close();

    tp_json(true, ['saved' => $saved], "Scores saved for {$saved} students.");
}
