<?php
declare(strict_types=1);

/**
 * helpers.php — shared helpers for ELMS
 * NOTE: no closing PHP tag to avoid accidental output/“unexpected '<'” errors.
 */

/* ------------ BASE_URL detection (e.g. /admin.edencampus.lk/elms) ------------ */
if (!defined('BASE_URL')) {
  $script = str_replace('\\','/', $_SERVER['SCRIPT_NAME'] ?? '');
  if (($p = strpos($script, '/elms/')) !== false) {
    $base = substr($script, 0, $p + 5); // keep “…/elms”
  } else {
    $base = rtrim(dirname($script), '/');
  }
  define('BASE_URL', $base);
}

/* ---------------------------- Output helpers ---------------------------- */
if (!function_exists('esc')) {
  function esc($s): string {
    return htmlspecialchars((string)$s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
  }
}

/* ----------------------------- URL helpers ----------------------------- */
if (!function_exists('app_url')) {
  function app_url(string $path = ''): string {
    $p = ($path === '') ? '' : ($path[0] === '/' ? $path : '/'.$path);
    return rtrim(BASE_URL, '/') . $p;
  }
}

if (!function_exists('url_for')) { // alias for legacy code
  function url_for(string $path = ''): string {
    return app_url($path);
  }
}

if (!function_exists('go')) {
  function go(string $path = '/'): void {
    header('Location: '.app_url($path));
    exit;
  }
}

/* ------------------------------ DB helpers ----------------------------- */
if (!function_exists('table_exists')) {
  function table_exists(?mysqli $db, string $t): bool {
    if (!($db instanceof mysqli)) return false;
    try {
      $st = $db->prepare(
        'SELECT 1 FROM INFORMATION_SCHEMA.TABLES
         WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? LIMIT 1'
      );
      $st->bind_param('s', $t);
      $st->execute();
      $ok = (bool)$st->get_result()->fetch_row();
      $st->close();
      return $ok;
    } catch (Throwable $e) { return false; }
  }
}

if (!function_exists('column_exists')) {
  function column_exists(?mysqli $db, string $t, string $c): bool {
    if (!($db instanceof mysqli)) return false;
    try {
      $st = $db->prepare(
        'SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
         WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ? LIMIT 1'
      );
      $st->bind_param('ss', $t, $c);
      $st->execute();
      $ok = (bool)$st->get_result()->fetch_row();
      $st->close();
      return $ok;
    } catch (Throwable $e) { return false; }
  }
}

if (!function_exists('label_column')) {
  /** Pick the first existing column from a preferred list, falling back to 'id'. */
  function label_column(?mysqli $db, string $table, array $candidates): string {
    if (!($db instanceof mysqli)) return 'id';
    try {
      $cols = [];
      $t = $db->real_escape_string($table);
      if ($rs = $db->query("SHOW COLUMNS FROM `$t`")) {
        while ($r = $rs->fetch_assoc()) $cols[] = $r['Field'];
      }
      foreach ($candidates as $c) if (in_array($c, $cols, true)) return $c;
    } catch (Throwable $e) {}
    return 'id';
  }
}

/* ------------------------------ CSRF (opt) ----------------------------- */
if (!function_exists('csrf_token')) {
  function csrf_token(): string {
    if (empty($_SESSION['csrf'])) $_SESSION['csrf'] = bin2hex(random_bytes(16));
    return $_SESSION['csrf'];
  }
}
if (!function_exists('csrf_check')) {
  function csrf_check(): bool {
    return isset($_POST['csrf']) && hash_equals($_SESSION['csrf'] ?? '', (string)($_POST['csrf'] ?? ''));
  }
}

// Ensure quiz tables/columns exist
// Accepts optional connection; falls back to global $mysqli.
// Safe to call multiple times (CREATE TABLE IF NOT EXISTS).
if (!function_exists('ensure_quiz_schema')) {
  function ensure_quiz_schema($conn = null){
    global $mysqli;
    $db = $conn ?: (isset($mysqli) ? $mysqli : null);
    if (!$db) { return; }

    $db->query("CREATE TABLE IF NOT EXISTS lms_quizzes (
      id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
      course_id INT UNSIGNED NOT NULL,
      module_id INT UNSIGNED NOT NULL,
      title VARCHAR(255) NOT NULL,
      description TEXT NULL,
      time_limit_sec INT NULL,
      max_attempts INT NULL,
      pass_score INT NULL,
      randomized TINYINT(1) NOT NULL DEFAULT 0,
      active TINYINT(1) NOT NULL DEFAULT 1,
      created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $db->query("CREATE TABLE IF NOT EXISTS lms_quiz_questions (
      id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
      quiz_id INT UNSIGNED NOT NULL,
      question_text TEXT NOT NULL,
      points INT NOT NULL DEFAULT 1,
      sort_order INT NOT NULL DEFAULT 0,
      KEY idx_quiz (quiz_id, sort_order)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $db->query("CREATE TABLE IF NOT EXISTS lms_quiz_options (
      id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
      question_id INT UNSIGNED NOT NULL,
      option_text TEXT NOT NULL,
      is_correct TINYINT(1) NOT NULL DEFAULT 0,
      sort_order INT NOT NULL DEFAULT 0,
      KEY idx_q (question_id, sort_order)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $db->query("CREATE TABLE IF NOT EXISTS lms_quiz_attempts (
      id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
      quiz_id INT UNSIGNED NOT NULL,
      student_id INT UNSIGNED NOT NULL,
      attempt_no INT NOT NULL DEFAULT 1,
      started_at DATETIME NULL,
      finished_at DATETIME NULL,
      score INT NULL,
      max_score INT NULL,
      percentage DECIMAL(6,2) NULL,
      passed TINYINT(1) NULL,
      KEY idx_qs (quiz_id, student_id),
      KEY idx_finished (finished_at)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $db->query("CREATE TABLE IF NOT EXISTS lms_quiz_answers (
      id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
      attempt_id INT UNSIGNED NOT NULL,
      question_id INT UNSIGNED NOT NULL,
      option_id INT UNSIGNED NULL,
      correct TINYINT(1) NULL,
      points_awarded INT NULL,
      KEY idx_attempt (attempt_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
  }
}
// ---------- UNIVERSAL UPLOAD PATH HELPERS (web <-> fs) ----------
if (!function_exists('app_root_dir')) {
  function app_root_dir(): string {
    // Points to /elms
    return realpath(__DIR__ . '/..') ?: dirname(__DIR__);
  }
}

if (!function_exists('app_base_web')) {
  function app_base_web(): string {
    // e.g. /admin.edencampus.lk/elms  (works from any sub-app)
    $script = $_SERVER['SCRIPT_NAME'] ?? '/elms/index.php';
    return rtrim(dirname($script, 1), '/');
  }
}

if (!function_exists('web_upload')) {
  // Build a web URL under /uploads
  function web_upload(string $rel): string {
    $rel = ltrim(str_replace('\\','/',$rel), '/');
    return app_base_web().'/uploads/'.$rel; // /.../elms/uploads/...
  }
}

if (!function_exists('fs_upload')) {
  // Build a filesystem path under /elms/uploads
  function fs_upload(string $rel): string {
    $rel = ltrim(str_replace(['\\','..'], ['/',''], $rel), '/');
    return app_root_dir().DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR
         . str_replace('/', DIRECTORY_SEPARATOR, $rel);
  }
}

if (!function_exists('web_to_fs')) {
  // Convert a stored web path (or accidental Windows path) to fs path
  function web_to_fs(string $path): string {
    $p = str_replace('\\','/',$path);

    // If path contains /uploads/... anywhere, normalize to fs_upload
    if (($pos = stripos($p, '/uploads/')) !== false) {
      $rel = substr($p, $pos + strlen('/uploads/'));
      return fs_upload($rel);
    }
    // If it begins with uploads/ or /uploads/ treat as relative under uploads
    if (preg_match('#^/?uploads/#i', $p)) {
      $rel = preg_replace('#^/?uploads/#i', '', $p);
      return fs_upload($rel);
    }
    // Fallback: treat as relative under uploads
    return fs_upload($p);
  }
}

if (!function_exists('fs_to_web')) {
  // Convert a filesystem path to a web /uploads/... path
  function fs_to_web(string $fs): string {
    $fs = str_replace('\\','/',$fs);
    if (($pos = stripos($fs, '/uploads/')) !== false) {
      return app_base_web().substr($fs, $pos);
    }
    return app_base_web().'/uploads/'.ltrim($fs,'/');
  }
}
 
// --- Add to includes/helpers.php ---

if (!function_exists('app_base')) {
  /** Returns app base like "/elms" (strips trailing /admin if any). */
  function app_base(): string {
    $script = $_SERVER['SCRIPT_NAME'] ?? '';
    $base   = rtrim(dirname(dirname($script)), '/'); // e.g. /elms/admin
    $base   = preg_replace('#/admin$#', '', $base);  // -> /elms
    return $base ?: '/';
  }
}

if (!function_exists('webify_submission_url')) {
  /**
   * Normalizes a stored file_path into a correct web URL:
   * - Keeps http(s) as-is
   * - /uploads/...   => /elms/uploads/...
   * - uploads/...    => /elms/uploads/...
   * - Windows paths  => /elms/uploads/submissions/<basename>
   * - Other relative => prefix with /elms/
   */
  function webify_submission_url(?string $p): string {
    $p = trim((string)$p);
    if ($p === '') return '#';

    if (preg_match('#^https?://#i', $p)) return $p;

    $p = str_replace('\\', '/', $p);

    if (preg_match('#^/elms/uploads/#i', $p)) return $p;

    $base = app_base(); // "/elms"

    if (preg_match('#^/uploads/#i', $p))  return $base . $p;
    if (preg_match('#^uploads/#i', $p))   return $base . '/' . ltrim($p, '/');

    if (preg_match('#^[A-Za-z]:/#', $p))  // Windows absolute
      return $base . '/uploads/submissions/' . basename($p);

    if ($p[0] !== '/') return $base . '/' . ltrim($p, '/');

    return $p;
  }
}
 
if (!function_exists('esc')) {
  function esc($s){ return htmlspecialchars((string)$s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
}
if (!function_exists('sql_val')) {
  function sql_val(string $sql, ?callable $binder=null){
    global $mysqli;
    try{
      $st = $mysqli->prepare($sql);
      if ($binder) $binder($st);
      $st->execute();
      $st->bind_result($v);
      $st->fetch();
      $st->close();
      return $v;
    }catch(Throwable $e){ return null; }
  }
}
if (!function_exists('kpi_count')) {
  function kpi_count(string $sql, ?callable $binder=null): int {
    $v = sql_val($sql, $binder);
    return (int)($v ?? 0);
  }
}

if (!function_exists('elms_base_url')) {
  function elms_base_url(): string {
    $sn = $_SERVER['SCRIPT_NAME'] ?? '/';
    $base = rtrim(dirname(dirname($sn)), '/');   // from /elms/admin/page.php -> /elms
    return $base !== '' ? $base : '/elms';
  }
}

