<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception as MailerException;

if (!function_exists('generateCode')) {
    function generateCode(string $prefix, int $length = 8): string {
        $chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $code = '';
        for ($i = 0; $i < $length; $i++) {
            $code .= $chars[random_int(0, strlen($chars) - 1)];
        }
        return $prefix . '-' . $code;
    }
}

if (!function_exists('formatCurrency')) {
    function formatCurrency(float $amount, ?string $currency = null, ?string $locale = null): string {
        $currency = $currency ?: DEFAULT_CURRENCY;
        $symbol = CURRENCIES[$currency] ?? $currency;
        return $symbol . number_format($amount, 2);
    }
}

if (!function_exists('formatDate')) {
    function formatDate(string|null $date, ?string $locale = null): string {
        if (!$date) return '';
        $format = DATE_FORMATS[$locale ?: DEFAULT_LOCALE] ?? 'Y-m-d H:i:s';
        $format = explode(' ', $format)[0];
        return date($format, strtotime($date));
    }
}

if (!function_exists('formatDateTime')) {
    function formatDateTime(string|null $datetime, ?string $locale = null): string {
        if (!$datetime) return '';
        $format = DATE_FORMATS[$locale ?: DEFAULT_LOCALE] ?? 'Y-m-d H:i:s';
        return date($format, strtotime($datetime));
    }
}

if (!function_exists('sanitize')) {
    function sanitize(string $input): string {
        return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
    }
}

if (!function_exists('normalizeUrl')) {
    function normalizeUrl(?string $url): ?string {
        $url = trim((string)$url);
        if ($url === '') {
            return null;
        }
        if (!preg_match('#^https?://#i', $url)) {
            $url = 'https://' . $url;
        }
        return $url;
    }
}

if (!function_exists('slugify')) {
    function slugify(string $text): string {
        $text = preg_replace('~[^\pL\d]+~u', '-', $text);
        $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
        $text = preg_replace('~[^-\w]+~', '', $text);
        $text = trim($text, '-');
        $text = preg_replace('~-+~', '-', $text);
        return strtolower($text);
    }
}

if (!function_exists('truncate')) {
    function truncate(string $text, int $length = 100): string {
        if (strlen($text) <= $length) return $text;
        return substr($text, 0, $length) . '...';
    }
}

if (!function_exists('timeSince')) {
    function timeSince(string $datetime): string {
        return timeAgo($datetime);
    }
}

if (!function_exists('formatFileSize')) {
    function formatFileSize(int $bytes): string {
        if ($bytes >= 1073741824) {
            return number_format($bytes / 1073741824, 2) . ' GB';
        }
        if ($bytes >= 1048576) {
            return number_format($bytes / 1048576, 2) . ' MB';
        }
        if ($bytes >= 1024) {
            return number_format($bytes / 1024, 2) . ' KB';
        }
        return $bytes . ' bytes';
    }
}

if (!function_exists('generateUniqueFilename')) {
    function generateUniqueFilename(string $originalName): string {
        $ext = pathinfo($originalName, PATHINFO_EXTENSION);
        return time() . '_' . bin2hex(random_bytes(8)) . '.' . $ext;
    }
}

if (!function_exists('sendEmail')) {
    function sendEmail(string $to, string $toName, string $subject, string $htmlBody, array $attachments = []): bool {
        if (!class_exists('PHPMailer\PHPMailer\PHPMailer')) {
            return false;
        }
        
        $mail = new PHPMailer(true);
        try {
            $mail->isSMTP();
            $mail->Host       = SMTP_HOST;
            $mail->SMTPAuth   = true;
            $mail->Username   = SMTP_USERNAME;
            $mail->Password   = SMTP_PASSWORD;
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
            $mail->Port       = SMTP_PORT;

            $mail->setFrom(SMTP_FROM_EMAIL, SMTP_FROM_NAME);
            $mail->addAddress($to, $toName);

            foreach ($attachments as $attachment) {
                if (file_exists($attachment)) {
                    $mail->addAttachment($attachment);
                }
            }

            $mail->isHTML(true);
            $mail->Subject = $subject;
            $mail->Body    = $htmlBody;

            $mail->send();
            return true;
        } catch (MailerException $e) {
            error_log("Email sending failed: {$mail->ErrorInfo}");
            return false;
        }
    }
}

if (!function_exists('createNotification')) {
    function createNotification(int $userId, string $type, string $title, string $message, array $data = []): void {
        $db = Database::getInstance();
        $stmt = $db->prepare("INSERT INTO notifications (user_id, type, title, message, data, created_at) VALUES (?, ?, ?, ?, ?, NOW())");
        $stmt->execute([$userId, $type, $title, $message, json_encode($data)]);
    }
}

if (!function_exists('logAudit')) {
    function logAudit(string $action, string $module, string $entityType, int|null $entityId, mixed $oldValues = null, mixed $newValues = null): void {
        $db = Database::getInstance();
        $userId = \Core\Auth::id();
        $stmt = $db->prepare("INSERT INTO audit_logs (user_id, action, module, entity_type, entity_id, old_values, new_values, ip_address, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())");
        $ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
        $stmt->execute([$userId, $action, $module, $entityType, $entityId, $oldValues ? json_encode($oldValues) : null, $newValues ? json_encode($newValues) : null, $ip]);
    }
}

if (!function_exists('getLocales')) {
    function getLocales(): array {
        return SUPPORTED_LOCALES;
    }
}

if (!function_exists('getCurrencies')) {
    function getCurrencies(): array {
        return CURRENCIES;
    }
}

if (!function_exists('getIndustryGroups')) {
    // Nested form: sector label => list of sub-industries (empty list for a
    // standalone sector like 'Other').
    function getIndustryGroups(): array {
        return INDUSTRIES;
    }
}

if (!function_exists('getPlatformSetting')) {
    /**
     * Read a platform-wide (super-admin) setting from organization_settings
     * (org_id IS NULL rows) — e.g. gateway/API credentials configured via
     * Admin > System Settings. Cached for the life of the request.
     */
    function getPlatformSetting(string $key, mixed $default = null): mixed {
        static $cache = null;
        if ($cache === null) {
            $cache = [];
            try {
                $rows = Database::getInstance()
                    ->query("SELECT setting_key, setting_value FROM organization_settings WHERE org_id IS NULL")
                    ->fetchAll();
                foreach ($rows as $row) {
                    $cache[$row['setting_key']] = $row['setting_value'];
                }
            } catch (\Throwable $e) {
                // Table not ready yet (e.g. fresh install before migrations) — fall through to defaults.
            }
        }
        $value = $cache[$key] ?? null;
        return ($value === null || $value === '') ? $default : $value;
    }
}

if (!function_exists('getIndustries')) {
    // Flat, leaf-level list: every sub-industry, plus each sector that has no
    // sub-industries of its own (e.g. 'Other'), in declaration order.
    function getIndustries(): array {
        $flat = [];
        foreach (INDUSTRIES as $sector => $subIndustries) {
            if (empty($subIndustries)) {
                $flat[] = $sector;
            } else {
                foreach ($subIndustries as $sub) {
                    $flat[] = $sub;
                }
            }
        }
        return $flat;
    }
}

if (!function_exists('flash')) {
    function flash(string $type, string $message): void {
        $_SESSION['flash'][$type] = $message;
    }
}

if (!function_exists('redirect')) {
    function redirect(string $url): never {
        header("Location: " . \Core\View::url($url));
        exit;
    }
}

if (!function_exists('isValidEmail')) {
    function isValidEmail(string $email): bool {
        return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
    }
}

if (!function_exists('generateToken')) {
    function generateToken(int $length = 32): string {
        return bin2hex(random_bytes($length / 2));
    }
}

if (!function_exists('timeAgo')) {
    function timeAgo(string $datetime): string {
        $time = strtotime($datetime);
        $diff = time() - $time;
        
        if ($diff < 1) return 'just now';
        
        $intervals = [
            31536000 => 'year',
            2592000 => 'month',
            604800 => 'week',
            86400 => 'day',
            3600 => 'hour',
            60 => 'minute',
            1 => 'second'
        ];
        
        foreach ($intervals as $secs => $str) {
            $d = $diff / $secs;
            if ($d >= 1) {
                $r = round($d);
                return $r . ' ' . $str . ($r > 1 ? 's' : '') . ' ago';
            }
        }
        return 'just now';
    }
}
