<?php
/**
 * Enterprise HRM ERP System - Core Functions
 */

// Prevent direct access
if (!defined('HRM_ACCESS')) {
    die('Direct access not allowed');
}

/**
 * Get system setting from database
 */
function getSetting($key, $default = null) {
    static $settings_cache = [];
    
    if (isset($settings_cache[$key])) {
        return $settings_cache[$key];
    }
    
    try {
        $db = getDB();
        $stmt = $db->prepare("SELECT setting_value, setting_type FROM system_settings WHERE setting_key = ?");
        $stmt->execute([$key]);
        $setting = $stmt->fetch();
        
        if ($setting) {
            $value = $setting['setting_value'];
            
            // Convert based on type
            switch ($setting['setting_type']) {
                case 'number':
                    $value = is_numeric($value) ? (strpos($value, '.') !== false ? (float)$value : (int)$value) : $default;
                    break;
                case 'boolean':
                    $value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
                    break;
                case 'json':
                    $value = json_decode($value, true);
                    break;
            }
            
            $settings_cache[$key] = $value;
            return $value;
        }
    } catch (Exception $e) {
        error_log("Error getting setting {$key}: " . $e->getMessage());
    }
    
    return $default;
}

/**
 * Set system setting
 */
function setSetting($key, $value, $type = 'string', $category = null, $description = null) {
    try {
        $db = getDB();
        
        // Convert value based on type
        if ($type === 'json') {
            $value = json_encode($value);
        } elseif ($type === 'boolean') {
            $value = $value ? '1' : '0';
        }
        
        $stmt = $db->prepare("
            INSERT INTO system_settings (setting_key, setting_value, setting_type, setting_category, setting_description, updated_by)
            VALUES (?, ?, ?, ?, ?, ?)
            ON DUPLICATE KEY UPDATE 
                setting_value = VALUES(setting_value),
                setting_type = VALUES(setting_type),
                updated_by = VALUES(updated_by),
                updated_at = CURRENT_TIMESTAMP
        ");
        
        $user_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        $stmt->execute([$key, $value, $type, $category, $description, $user_id]);
        
        return true;
    } catch (Exception $e) {
        error_log("Error setting setting {$key}: " . $e->getMessage());
        return false;
    }
}

/**
 * Sanitize input
 */
function sanitize($data) {
    if (is_array($data)) {
        return array_map('sanitize', $data);
    }
    return htmlspecialchars(strip_tags(trim($data)), ENT_QUOTES, 'UTF-8');
}

/**
 * Validate email
 */
function validateEmail($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

/**
 * Format date
 */
function formatDate($date, $format = null) {
    if (empty($date) || $date === '0000-00-00' || $date === '0000-00-00 00:00:00') {
        return '';
    }
    
    if ($format === null) {
        $format = getSetting('DATE_FORMAT', 'Y-m-d');
    }
    
    try {
        $dateObj = new DateTime($date);
        return $dateObj->format($format);
    } catch (Exception $e) {
        return '';
    }
}

/**
 * Format datetime
 */
function formatDateTime($datetime, $format = null) {
    if (empty($datetime) || $datetime === '0000-00-00 00:00:00') {
        return '';
    }
    
    if ($format === null) {
        $format = getSetting('DATETIME_FORMAT', 'Y-m-d H:i:s');
    }
    
    try {
        $dateObj = new DateTime($datetime);
        return $dateObj->format($format);
    } catch (Exception $e) {
        return '';
    }
}

/**
 * Format currency
 */
function formatCurrency($amount) {
    $symbol = getSetting('CURRENCY_SYMBOL', '$');
    return $symbol . number_format((float)$amount, 2);
}

/**
 * Calculate days between dates
 */
function calculateDays($startDate, $endDate) {
    try {
        $start = new DateTime($startDate);
        $end = new DateTime($endDate);
        $diff = $start->diff($end);
        return $diff->days + 1; // Include both start and end date
    } catch (Exception $e) {
        return 0;
    }
}

/**
 * Check if user has permission
 */
function hasPermission($permissionCode) {
    if (!isset($_SESSION['user_id'])) {
        return false;
    }
    
    // If permissions not set in session, allow access (for simplified schema)
    if (!isset($_SESSION['permissions'])) {
        return true; // Allow access if permissions system not fully set up
    }
    
    return in_array($permissionCode, $_SESSION['permissions']);
}

/**
 * Require permission or redirect
 */
function requirePermission($permissionCode) {
    if (!hasPermission($permissionCode)) {
        $_SESSION['error'] = 'You do not have permission to access this resource.';
        header('Location: ' . BASE_URL . '/index.php');
        exit;
    }
}

/**
 * Log audit trail
 */
function logAudit($action, $tableName = null, $recordId = null, $oldValues = null, $newValues = null) {
    try {
        $db = getDB();
        $stmt = $db->prepare("
            INSERT INTO audit_logs (site_id, user_id, action, table_name, record_id, old_values, new_values, ip_address, user_agent)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
        ");
        
        $siteId = isset($_SESSION['site_id']) ? $_SESSION['site_id'] : null;
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        $ipAddress = $_SERVER['REMOTE_ADDR'] ?? null;
        $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? null;
        
        $oldValuesJson = $oldValues ? json_encode($oldValues) : null;
        $newValuesJson = $newValues ? json_encode($newValues) : null;
        
        $stmt->execute([
            $siteId,
            $userId,
            $action,
            $tableName,
            $recordId,
            $oldValuesJson,
            $newValuesJson,
            $ipAddress,
            $userAgent
        ]);
        
        return true;
    } catch (Exception $e) {
        error_log("Error logging audit: " . $e->getMessage());
        return false;
    }
}

/**
 * Generate unique code
 */
function generateCode($prefix, $table, $codeColumn, $siteId = null) {
    try {
        $db = getDB();
        
        $year = date('Y');
        $month = date('m');
        
        // Try to get the last code
        $sql = "SELECT {$codeColumn} FROM {$table} WHERE {$codeColumn} LIKE ?";
        $params = ["{$prefix}{$year}{$month}%"];
        
        if ($siteId !== null) {
            $sql .= " AND site_id = ?";
            $params[] = $siteId;
        }
        
        $sql .= " ORDER BY {$codeColumn} DESC LIMIT 1";
        
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        $lastCode = $stmt->fetchColumn();
        
        if ($lastCode) {
            // Extract sequence number
            $sequence = (int)substr($lastCode, -4) + 1;
        } else {
            $sequence = 1;
        }
        
        return sprintf("%s%s%s%04d", $prefix, $year, $month, $sequence);
    } catch (Exception $e) {
        error_log("Error generating code: " . $e->getMessage());
        return $prefix . time();
    }
}

/**
 * Redirect with message
 */
function redirect($url, $message = null, $type = 'success') {
    if ($message) {
        $_SESSION[$type] = $message;
    }
    header('Location: ' . $url);
    exit;
}

/**
 * Get flash message
 */
function getFlashMessage($type = 'success') {
    if (isset($_SESSION[$type])) {
        $message = $_SESSION[$type];
        unset($_SESSION[$type]);
        return $message;
    }
    return null;
}

/**
 * Validate password strength
 */
function validatePassword($password) {
    $errors = [];
    
    if (strlen($password) < PASSWORD_MIN_LENGTH) {
        $errors[] = "Password must be at least " . PASSWORD_MIN_LENGTH . " characters long.";
    }
    
    if (PASSWORD_REQUIRE_UPPERCASE && !preg_match('/[A-Z]/', $password)) {
        $errors[] = "Password must contain at least one uppercase letter.";
    }
    
    if (PASSWORD_REQUIRE_LOWERCASE && !preg_match('/[a-z]/', $password)) {
        $errors[] = "Password must contain at least one lowercase letter.";
    }
    
    if (PASSWORD_REQUIRE_NUMBER && !preg_match('/[0-9]/', $password)) {
        $errors[] = "Password must contain at least one number.";
    }
    
    if (PASSWORD_REQUIRE_SPECIAL && !preg_match('/[^A-Za-z0-9]/', $password)) {
        $errors[] = "Password must contain at least one special character.";
    }
    
    return $errors;
}

/**
 * Hash password
 */
function hashPassword($password) {
    return password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
}

/**
 * Verify password
 */
function verifyPassword($password, $hash) {
    return password_verify($password, $hash);
}

