<?php
use App\Core\Auth;
use App\Core\Database;
use App\Core\Security;

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

function app_base_url(): string {
    $configured = rtrim((string)APP_URL, '/');
    if ($configured !== '') return $configured;
    $script = $_SERVER['SCRIPT_NAME'] ?? '';
    $root = '';
    foreach (['/admin/','/vendor/','/customer/','/member/','/public/','/pos/','/api/','/payment/','/install/'] as $marker) {
        $pos = strpos($script, $marker);
        if ($pos !== false) { $root = substr($script, 0, $pos); break; }
    }
    return rtrim($root, '/');
}

function url(string $path = ''): string {
    $path = ltrim($path, '/');
    $base = app_base_url();
    return ($base === '' ? '' : $base) . ($path ? '/' . $path : '/');
}

function asset(string $path): string { return url('public/assets/' . ltrim($path, '/')); }
function admin_asset(string $path): string { return url('public/admin-assets/' . ltrim($path, '/')); }
function redirect(string $path): void {
    if (preg_match('/[\r\n]/', $path) || !Security::isSafeReturnPath($path)) $path = '';
    header('Location: ' . url($path), true, 302);
    exit;
}
function is_installed(): bool { return Database::isConnected(); }

function install_notice_html(): string {
    if (is_installed()) return '';
    return '<div class="alert alert-warning border-0 shadow-sm"><strong>Setup required:</strong> The database is not connected. Import <code>install/smarmvty_smart_completed.sql</code>, then create <code>app/config.local.php</code> from the supplied example.</div>';
}

function csrf_token(): string { return Security::csrfToken(); }
function csrf_field(): string { return '<input type="hidden" name="csrf_token" value="' . e(csrf_token()) . '">'; }
function verify_csrf(): bool {
    $token = $_POST['csrf_token'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
    if ($token === '') {
        $json = json_decode((string)file_get_contents('php://input'), true);
        if (is_array($json)) $token = (string)($json['csrf_token'] ?? '');
    }
    return Security::verifyCsrf((string)$token);
}

function request_data(): array {
    $contentType = strtolower((string)($_SERVER['CONTENT_TYPE'] ?? ''));
    if (str_contains($contentType, 'application/json')) {
        $decoded = json_decode((string)file_get_contents('php://input'), true);
        return is_array($decoded) ? $decoded : [];
    }
    return $_POST ?: $_GET;
}

function flash(string $key): ?string { $value = $_SESSION['flash'][$key] ?? null; unset($_SESSION['flash'][$key]); return $value; }
function set_flash(string $key, string $value): void { $_SESSION['flash'][$key] = $value; }
function money($amount): string { return APP_CURRENCY_SYMBOL . ' ' . number_format((float)$amount, 2); }

function slugify(string $text): string {
    $slug = strtolower(trim($text));
    $slug = preg_replace('/[^a-z0-9]+/i', '-', $slug);
    return trim((string)$slug, '-') ?: 'item-' . time();
}

function unique_slug(string $table, string $text, ?int $ignoreId = null): string {
    $base = slugify($text);
    $slug = $base;
    $counter = 2;
    if (!Database::tableExists($table)) return $slug;
    while (true) {
        $sql = "SELECT id FROM `{$table}` WHERE slug=?" . ($ignoreId ? ' AND id<>?' : '') . ' LIMIT 1';
        $params = $ignoreId ? [$slug, $ignoreId] : [$slug];
        if (!Database::safeFetchOne($sql, $params)) return $slug;
        $slug = $base . '-' . $counter++;
    }
}

function current_user(): ?array { return Auth::user(); }

function role_dashboard_url(?string $role = null): string {
    if (Auth::requiresPasswordChange()) return 'public/change-password.php';
    $role ??= Auth::role();
    return match ($role) {
        'admin', 'staff' => 'admin/index.php',
        'vendor' => 'vendor/index.php',
        'affiliate' => 'member/index.php',
        'pos_cashier', 'pos_manager', 'pos_reporter' => 'pos/register.php',
        default => 'customer/dashboard.php',
    };
}

function setting(string $key, string $default = ''): string {
    static $cache = [];
    if (array_key_exists($key, $cache)) return $cache[$key];
    if (!Database::tableExists('settings')) return $cache[$key] = $default;
    $row = Database::safeFetchOne('SELECT setting_value FROM settings WHERE setting_key=? LIMIT 1', [$key]);
    return $cache[$key] = (string)($row['setting_value'] ?? $default);
}

function badge(string $status): string {
    $map = ['active'=>'success','approved'=>'success','published'=>'success','pending'=>'warning','processing'=>'info','shipped'=>'primary','delivered'=>'success','paid'=>'success','cancelled'=>'danger','rejected'=>'danger','failed'=>'danger','open'=>'info','closed'=>'secondary'];
    $class = $map[strtolower($status)] ?? 'secondary';
    return '<span class="badge bg-' . $class . '">' . e(ucwords(str_replace('_', ' ', $status))) . '</span>';
}

function db_count(string $table, string $where = '1=1', array $params = []): int {
    if (!Database::tableExists($table) || !preg_match('/^[a-zA-Z0-9_]+$/', $table)) return 0;
    $row = Database::safeFetchOne("SELECT COUNT(*) total FROM `{$table}` WHERE {$where}", $params);
    return (int)($row['total'] ?? 0);
}

function sample_products(): array {
    if (APP_ENV === 'production') return [];
    return [
    ['id'=>1,'name'=>'Smart LED Television 43 inch','slug'=>'smart-led-television-43-inch','sku'=>'ST-LED43','regular_price'=>49900,'sale_price'=>45900,'stock'=>18,'image'=>'assets/images/gallery/product-images/01.png','shop_name'=>'Smart Tech OMP Official'],
    ['id'=>2,'name'=>'Wireless Router AX1800','slug'=>'wireless-router-ax1800','sku'=>'ST-AX1800','regular_price'=>7200,'sale_price'=>6490,'stock'=>42,'image'=>'assets/images/gallery/product-images/02.png','shop_name'=>'Smart Tech OMP Official'],
    ['id'=>3,'name'=>'Android POS Barcode Kit','slug'=>'android-pos-barcode-kit','sku'=>'ST-POSKIT','regular_price'=>28500,'sale_price'=>26900,'stock'=>9,'image'=>'assets/images/gallery/product-images/03.png','shop_name'=>'Smart Tech OMP Official'],
    ['id'=>4,'name'=>'Solar IP Camera Pro','slug'=>'solar-ip-camera-pro','sku'=>'ST-IPCAM','regular_price'=>9800,'sale_price'=>8990,'stock'=>27,'image'=>'assets/images/gallery/product-images/04.png','shop_name'=>'Smart Tech OMP Official'],
]; }

function product_image(array $product): string {
    $image = trim((string)($product['image'] ?? ''));
    if ($image === '') return asset('images/gallery/product-images/01.png');
    if (preg_match('#^https?://#i', $image)) return $image;
    if (str_starts_with($image, 'public/')) return url($image);
    if (str_starts_with($image, 'assets/')) return url('public/' . $image);
    return asset(ltrim($image, '/'));
}

function table_empty(int $columns, string $message = 'No records found.'): string {
    return '<tr><td colspan="' . max(1, $columns) . '" class="text-center text-muted py-4">' . e($message) . '</td></tr>';
}

function app_base_path(): string {
    if (APP_URL !== '') {
        $path = (string)(parse_url(APP_URL, PHP_URL_PATH) ?? '');
        return rtrim($path, '/');
    }
    $base = app_base_url();
    if (preg_match('#^https?://#i', $base)) {
        return rtrim((string)(parse_url($base, PHP_URL_PATH) ?? ''), '/');
    }
    return rtrim($base, '/');
}

function config_warnings(): array {
    $warnings = [];
    if (APP_ENV === 'production' && APP_DEBUG) $warnings[] = 'APP_DEBUG must be disabled in production.';
    if (APP_URL === '') $warnings[] = 'APP_URL is not configured.';
    elseif (!filter_var(APP_URL, FILTER_VALIDATE_URL)) $warnings[] = 'APP_URL is not a valid absolute URL.';
    elseif (APP_ENV === 'production' && !str_starts_with(strtolower(APP_URL), 'https://')) $warnings[] = 'APP_URL should use HTTPS in production.';
    if (!App\Core\Database::configured()) $warnings[] = 'Database name and user are not configured.';
    if (APP_ENV === 'production' && strlen(APP_KEY) < 32) $warnings[] = 'APP_KEY should contain at least 32 random characters.';
    if (APP_ENV === 'production' && strlen(CRON_TOKEN) < 24) $warnings[] = 'CRON_TOKEN should contain at least 24 random characters.';
    if (APP_ENV === 'production' && PAYMENT_SANDBOX === false && (SSLCOMMERZ_STORE_ID === '' || SSLCOMMERZ_STORE_PASSWORD === '')) $warnings[] = 'Live payment mode is enabled without SSLCommerz credentials.';
    return $warnings;
}

/**
 * Sanitize limited rich-text HTML entered through trusted dashboard editors.
 * Keeps common formatting while removing scripts, event handlers and unsafe URLs.
 */
function sanitize_rich_html(string $html): string {
    $html = trim($html);
    if ($html === '') return '';

    $html = preg_replace('#<(script|style|noscript|template|svg|math)[^>]*>.*?</\1>#is', '', $html) ?? '';
    $allowedTags = '<div><p><br><strong><b><em><i><u><ul><ol><li><h2><h3><h4><blockquote><a>';
    $html = strip_tags($html, $allowedTags);
    $html = preg_replace('/<!--.*?-->/s', '', $html) ?? '';
    $html = preg_replace('/\s+on[a-z]+\s*=\s*("[^"]*"|\'[^\']*\'|[^\s>]+)/i', '', $html) ?? '';
    $html = preg_replace('/\s+(style|class|id|src|formaction)\s*=\s*("[^"]*"|\'[^\']*\'|[^\s>]+)/i', '', $html) ?? '';

    $html = preg_replace_callback('/<a\b([^>]*)>/i', static function (array $match): string {
        $attributes = $match[1] ?? '';
        $href = '';
        if (preg_match('/\bhref\s*=\s*("([^"]*)"|\'([^\']*)\'|([^\s>]+))/i', $attributes, $hrefMatch)) {
            $href = html_entity_decode((string) ($hrefMatch[2] ?: ($hrefMatch[3] ?: ($hrefMatch[4] ?? ''))), ENT_QUOTES | ENT_HTML5, 'UTF-8');
        }
        $href = trim($href);
        if ($href === '' || preg_match('/^(javascript|data|vbscript):/i', $href)) return '<a>';
        if (!preg_match('#^(https?://|mailto:|tel:|/|\#)#i', $href)) return '<a>';
        return '<a href="' . e($href) . '" target="_blank" rel="noopener noreferrer">';
    }, $html) ?? '';

    return trim($html);
}
