<?php
/**
 * Access Control Functions
 * This file contains functions to check user permissions and restrict access based on roles
 */

/**
 * Check if user is logged in
 * 
 * @return bool
 */
function is_logged_in() {
    return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
}

/**
 * Check if user has a specific role
 * 
 * @param string $role The role to check for
 * @return bool
 */
function has_role($role) {
    return isset($_SESSION['user_role']) && $_SESSION['user_role'] === $role;
}

/**
 * Check if user is an admin
 * 
 * @return bool
 */
function is_admin() {
    return has_role('admin');
}

/**
 * Check if user is a teacher
 * 
 * @return bool
 */
function is_teacher() {
    return has_role('teacher');
}

/**
 * Check if user is a student
 * 
 * @return bool
 */
function is_student() {
    return has_role('student');
}

/**
 * Require admin access - redirects to login if user is not admin
 * 
 * @param string $redirect_url URL to redirect to if access is denied (default: ../login.php)
 */
function require_admin($redirect_url = '../login.php') {
    if (!is_logged_in() || !is_admin()) {
        header("Location: $redirect_url");
        exit();
    }
}

/**
 * Require teacher access - redirects to login if user is not teacher
 * 
 * @param string $redirect_url URL to redirect to if access is denied (default: ../login.php)
 */
function require_teacher($redirect_url = '../login.php') {
    if (!is_logged_in() || !is_teacher()) {
        header("Location: $redirect_url");
        exit();
    }
}

/**
 * Require student access - redirects to login if user is not student
 * 
 * @param string $redirect_url URL to redirect to if access is denied (default: ../login.php)
 */
function require_student($redirect_url = '../login.php') {
    if (!is_logged_in() || !is_student()) {
        header("Location: $redirect_url");
        exit();
    }
}

/**
 * Require any of the specified roles - redirects to login if user doesn't have any of the roles
 * 
 * @param array $roles Array of roles that are allowed access
 * @param string $redirect_url URL to redirect to if access is denied (default: ../login.php)
 */
function require_any_role($roles, $redirect_url = '../login.php') {
    if (!is_logged_in()) {
        header("Location: $redirect_url");
        exit();
    }
    
    $has_access = false;
    foreach ($roles as $role) {
        if (has_role($role)) {
            $has_access = true;
            break;
        }
    }
    
    if (!$has_access) {
        header("Location: $redirect_url");
        exit();
    }
}

/**
 * Check if user has admin access
 * 
 * @return bool
 */
function check_admin_access() {
    return is_logged_in() && is_admin();
}

/**
 * Check if user has teacher access
 * 
 * @return bool
 */
function check_teacher_access() {
    return is_logged_in() && is_teacher();
}

/**
 * Check if user has student access
 * 
 * @return bool
 */
function check_student_access() {
    return is_logged_in() && is_student();
}

/**
 * Check if user has any of the specified roles
 *
 * @param array $roles Array of roles to check
 * @return bool
 */
function check_any_role_access($roles) {
    if (!is_logged_in()) {
        return false;
    }

    foreach ($roles as $role) {
        if (has_role($role)) {
            return true;
        }
    }

    return false;
}

/**
 * Get teacher's assigned classes
 *
 * @param int $teacher_id Teacher ID
 * @return array Array of assigned class IDs
 */
function get_teacher_assigned_classes($teacher_id) {
    global $pdo;

    if (!$teacher_id) {
        return [];
    }

    // Get classes where this teacher is assigned (either as primary or assistant)
    $stmt = $pdo->prepare("
        SELECT DISTINCT c.id
        FROM classes c
        JOIN class_teachers ct ON c.id = ct.class_id
        WHERE ct.teacher_id = ? AND ct.status = 'active' AND c.status = 'active'
    ");
    $stmt->execute([$teacher_id]);
    $assigned_classes = $stmt->fetchAll(PDO::FETCH_COLUMN);

    // Also get classes where this teacher teaches subjects (for backward compatibility)
    $stmt = $pdo->prepare("
        SELECT DISTINCT c.id
        FROM classes c
        JOIN class_subjects cs ON c.id = cs.class_id
        WHERE cs.teacher_id = ? AND c.status = 'active'
    ");
    $stmt->execute([$teacher_id]);
    $subject_classes = $stmt->fetchAll(PDO::FETCH_COLUMN);

    // Merge both arrays, avoiding duplicates
    return array_unique(array_merge($assigned_classes, $subject_classes));
}

/**
 * Get teacher's assigned subjects
 *
 * @param int $teacher_id Teacher ID
 * @param array $class_ids Optional array of class IDs to filter subjects
 * @return array Array of assigned subject IDs
 */
function get_teacher_assigned_subjects($teacher_id, $class_ids = []) {
    global $pdo;

    if (!$teacher_id) {
        return [];
    }

    if (!empty($class_ids)) {
        // Get subjects for specific classes
        $placeholders = str_repeat('?,', count($class_ids) - 1) . '?';
        $stmt = $pdo->prepare("
            SELECT DISTINCT s.id
            FROM subjects s
            JOIN class_subjects cs ON s.id = cs.subject_id
            WHERE cs.class_id IN ($placeholders) AND s.status = 'active'
        ");
        $stmt->execute($class_ids);
    } else {
        // Get all subjects taught by this teacher
        $stmt = $pdo->prepare("
            SELECT DISTINCT s.id
            FROM subjects s
            JOIN class_subjects cs ON s.id = cs.subject_id
            WHERE cs.teacher_id = ? AND s.status = 'active'
        ");
        $stmt->execute([$teacher_id]);
    }

    return $stmt->fetchAll(PDO::FETCH_COLUMN);
}

/**
 * Check if teacher has access to a specific class
 *
 * @param int $teacher_id Teacher ID
 * @param int $class_id Class ID to check
 * @return bool
 */
function teacher_has_class_access($teacher_id, $class_id) {
    $assigned_classes = get_teacher_assigned_classes($teacher_id);
    return in_array($class_id, $assigned_classes);
}

/**
 * Check if teacher has access to a specific subject
 *
 * @param int $teacher_id Teacher ID
 * @param int $subject_id Subject ID to check
 * @param int $class_id Optional class ID for additional validation
 * @return bool
 */
function teacher_has_subject_access($teacher_id, $subject_id, $class_id = null) {
    $assigned_subjects = get_teacher_assigned_subjects($teacher_id, $class_id ? [$class_id] : []);
    return in_array($subject_id, $assigned_subjects);
}

/**
 * Check if teacher has access to a specific student (student must be in teacher's assigned classes)
 *
 * @param int $teacher_id Teacher ID
 * @param int $student_id Student ID to check
 * @return bool
 */
function teacher_has_student_access($teacher_id, $student_id) {
    global $pdo;

    $assigned_classes = get_teacher_assigned_classes($teacher_id);
    if (empty($assigned_classes)) {
        return false;
    }

    // Check if student belongs to one of teacher's assigned classes
    $placeholders = str_repeat('?,', count($assigned_classes) - 1) . '?';
    $stmt = $pdo->prepare("SELECT COUNT(*) FROM students WHERE id = ? AND class_id IN ($placeholders)");
    $stmt->execute(array_merge([$student_id], $assigned_classes));

    return $stmt->fetchColumn() > 0;
}

/**
 * Validate teacher access to class and subject combination
 *
 * @param int $teacher_id Teacher ID
 * @param int $class_id Class ID
 * @param int $subject_id Subject ID
 * @return array ['valid' => bool, 'error' => string]
 */
function validate_teacher_class_subject_access($teacher_id, $class_id, $subject_id) {
    if (!teacher_has_class_access($teacher_id, $class_id)) {
        return ['valid' => false, 'error' => 'আপনি এই ক্লাসের জন্য অ্যাক্সেস পাওয়ার অধিকারী নন।'];
    }

    if (!teacher_has_subject_access($teacher_id, $subject_id, $class_id)) {
        return ['valid' => false, 'error' => 'আপনি এই বিষয়ের জন্য অ্যাক্সেস পাওয়ার অধিকারী নন।'];
    }

    return ['valid' => true, 'error' => ''];
}
?>