<?php
// questions_ajax.php
// Single endpoint for all AJAX actions.
// Requires config.php which provides $dbh (PDO) and session with teacher_id.

session_start();
require_once 'config.php'; // expects $dbh (PDO)

$teacher_id = $_SESSION['teacher_id'] ?? null;
if (!$teacher_id) {
  echo json_encode(['success'=>false,'error'=>'Not authenticated']);
  exit;
}

header('Content-Type: application/json; charset=utf-8');

$action = $_POST['action'] ?? '';

try {
  switch ($action) {
    case 'load_selects':
      echo json_encode(load_selects($dbh));
      break;

    case 'load_questions':
      $session_id = empty($_POST['session_id']) ? null : intval($_POST['session_id']);
      $student_class = empty($_POST['student_class']) ? null : $_POST['student_class'];
      $term_id = empty($_POST['term_id']) ? null : intval($_POST['term_id']);
      $subject_id = empty($_POST['subject_id']) ? null : intval($_POST['subject_id']);
      echo json_encode(load_questions($dbh, $teacher_id, $session_id, $student_class, $term_id, $subject_id));
      break;

    case 'add_question':
      $payload = $_POST;
      echo json_encode(add_or_edit_question($dbh, $teacher_id, $payload, false));
      break;

    case 'edit_question':
      $payload = $_POST;
      echo json_encode(add_or_edit_question($dbh, $teacher_id, $payload, true));
      break;

    case 'get_question':
      $id = intval($_POST['id'] ?? 0);
      echo json_encode(get_question($dbh, $teacher_id, $id));
      break;

    case 'delete_question':
      $id = intval($_POST['id'] ?? 0);
      echo json_encode(delete_question($dbh, $teacher_id, $id));
      break;

    case 'delete_bulk':
      $ids = json_decode($_POST['ids'] ?? '[]', true);
      echo json_encode(delete_bulk($dbh, $teacher_id, $ids));
      break;

    case 'bulk_change_session':
      $ids = json_decode($_POST['ids'] ?? '[]', true);
      $new_session_id = intval($_POST['new_session_id'] ?? 0);
      echo json_encode(bulk_change_session($dbh, $teacher_id, $ids, $new_session_id));
      break;

    default:
      echo json_encode(['success'=>false,'error'=>'Unknown action']);
  }
} catch (Exception $e) {
  echo json_encode(['success'=>false,'error'=>'Server error: '.$e->getMessage()]);
}

/* --- Handlers --- */

function load_selects($dbh) {
  // sessions
  $s = $dbh->query("SELECT id, session_year FROM sessions ORDER BY session_year DESC")->fetchAll(PDO::FETCH_ASSOC);
  $t = $dbh->query("SELECT id, term_name FROM terms ORDER BY id ASC")->fetchAll(PDO::FETCH_ASSOC);
  $c = $dbh->query("SELECT id, name FROM classes ORDER BY name")->fetchAll(PDO::FETCH_ASSOC);
  $subs = $dbh->query("SELECT id, name FROM ubjects ORDER BY name")->fetchAll(PDO::FETCH_ASSOC);
  return ['success'=>true,'sessions'=>$s,'terms'=>$t,'classes'=>$c,'subjects'=>$subs];
}

function load_questions($dbh, $teacher_id, $session_id=null, $student_class=null, $term_id=null, $subject_id=null) {
  $sql = "SELECT q.*, s.session_year, t.term_name, sub.name as subject_name
          FROM questions q
          LEFT JOIN sessions s ON s.id = q.session_id
          LEFT JOIN terms t ON t.id = q.term_id
          LEFT JOIN Subjects sub ON sub.id = q.subject_id
          WHERE q.teacher_id = :teacher_id";
  $params = [':teacher_id'=>$teacher_id];
  if ($session_id) { $sql .= " AND q.session_id = :session_id"; $params[':session_id']=$session_id; }
  if ($student_class) { $sql .= " AND q.student_class = :student_class"; $params[':student_class']=$student_class; }
  if ($term_id) { $sql .= " AND q.term_id = :term_id"; $params[':term_id']=$term_id; }
  if ($subject_id) { $sql .= " AND q.subject_id = :subject_id"; $params[':subject_id']=$subject_id; }
  $sql .= " ORDER BY q.id DESC LIMIT 500";
  $stmt = $dbh->prepare($sql);
  $stmt->execute($params);
  $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  return ['success'=>true,'questions'=>$rows];
}

function add_or_edit_question($dbh, $teacher_id, $payload, $isEdit=false) {
  // sanitize / extract
  $id = intval($payload['id'] ?? 0);
  $student_class = $payload['student_class'] ?? null;
  $term_id = empty($payload['term_id']) ? null : intval($payload['term_id']);
  $session_id = empty($payload['session_id']) ? null : intval($payload['session_id']);
  $subject_id = empty($payload['subject_id']) ? null : intval($payload['subject_id']);
  $type = $payload['type'] ?? null;
  $question_text = $payload['question_text'] ?? null;
  $set_time_minutes = isset($payload['set_time_minutes']) && $payload['set_time_minutes'] !== '' ? intval($payload['set_time_minutes']) : null;
  $correct_answer = $payload['correct_answer'] ?? null;

  if (!$student_class || !$session_id || !$term_id || !$subject_id || !$type || !$question_text) {
    return ['success'=>false,'error'=>'Missing required fields'];
  }

  // handle options for objective: input is comma-separated in options field -> convert to JSON array
  $options_raw = $payload['options'] ?? '';
  $options_json = null;
  if ($type === 'objective') {
    $arr = array_filter(array_map('trim', explode(',', $options_raw)));
    if (count($arr) < 2) return ['success'=>false,'error'=>'Provide at least two options for objective question.'];
    $options_json = json_encode(array_values($arr));
    if (!$correct_answer) return ['success'=>false,'error'=>'Provide correct answer for objective question.'];
    // ensure correct_answer matches one option (exact match)
    $found = false;
    foreach ($arr as $opt) if ($opt === trim($correct_answer)) { $found = true; break; }
    if (!$found) {
      // allow if user provided A/B/C style (index) -> try to map
      // but prefer strict matching; return error
      return ['success'=>false,'error'=>'Correct answer must exactly match one of the provided options.'];
    }
  } else {
    // for fill/theory, options_json left null
    $options_json = null;
  }

  if ($isEdit) {
    // verify ownership
    $stmt = $dbh->prepare("SELECT id FROM questions WHERE id = :id AND teacher_id = :teacher_id LIMIT 1");
    $stmt->execute([':id'=>$id, ':teacher_id'=>$teacher_id]);
    if (!$stmt->fetch()) return ['success'=>false,'error'=>'Question not found or access denied.'];

    $sql = "UPDATE questions SET student_class = :student_class, term_id = :term_id, session_id = :session_id,
            subject_id = :subject_id, type = :type, question_text = :question_text, options = :options,
            correct_answer = :correct_answer, set_time_minutes = :set_time_minutes
            WHERE id = :id";
    $stmt = $dbh->prepare($sql);
    $stmt->execute([
      ':student_class'=>$student_class, ':term_id'=>$term_id, ':session_id'=>$session_id,
      ':subject_id'=>$subject_id, ':type'=>$type, ':question_text'=>$question_text,
      ':options'=>$options_json, ':correct_answer'=>$correct_answer, ':set_time_minutes'=>$set_time_minutes,
      ':id'=>$id
    ]);
    return ['success'=>true];
  } else {
    $sql = "INSERT INTO questions (teacher_id, student_class, term_id, session_id, subject_id, type, question_text, options, correct_answer, set_time_minutes)
            VALUES (:teacher_id, :student_class, :term_id, :session_id, :subject_id, :type, :question_text, :options, :correct_answer, :set_time_minutes)";
    $stmt = $dbh->prepare($sql);
    $stmt->execute([
      ':teacher_id'=>$teacher_id, ':student_class'=>$student_class, ':term_id'=>$term_id, ':session_id'=>$session_id,
      ':subject_id'=>$subject_id, ':type'=>$type, ':question_text'=>$question_text,
      ':options'=>$options_json, ':correct_answer'=>$correct_answer, ':set_time_minutes'=>$set_time_minutes
    ]);
    return ['success'=>true, 'insert_id' => $dbh->lastInsertId()];
  }
}

function get_question($dbh, $teacher_id, $id) {
  if (!$id) return ['success'=>false,'error'=>'Missing id'];
  $stmt = $dbh->prepare("SELECT * FROM questions WHERE id = :id AND teacher_id = :teacher_id LIMIT 1");
  $stmt->execute([':id'=>$id, ':teacher_id'=>$teacher_id]);
  $row = $stmt->fetch(PDO::FETCH_ASSOC);
  if (!$row) return ['success'=>false,'error'=>'Not found'];
  return ['success'=>true,'question'=>$row];
}

function delete_question($dbh, $teacher_id, $id) {
  if (!$id) return ['success'=>false,'error'=>'Missing id'];
  $stmt = $dbh->prepare("DELETE FROM questions WHERE id = :id AND teacher_id = :teacher_id");
  $stmt->execute([':id'=>$id, ':teacher_id'=>$teacher_id]);
  return ['success'=>true];
}

function delete_bulk($dbh, $teacher_id, $ids) {
  if (!is_array($ids) || count($ids) === 0) return ['success'=>false,'error'=>'No ids'];
  // prepare placeholders safely
  $placeholders = implode(',', array_fill(0, count($ids), '?'));
  $params = $ids;
  array_unshift($params, $teacher_id); // teacher first
  $sql = "DELETE FROM questions WHERE teacher_id = ? AND id IN ($placeholders)";
  $stmt = $dbh->prepare($sql);
  $stmt->execute($params);
  return ['success'=>true];
}

function bulk_change_session($dbh, $teacher_id, $ids, $new_session_id) {
  if (!is_array($ids) || count($ids) === 0) return ['success'=>false,'error'=>'No ids'];
  if (!$new_session_id) return ['success'=>false,'error'=>'Missing new session'];
  $placeholders = implode(',', array_fill(0, count($ids), '?'));
  $params = $ids;
  array_unshift($params, $teacher_id);
  // construct param array for execute (teacher_id + ids)
  $sql = "UPDATE questions SET session_id = :new_session WHERE teacher_id = :teacher_id AND id IN ($placeholders)";
  $stmt = $dbh->prepare($sql);
  // bind teacher_id and new_session specially
  $bindParams = [];
  foreach ($ids as $k => $v) $bindParams[($k+1)] = $v; // numeric placeholders
  // execute with named + positional isn't easy; instead build final SQL with numeric placeholders and execute
  $sql2 = "UPDATE questions SET session_id = ? WHERE teacher_id = ? AND id IN ($placeholders)";
  $stmt2 = $dbh->prepare($sql2);
  $execParams = array_merge([$new_session_id, $teacher_id], $ids);
  $stmt2->execute($execParams);
  return ['success'=>true];
}
