<?php
/**
 * Base Controller Class with Command/Zone Filtering
 */
class Controller {
    
    /**
     * Load a view
     */
    protected function view($view, $data = []) {
        extract($data);
        
        $viewFile = BASE_PATH . '/views/' . $view . '.php';
        
        if (file_exists($viewFile)) {
            require_once $viewFile;
        } else {
            die("View not found: " . $view);
        }
    }
    
    /**
     * Load a model
     */
    protected function model($model) {
        $modelFile = BASE_PATH . '/models/' . $model . '.php';
        
        if (file_exists($modelFile)) {
            require_once $modelFile;
            return new $model();
        } else {
            die("Model not found: " . $model);
        }
    }
    
    /**
     * Redirect to a URL
     */
    protected function redirect($url, $messages = []) {
        foreach ($messages as $type => $message) {
            Session::set($type, $message);
        }
        
        Router::redirect($url);
    }
    
    /**
     * Return JSON response
     */
    protected function json($data, $statusCode = 200) {
        http_response_code($statusCode);
        header('Content-Type: application/json');
        echo json_encode($data);
        exit;
    }
    
    /**
     * Check if request is AJAX
     */
    protected function isAjax() {
        return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && 
               strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
    }
    
    /**
     * Get request input
     */
    protected function input($key = null, $default = null) {
        if ($key === null) {
            return $_REQUEST;
        }
        
        return $_REQUEST[$key] ?? $default;
    }
    
    /**
     * Get file upload
     */
    protected function file($key) {
        return $_FILES[$key] ?? null;
    }
    
    // =============================================
    // COMMAND/ZONE FILTERING METHODS
    // =============================================
    
    /**
     * Get the current user's command ID
     */
    protected function getUserCommandId() {
        return $_SESSION['command_id'] ?? null;
    }
    
    /**
     * Get the current user's zone ID
     */
    protected function getUserZoneId() {
        return $_SESSION['zone_id'] ?? null;
    }
    
    /**
     * Get the current user's roles
     */
    protected function getUserRoles() {
        return $_SESSION['roles'] ?? [];
    }
    
    /**
     * Check if user is Super Admin
     */
    protected function isSuperAdmin() {
        $isSuperAdmin = isset($_SESSION['is_super_admin']) && $_SESSION['is_super_admin'] === true;
        $roles = $this->getUserRoles();
        return $isSuperAdmin || in_array('Super Admin Officer', $roles);
    }
    
    /**
     * Check if user is Armourer
     */
    protected function isArmourer() {
        $roles = $this->getUserRoles();
        return in_array('Armourer', $roles);
    }
    
    /**
     * Check if user is Command Armourer
     */
    protected function isCommandArmourer() {
        $roles = $this->getUserRoles();
        return in_array('Command Armourer', $roles);
    }
    
    /**
     * Check if user is Command Approval Officer
     */
    protected function isCommandApprovalOfficer() {
        $roles = $this->getUserRoles();
        return in_array('Command Approval Officer', $roles);
    }
    
    /**
     * Check if user is HQ Vetting Officer
     */
    protected function isHQVettingOfficer() {
        $roles = $this->getUserRoles();
        return in_array('HQ Vetting Officer', $roles);
    }
    
    /**
     * Check if user is Sectional Head Transport
     */
    protected function isSectionalHeadTransport() {
        $roles = $this->getUserRoles();
        return in_array('Sectional Head Transport', $roles);
    }
    
    /**
     * Check if user is Sectional Head ICT
     */
    protected function isSectionalHeadICT() {
        $roles = $this->getUserRoles();
        return in_array('Sectional Head ICT', $roles);
    }
    
    /**
     * Check if user is Command Data Entry Officer
     */
    protected function isCommandDataEntryOfficer() {
        $roles = $this->getUserRoles();
        return in_array('Command Data Entry Officer', $roles);
    }
    
    /**
     * Check if user is HQ Sectional Supervisor
     */
    protected function isHQSectionalSupervisor() {
        $roles = $this->getUserRoles();
        return in_array('HQ Sectional Supervisor', $roles);
    }
    
    /**
     * Check if user has requisition-only access
     */
    protected function hasRequisitionOnlyAccess() {
        return $this->isCommandArmourer() || $this->isCommandApprovalOfficer() || $this->isHQVettingOfficer();
    }
    
    /**
     * Check if user has full weapons access
     */
    protected function hasFullWeaponsAccess() {
        return $this->isSuperAdmin() || $this->isArmourer();
    }
    
    /**
     * Add command filter to SQL query
     * 
     * @param string $tableAlias The table alias (e.g., 'v', 'a', 'm')
     * @param string $column The column name (default: 'command_id')
     * @return string The SQL WHERE clause for command filtering
     */
    protected function addCommandFilter($tableAlias = null, $column = 'command_id') {
        // Super Admin sees everything
        if ($this->isSuperAdmin()) {
            return '';
        }
        
        $prefix = $tableAlias ? $tableAlias . '.' : '';
        $commandId = $this->getUserCommandId();
        
        if ($commandId) {
            return " AND {$prefix}{$column} = " . intval($commandId);
        }
        
        return '';
    }
    
    /**
     * Add zone filter to SQL query
     * 
     * @param string $tableAlias The table alias
     * @param string $column The column name (default: 'zone_id')
     * @return string The SQL WHERE clause for zone filtering
     */
    protected function addZoneFilter($tableAlias = null, $column = 'zone_id') {
        // Super Admin sees everything
        if ($this->isSuperAdmin()) {
            return '';
        }
        
        $prefix = $tableAlias ? $tableAlias . '.' : '';
        $zoneId = $this->getUserZoneId();
        
        if ($zoneId) {
            return " AND {$prefix}{$column} = " . intval($zoneId);
        }
        
        return '';
    }
    
    /**
     * Get filtered data based on user's command
     * 
     * @param string $table The table name
     * @param string $columns The columns to select
     * @param string $additionalWhere Additional WHERE conditions
     * @param string $orderBy Order by clause
     * @return array The filtered data
     */
    protected function getFilteredData($table, $columns = '*', $additionalWhere = '', $orderBy = 'created_at DESC') {
        $filter = $this->addCommandFilter();
        $where = $filter ? " WHERE 1=1 $filter" : '';
        
        if ($additionalWhere) {
            if ($where) {
                $where .= " AND $additionalWhere";
            } else {
                $where = " WHERE $additionalWhere";
            }
        }
        
        $sql = "SELECT $columns FROM $table $where ORDER BY $orderBy";
        return Database::fetchAll($sql);
    }
    
    /**
     * Get filtered data with joins
     * 
     * @param string $sql Base SQL query
     * @param string $filterColumn The column to filter on
     * @param string $tableAlias The table alias for the filter column
     * @return string The modified SQL with command filter
     */
    protected function applyCommandFilterToSql($sql, $filterColumn = 'command_id', $tableAlias = null) {
        if ($this->isSuperAdmin()) {
            return $sql;
        }
        
        $commandId = $this->getUserCommandId();
        if (!$commandId) {
            return $sql;
        }
        
        $prefix = $tableAlias ? $tableAlias . '.' : '';
        
        // Check if WHERE clause already exists
        if (stripos($sql, 'WHERE') !== false) {
            $sql .= " AND {$prefix}{$filterColumn} = $commandId";
        } else {
            $sql .= " WHERE {$prefix}{$filterColumn} = $commandId";
        }
        
        return $sql;
    }
    
    /**
     * Verify that a user has access to a specific asset
     * 
     * @param string $table The table name
     * @param int $assetId The asset ID
     * @param string $commandColumn The command column name
     * @return bool True if user has access
     */
    protected function verifyAssetAccess($table, $assetId, $commandColumn = 'command_id') {
        // Super Admin has access to everything
        if ($this->isSuperAdmin()) {
            return true;
        }
        
        $commandId = $this->getUserCommandId();
        if (!$commandId) {
            return false;
        }
        
        $asset = Database::fetchOne(
            "SELECT $commandColumn FROM $table WHERE id = ?",
            [$assetId]
        );
        
        return $asset && $asset[$commandColumn] == $commandId;
    }
    
    /**
     * Get commands for the user's zone (for dropdowns)
     */
    protected function getUserCommands() {
        if ($this->isSuperAdmin()) {
            return Database::fetchAll("SELECT * FROM commands ORDER BY command_name");
        }
        
        $zoneId = $this->getUserZoneId();
        if ($zoneId) {
            return Database::fetchAll(
                "SELECT * FROM commands WHERE zone_id = ? ORDER BY command_name",
                [$zoneId]
            );
        }
        
        $commandId = $this->getUserCommandId();
        if ($commandId) {
            return Database::fetchAll(
                "SELECT * FROM commands WHERE id = ? ORDER BY command_name",
                [$commandId]
            );
        }
        
        return [];
    }
    
    /**
     * Get zones for the user (for dropdowns)
     */
    protected function getUserZones() {
        if ($this->isSuperAdmin()) {
            return Database::fetchAll("SELECT * FROM zones ORDER BY zone_name");
        }
        
        $zoneId = $this->getUserZoneId();
        if ($zoneId) {
            return Database::fetchAll(
                "SELECT * FROM zones WHERE id = ? ORDER BY zone_name",
                [$zoneId]
            );
        }
        
        return [];
    }
}