<?php
/**
 * Utility Functions for Ultrasure Insurance Platform
 * Contains common helper functions used throughout the application
 */

/**
 * Format date and time
 */
function formatDateTime($datetime, $format = 'M j, Y g:i A') {
    if (empty($datetime) || $datetime === '0000-00-00 00:00:00') {
        return 'Not set';
    }
    
    try {
        $date = new DateTime($datetime);
        return $date->format($format);
    } catch (Exception $e) {
        return 'Invalid date';
    }
}

/**
 * Format date only
 */
function formatDate($date, $format = 'M j, Y') {
    if (empty($date) || $date === '0000-00-00') {
        return 'Not set';
    }
    
    try {
        $dateObj = new DateTime($date);
        return $dateObj->format($format);
    } catch (Exception $e) {
        return 'Invalid date';
    }
}

/**
 * Calculate age from date of birth
 */
function calculateAge($dob) {
    if (empty($dob) || $dob === '0000-00-00') {
        return 0;
    }
    
    try {
        $birthDate = new DateTime($dob);
        $today = new DateTime('today');
        return $birthDate->diff($today)->y;
    } catch (Exception $e) {
        return 0;
    }
}

/**
 * Format currency (KSH)
 */
function formatCurrency($amount, $decimals = 2) {
    return 'KSH ' . number_format($amount, $decimals);
}

/**
 * Format percentage
 */
function formatPercentage($value, $decimals = 1) {
    return number_format($value, $decimals) . '%';
}

/**
 * Generate unique reference number
 */
function generateReferenceNumber($prefix = '', $length = 8) {
    $timestamp = date('ymdHis');
    $random = substr(str_shuffle('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, $length - strlen($timestamp));
    return strtoupper($prefix . $timestamp . $random);
}

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

/**
 * Check if user has permission
 */
function hasPermission($permission) {
    global $conn;
    
    if (!isset($_SESSION['user_id'])) {
        return false;
    }
    
    // Super Admin has all permissions
    if ($_SESSION['role_name'] === 'Super Admin') {
        return true;
    }
    
    // Check specific permission
    try {
        $sql = "SELECT COUNT(*) as has_permission 
                FROM users u 
                JOIN role_permissions rp ON u.role_id = rp.role_id 
                JOIN permissions p ON rp.permission_id = p.permission_id 
                WHERE u.user_id = ? AND p.name = ? AND u.status = 'ACTIVE'";
        
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("is", $_SESSION['user_id'], $permission);
        $stmt->execute();
        $result = $stmt->get_result()->fetch_assoc();
        $stmt->close();
        
        return $result['has_permission'] > 0;
    } catch (Exception $e) {
        error_log("Permission check error: " . $e->getMessage());
        return false;
    }
}

/**
 * Log activity
 */
function logActivity($action, $module, $record_id = null, $record_type = null, $old_values = null, $new_values = null) {
    global $conn;
    
    if (!isset($_SESSION['user_id'])) {
        return false;
    }
    
    try {
        $ip_address = $_SERVER['REMOTE_ADDR'];
        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
        }
        
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        $session_id = session_id();
        
        $sql = "INSERT INTO activity_log (user_id, action, module, record_id, record_type, old_values, new_values, ip_address, user_agent, session_id) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("ississssss", 
            $_SESSION['user_id'], 
            $action, 
            $module, 
            $record_id, 
            $record_type,
            $old_values ? json_encode($old_values) : null,
            $new_values ? json_encode($new_values) : null,
            $ip_address,
            substr($user_agent, 0, 500), // Limit user agent length
            $session_id
        );
        
        $stmt->execute();
        $stmt->close();
        
        return true;
    } catch (Exception $e) {
        error_log("Activity log error: " . $e->getMessage());
        return false;
    }
}

/**
 * Get system setting value
 */
function getSystemSetting($key, $default = null) {
    global $conn;
    
    try {
        $sql = "SELECT setting_value FROM system_settings WHERE setting_key = ?";
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("s", $key);
        $stmt->execute();
        $result = $stmt->get_result()->fetch_assoc();
        $stmt->close();
        
        return $result ? $result['setting_value'] : $default;
    } catch (Exception $e) {
        error_log("System setting error: " . $e->getMessage());
        return $default;
    }
}

/**
 * Send notification
 */
function sendNotification($recipient_type, $recipient_id, $type, $subject, $message, $template_id = null) {
    global $conn;
    
    try {
        // Get recipient contact info based on type
        $contact_info = getRecipientContact($recipient_type, $recipient_id);
        
        if (!$contact_info) {
            return false;
        }
        
        $sql = "INSERT INTO communication_log (recipient_type, recipient_id, communication_type, template_id, subject, message, recipient_contact, sent_by) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
        
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("sisisssi", 
            $recipient_type, 
            $recipient_id, 
            $type, 
            $template_id,
            $subject, 
            $message, 
            $contact_info,
            $_SESSION['user_id'] ?? null
        );
        
        $stmt->execute();
        $stmt->close();
        
        return true;
    } catch (Exception $e) {
        error_log("Notification error: " . $e->getMessage());
        return false;
    }
}

/**
 * Get recipient contact information
 */
function getRecipientContact($recipient_type, $recipient_id) {
    global $conn;
    
    try {
        switch ($recipient_type) {
            case 'CUSTOMER':
                $sql = "SELECT phone_primary as contact FROM customers WHERE customer_id = ?";
                break;
            case 'AGENT':
                $sql = "SELECT phone_number as contact FROM users WHERE user_id = ?";
                break;
            case 'USER':
                $sql = "SELECT email as contact FROM users WHERE user_id = ?";
                break;
            default:
                return null;
        }
        
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("i", $recipient_id);
        $stmt->execute();
        $result = $stmt->get_result()->fetch_assoc();
        $stmt->close();
        
        return $result ? $result['contact'] : null;
    } catch (Exception $e) {
        error_log("Get recipient contact error: " . $e->getMessage());
        return null;
    }
}

/**
 * Validate phone number (Kenyan format)
 */
function validateKenyanPhone($phone) {
    // Remove any spaces, dashes, or parentheses
    $phone = preg_replace('/[\s\-\(\)]/', '', $phone);
    
    // Check if it's a valid Kenyan number
    if (preg_match('/^(\+254|254|0)(7|1)\d{8}$/', $phone)) {
        // Normalize to +254 format
        if (substr($phone, 0, 1) === '0') {
            return '+254' . substr($phone, 1);
        } elseif (substr($phone, 0, 3) === '254') {
            return '+' . $phone;
        } elseif (substr($phone, 0, 4) === '+254') {
            return $phone;
        }
    }
    
    return false;
}

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

/**
 * Generate PDF (placeholder - you'll need to implement with a PDF library)
 */
function generatePDF($html, $filename = 'document.pdf', $options = []) {
    // This is a placeholder - you'll need to implement using libraries like:
    // - TCPDF
    // - DOMPDF
    // - mPDF
    // For now, we'll return false
    return false;
}

/**
 * Upload file
 */
function uploadFile($file, $upload_dir = 'uploads/', $allowed_types = ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx']) {
    if (!isset($file['error']) || is_array($file['error'])) {
        return ['success' => false, 'message' => 'Invalid file upload'];
    }
    
    // Check for upload errors
    switch ($file['error']) {
        case UPLOAD_ERR_OK:
            break;
        case UPLOAD_ERR_NO_FILE:
            return ['success' => false, 'message' => 'No file sent'];
        case UPLOAD_ERR_INI_SIZE:
        case UPLOAD_ERR_FORM_SIZE:
            return ['success' => false, 'message' => 'File size exceeds limit'];
        default:
            return ['success' => false, 'message' => 'Unknown upload error'];
    }
    
    // Check file size (10MB limit)
    if ($file['size'] > 10485760) {
        return ['success' => false, 'message' => 'File size exceeds 10MB limit'];
    }
    
    // Check file type
    $file_extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    if (!in_array($file_extension, $allowed_types)) {
        return ['success' => false, 'message' => 'File type not allowed'];
    }
    
    // Generate unique filename
    $filename = uniqid() . '_' . time() . '.' . $file_extension;
    $upload_path = $upload_dir . $filename;
    
    // Create upload directory if it doesn't exist
    if (!is_dir($upload_dir)) {
        mkdir($upload_dir, 0755, true);
    }
    
    // Move uploaded file
    if (move_uploaded_file($file['tmp_name'], $upload_path)) {
        return [
            'success' => true, 
            'filename' => $filename,
            'filepath' => $upload_path,
            'size' => $file['size'],
            'type' => $file['type']
        ];
    } else {
        return ['success' => false, 'message' => 'Failed to save file'];
    }
}

/**
 * Get policy status color class
 */
function getPolicyStatusClass($status) {
    return match($status) {
        'ACTIVE' => 'success',
        'PENDING' => 'warning',
        'LAPSED' => 'danger',
        'CANCELLED' => 'secondary',
        'SUSPENDED' => 'warning',
        'EXPIRED' => 'danger',
        default => 'secondary'
    };
}

/**
 * Get claim status color class
 */
function getClaimStatusClass($status) {
    return match($status) {
        'SUBMITTED' => 'info',
        'UNDER_INVESTIGATION' => 'warning',
        'ADDITIONAL_INFO_REQUIRED' => 'warning',
        'APPROVED' => 'success',
        'REJECTED' => 'danger',
        'PAID' => 'success',
        'PARTIALLY_PAID' => 'warning',
        'CLOSED' => 'secondary',
        default => 'secondary'
    };
}

/**
 * Get quote status color class
 */
function getQuoteStatusClass($status) {
    return match($status) {
        'DRAFT' => 'secondary',
        'PENDING' => 'warning',
        'ACTIVE' => 'success',
        'EXPIRED' => 'danger',
        'CONVERTED' => 'info',
        'REJECTED' => 'danger',
        default => 'secondary'
    };
}

/**
 * Calculate working days between two dates
 */
function calculateWorkingDays($start_date, $end_date, $holidays = []) {
    $start = new DateTime($start_date);
    $end = new DateTime($end_date);
    $interval = new DateInterval('P1D');
    $daterange = new DatePeriod($start, $interval, $end);
    
    $working_days = 0;
    
    foreach($daterange as $date) {
        // Skip weekends (Saturday = 6, Sunday = 0)
        if ($date->format('w') != 0 && $date->format('w') != 6) {
            // Skip holidays
            if (!in_array($date->format('Y-m-d'), $holidays)) {
                $working_days++;
            }
        }
    }
    
    return $working_days;
}

/**
 * Generate random password
 */
function generateRandomPassword($length = 12) {
    $uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $lowercase = 'abcdefghijklmnopqrstuvwxyz';
    $numbers = '0123456789';
    $symbols = '!@#$%^&*()_+-=[]{}|;:,.<>?';
    
    $password = '';
    $password .= $uppercase[rand(0, strlen($uppercase) - 1)];
    $password .= $lowercase[rand(0, strlen($lowercase) - 1)];
    $password .= $numbers[rand(0, strlen($numbers) - 1)];
    $password .= $symbols[rand(0, strlen($symbols) - 1)];
    
    $all_chars = $uppercase . $lowercase . $numbers . $symbols;
    for ($i = 4; $i < $length; $i++) {
        $password .= $all_chars[rand(0, strlen($all_chars) - 1)];
    }
    
    return str_shuffle($password);
}

/**
 * Time ago function
 */
function timeAgo($datetime) {
    $time = time() - strtotime($datetime);
    
    if ($time < 60) return 'just now';
    if ($time < 3600) return floor($time/60) . ' minutes ago';
    if ($time < 86400) return floor($time/3600) . ' hours ago';
    if ($time < 2592000) return floor($time/86400) . ' days ago';
    if ($time < 31104000) return floor($time/2592000) . ' months ago';
    
    return floor($time/31104000) . ' years ago';
}

/**
 * Create breadcrumb navigation
 */
function createBreadcrumb($items) {
    $breadcrumb = '<nav aria-label="breadcrumb">
                    <ol class="breadcrumb m-0">';
    
    $count = count($items);
    foreach ($items as $index => $item) {
        if ($index === $count - 1) {
            // Last item (current page)
            $breadcrumb .= '<li class="breadcrumb-item active" aria-current="page">' . 
                          htmlspecialchars($item['title']) . '</li>';
        } else {
            // Navigation items
            if (isset($item['url'])) {
                $breadcrumb .= '<li class="breadcrumb-item">
                               <a href="' . htmlspecialchars($item['url']) . '">' . 
                               htmlspecialchars($item['title']) . '</a></li>';
            } else {
                $breadcrumb .= '<li class="breadcrumb-item">' . 
                              htmlspecialchars($item['title']) . '</li>';
            }
        }
    }
    
    $breadcrumb .= '</ol></nav>';
    return $breadcrumb;
}

/**
 * Include file with variables
 */
function includeFileWithVariables($filePath, $variables = []) {
    extract($variables);
    include $filePath;
}

/**
 * Debug function (only in development)
 */
function debug($data, $die = false) {
    if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE) {
        echo '<pre>';
        print_r($data);
        echo '</pre>';
        
        if ($die) {
            die();
        }
    }
}

/**
 * Check if current environment is development
 */
function isDevelopment() {
    return defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE;
}

/**
 * Get client IP address
 */
function getClientIP() {
    $ip = $_SERVER['REMOTE_ADDR'];
    
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED'])) {
        $ip = $_SERVER['HTTP_X_FORWARDED'];
    } elseif (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    } elseif (!empty($_SERVER['HTTP_FORWARDED_FOR'])) {
        $ip = $_SERVER['HTTP_FORWARDED_FOR'];
    } elseif (!empty($_SERVER['HTTP_FORWARDED'])) {
        $ip = $_SERVER['HTTP_FORWARDED'];
    }
    
    return $ip;
}
?>