<?php
/**
 * Global Helper Functions
 */

function redirect(string $url): void {
    header("Location: $url");
    exit;
}

function back(): void {
    $referer = $_SERVER['HTTP_REFERER'] ?? '?page=dashboard';
    header("Location: $referer");
    exit;
}

function e(string $value): string {
    return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}

function flash(string $key, $value = null) {
    if ($value !== null) {
        $_SESSION['flash'][$key] = $value;
        return null;
    }
    $val = $_SESSION['flash'][$key] ?? null;
    unset($_SESSION['flash'][$key]);
    return $val;
}

function old(string $key, $default = '') {
    return $_SESSION['old'][$key] ?? $default;
}

function setOld(array $data): void {
    $_SESSION['old'] = $data;
}

function clearOld(): void {
    unset($_SESSION['old']);
}

function formatMoney($amount): string {
    return '$' . number_format((float)$amount, 2);
}

function formatDate(?string $date, string $format = 'M d, Y'): string {
    if (!$date) return '-';
    return date($format, strtotime($date));
}

function formatDateTime(?string $date): string {
    if (!$date) return '-';
    return date('M d, Y g:i A', strtotime($date));
}

function timeAgo(string $datetime): string {
    $now = new DateTime();
    $ago = new DateTime($datetime);
    $diff = $now->diff($ago);
    
    if ($diff->y > 0) return $diff->y . 'y ago';
    if ($diff->m > 0) return $diff->m . 'mo ago';
    if ($diff->d > 0) return $diff->d . 'd ago';
    if ($diff->h > 0) return $diff->h . 'h ago';
    if ($diff->i > 0) return $diff->i . 'm ago';
    return 'Just now';
}

function generateToken(int $length = 32): string {
    return bin2hex(random_bytes($length));
}

function generateReceiptNumber(): string {
    return 'RCV-' . date('Ymd') . '-' . strtoupper(substr(uniqid(), -6));
}

function getInitials(string $name): string {
    $parts = explode(' ', trim($name));
    $initials = '';
    foreach ($parts as $part) {
        $initials .= strtoupper(substr($part, 0, 1));
    }
    return substr($initials, 0, 2);
}

function statusBadge(string $status): string {
    $colors = [
        // General
        'active' => 'bg-emerald-100 text-emerald-700',
        'inactive' => 'bg-gray-100 text-gray-600',
        'pending' => 'bg-amber-100 text-amber-700',
        'suspended' => 'bg-red-100 text-red-700',
        // Lease
        'draft' => 'bg-gray-100 text-gray-600',
        'expired' => 'bg-orange-100 text-orange-700',
        'terminated' => 'bg-red-100 text-red-700',
        'renewed' => 'bg-blue-100 text-blue-700',
        'month_to_month' => 'bg-purple-100 text-purple-700',
        // Payment
        'paid' => 'bg-emerald-100 text-emerald-700',
        'completed' => 'bg-emerald-100 text-emerald-700',
        'partial' => 'bg-amber-100 text-amber-700',
        'overdue' => 'bg-red-100 text-red-700',
        'failed' => 'bg-red-100 text-red-700',
        'refunded' => 'bg-purple-100 text-purple-700',
        'processing' => 'bg-blue-100 text-blue-700',
        // Unit
        'vacant' => 'bg-amber-100 text-amber-700',
        'occupied' => 'bg-emerald-100 text-emerald-700',
        'notice_given' => 'bg-orange-100 text-orange-700',
        'under_maintenance' => 'bg-blue-100 text-blue-700',
        'not_available' => 'bg-gray-100 text-gray-600',
        'model_unit' => 'bg-indigo-100 text-indigo-700',
        // Maintenance
        'new' => 'bg-blue-100 text-blue-700',
        'reviewed' => 'bg-indigo-100 text-indigo-700',
        'assigned' => 'bg-purple-100 text-purple-700',
        'in_progress' => 'bg-amber-100 text-amber-700',
        'waiting_parts' => 'bg-orange-100 text-orange-700',
        'waiting_approval' => 'bg-orange-100 text-orange-700',
        'closed' => 'bg-gray-100 text-gray-600',
        'cancelled' => 'bg-gray-100 text-gray-600',
        // Priority
        'emergency' => 'bg-red-100 text-red-700',
        'high' => 'bg-orange-100 text-orange-700',
        'medium' => 'bg-amber-100 text-amber-700',
        'low' => 'bg-blue-100 text-blue-700',
        // Leads
        'contacted' => 'bg-blue-100 text-blue-700',
        'tour_scheduled' => 'bg-purple-100 text-purple-700',
        'tour_completed' => 'bg-indigo-100 text-indigo-700',
        'applied' => 'bg-amber-100 text-amber-700',
        'approved' => 'bg-emerald-100 text-emerald-700',
        'leased' => 'bg-emerald-100 text-emerald-700',
        'lost' => 'bg-gray-100 text-gray-600',
        // Connection
        'connected' => 'bg-emerald-100 text-emerald-700',
        'disconnected' => 'bg-gray-100 text-gray-600',
        'error' => 'bg-red-100 text-red-700',
        // Subscription
        'trialing' => 'bg-blue-100 text-blue-700',
        'past_due' => 'bg-red-100 text-red-700',
    ];
    
    $colorClass = $colors[$status] ?? 'bg-gray-100 text-gray-600';
    $label = ucwords(str_replace('_', ' ', $status));
    
    return "<span class=\"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {$colorClass}\">{$label}</span>";
}

function priorityBadge(string $priority): string {
    return statusBadge($priority);
}

function paginate(int $total, int $page, int $perPage = ITEMS_PER_PAGE): array {
    $totalPages = max(1, ceil($total / $perPage));
    $page = max(1, min($page, $totalPages));
    $offset = ($page - 1) * $perPage;
    
    return [
        'total' => $total,
        'per_page' => $perPage,
        'current_page' => $page,
        'total_pages' => $totalPages,
        'offset' => $offset,
        'has_prev' => $page > 1,
        'has_next' => $page < $totalPages,
    ];
}

function paginationHtml(array $pagination, string $baseUrl): string {
    if ($pagination['total_pages'] <= 1) return '';
    
    $html = '<nav class="flex items-center justify-between border-t border-gray-200 pt-4 mt-4">';
    $html .= '<div class="text-sm text-gray-500">Showing ' . (($pagination['current_page'] - 1) * $pagination['per_page'] + 1) . ' to ' . min($pagination['current_page'] * $pagination['per_page'], $pagination['total']) . ' of ' . $pagination['total'] . '</div>';
    $html .= '<div class="flex gap-1">';
    
    $sep = strpos($baseUrl, '?') !== false ? '&' : '?';
    
    if ($pagination['has_prev']) {
        $html .= '<a href="' . $baseUrl . $sep . 'pg=' . ($pagination['current_page'] - 1) . '" class="px-3 py-1.5 text-sm border border-gray-300 rounded-lg hover:bg-gray-50 transition">Prev</a>';
    }
    
    for ($i = max(1, $pagination['current_page'] - 2); $i <= min($pagination['total_pages'], $pagination['current_page'] + 2); $i++) {
        $active = $i === $pagination['current_page'] ? 'bg-gray-900 text-white border-gray-900' : 'border-gray-300 hover:bg-gray-50';
        $html .= '<a href="' . $baseUrl . $sep . 'pg=' . $i . '" class="px-3 py-1.5 text-sm border rounded-lg transition ' . $active . '">' . $i . '</a>';
    }
    
    if ($pagination['has_next']) {
        $html .= '<a href="' . $baseUrl . $sep . 'pg=' . ($pagination['current_page'] + 1) . '" class="px-3 py-1.5 text-sm border border-gray-300 rounded-lg hover:bg-gray-50 transition">Next</a>';
    }
    
    $html .= '</div></nav>';
    return $html;
}

function getSetting(string $key, $default = null) {
    static $cache = [];
    if (isset($cache[$key])) return $cache[$key];
    
    $db = Database::getInstance();
    $companyId = Auth::check() ? Auth::user()['company_id'] : null;
    
    $row = $db->fetch(
        "SELECT `value` FROM `settings` WHERE `key` = ? AND (company_id = ? OR company_id IS NULL) ORDER BY company_id DESC LIMIT 1",
        [$key, $companyId]
    );
    
    $cache[$key] = $row ? $row['value'] : $default;
    return $cache[$key];
}

function setSetting(string $key, $value, ?int $companyId = null): void {
    $db = Database::getInstance();
    $existing = $db->fetch(
        "SELECT id FROM `settings` WHERE `key` = ? AND company_id " . ($companyId ? "= ?" : "IS NULL"),
        $companyId ? [$key, $companyId] : [$key]
    );
    
    if ($existing) {
        $db->update('settings', ['value' => $value], 'id = ?', [$existing['id']]);
    } else {
        $db->insert('settings', [
            'company_id' => $companyId,
            'key' => $key,
            'value' => $value,
            'group' => 'general'
        ]);
    }
}

function auditLog(string $action, ?string $modelType = null, ?int $modelId = null, ?array $oldValues = null, ?array $newValues = null): void {
    $db = Database::getInstance();
    $user = Auth::check() ? Auth::user() : null;
    
    $db->insert('audit_logs', [
        'company_id' => $user['company_id'] ?? null,
        'user_id' => $user['id'] ?? null,
        'action' => $action,
        'model_type' => $modelType,
        'model_id' => $modelId,
        'old_values' => $oldValues ? json_encode($oldValues) : null,
        'new_values' => $newValues ? json_encode($newValues) : null,
        'ip_address' => $_SERVER['REMOTE_ADDR'] ?? null,
        'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null,
    ]);
}

function notify(int $userId, string $type, string $title, ?string $body = null, ?array $data = null): void {
    $db = Database::getInstance();
    $user = Auth::check() ? Auth::user() : null;
    
    $db->insert('notifications', [
        'company_id' => $user['company_id'] ?? null,
        'user_id' => $userId,
        'type' => $type,
        'title' => $title,
        'body' => $body,
        'data' => $data ? json_encode($data) : null,
    ]);
}

function uploadFile(array $file, string $directory = 'general'): ?string {
    $uploadDir = UPLOAD_PATH . '/' . $directory;
    if (!is_dir($uploadDir)) {
        mkdir($uploadDir, 0755, true);
    }
    
    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    $allowed = explode(',', ALLOWED_FILE_TYPES);
    
    if (!in_array($ext, $allowed)) {
        return null;
    }
    
    if ($file['size'] > MAX_UPLOAD_SIZE) {
        return null;
    }
    
    $filename = uniqid() . '_' . time() . '.' . $ext;
    $destination = $uploadDir . '/' . $filename;
    
    if (move_uploaded_file($file['tmp_name'], $destination)) {
        return 'uploads/' . $directory . '/' . $filename;
    }
    
    return null;
}

function appName(): string {
    return getSetting('app_name', APP_NAME ?? 'RentRev AI');
}
