<?php
declare(strict_types=1);

/**
 * /profile/coins.php
 *
 * Сторінка керування VM Coins:
 * - баланс
 * - власний промокод
 * - хто запросив
 * - застосування чужого промокоду (1 раз)
 * - останні 5 транзакцій
 * - переказ VM Coins між користувачами
 *
 * Оновлено:
 * - додано нормальні підписи для reaction-транзакцій
 * - підтримано нові ключі:
 *   - post_reaction_adjust
 *   - comment_reaction_adjust
 *   - referral_bonus_referrer
 *   - referral_bonus_referred
 *   - user_transfer_out
 *   - user_transfer_in
 * - для історії транзакцій підтягується meta_json і формується людський опис дії
 * - автооновлення чисел працює лише на цій сторінці
 * - справа блок ігор підключено ПІД блоком груп
 * - реалізовано переказ VM Coins іншому користувачу по username
 * - при нестачі монет показується помилка без від’ємного балансу
 *
 * SEO:
 * - noindex, nofollow
 * - canonical на /profile/coins.php
 */

require_once __DIR__ . '/../includes/start.php';
require_login();

$vmCoinsLibPath = __DIR__ . '/../functional/VMCoins/_lib.php';
if (is_file($vmCoinsLibPath)) {
    require_once $vmCoinsLibPath;
}

/** @var PDO|null $pdo */
/** @var array|null $me */
$pdo = (isset($pdo) && $pdo instanceof PDO) ? $pdo : db();
$me  = $me ?? current_user();

if (!function_exists('h')) {
    function h(?string $s): string { return htmlspecialchars((string)$s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
}

$userId = (int)(is_array($me) ? ($me['id'] ?? 0) : 0);
if ($userId <= 0) {
    header('Location: /login.php');
    exit;
}

/* ===== helpers ===== */
if (!function_exists('vmc_profile_starts_with')) {
    function vmc_profile_starts_with(string $hay, string $needle): bool {
        if ($needle === '') return true;
        if (function_exists('str_starts_with')) return str_starts_with($hay, $needle);
        return (strlen($hay) >= strlen($needle) && substr($hay, 0, strlen($needle)) === $needle);
    }
}

if (!function_exists('db_has_column')) {
    function db_has_column(PDO $pdo, string $table, string $col): bool {
        static $cache = [];
        $k = $table . '.' . $col;
        if (array_key_exists($k, $cache)) return (bool)$cache[$k];

        try {
            $st = $pdo->prepare("
                SELECT 1
                FROM information_schema.columns
                WHERE table_schema = DATABASE()
                  AND table_name = ?
                  AND column_name = ?
                LIMIT 1
            ");
            $st->execute([$table, $col]);
            $cache[$k] = (bool)$st->fetchColumn();
            return (bool)$cache[$k];
        } catch (Throwable $e) {
            $cache[$k] = false;
            return false;
        }
    }
}

if (!function_exists('vmc_profile_table_exists')) {
    function vmc_profile_table_exists(PDO $pdo, string $table): bool {
        static $cache = [];
        if (array_key_exists($table, $cache)) return (bool)$cache[$table];

        try {
            $st = $pdo->prepare("
                SELECT 1
                FROM information_schema.tables
                WHERE table_schema = DATABASE()
                  AND table_name = ?
                LIMIT 1
            ");
            $st->execute([$table]);
            $cache[$table] = (bool)$st->fetchColumn();
            return (bool)$cache[$table];
        } catch (Throwable $e) {
            $cache[$table] = false;
            return false;
        }
    }
}

if (!function_exists('vm_lower')) {
    function vm_lower(string $s): string {
        $s = trim($s);
        if ($s === '') return '';
        return function_exists('mb_strtolower') ? mb_strtolower($s) : strtolower($s);
    }
}

if (!function_exists('vm_post_csrf_value')) {
    function vm_post_csrf_value(): string {
        $t = (string)($_POST['csrf'] ?? '');
        if ($t === '') $t = (string)($_POST['csrf_token'] ?? '');
        if ($t === '') $t = (string)($_POST['_csrf'] ?? '');
        return trim($t);
    }
}

if (!function_exists('vm_csrf_ok')) {
    function vm_csrf_ok(string $token): bool {
        if (function_exists('csrf_check')) {
            try { return (bool)csrf_check($token); } catch (Throwable $e) { /* fallback below */ }
        }
        if (session_status() !== PHP_SESSION_ACTIVE) @session_start();
        $sess = (string)($_SESSION['_csrf'] ?? ($_SESSION['csrf_token'] ?? ''));
        if ($sess === '' || $token === '') return false;
        return function_exists('hash_equals') ? hash_equals($sess, $token) : ($sess === $token);
    }
}

if (!function_exists('vm_redirect')) {
    function vm_redirect(string $to): void {
        if (function_exists('redirect')) {
            redirect($to);
            return;
        }
        $code = (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') ? 303 : 302;
        header('Location: ' . $to, true, $code);
        exit;
    }
}

if (!function_exists('vmc_profile_json_decode')) {
    function vmc_profile_json_decode(?string $json): array {
        $json = trim((string)$json);
        if ($json === '') return [];

        try {
            $data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
            return is_array($data) ? $data : [];
        } catch (Throwable $e) {
            return [];
        }
    }
}

if (!function_exists('vmc_profile_find_user_by_username')) {
    function vmc_profile_find_user_by_username(PDO $pdo, string $username): ?array {
        $username = trim($username);
        $username = ltrim($username, '@');

        if ($username === '') {
            return null;
        }

        if (function_exists('vmc_find_user_by_username')) {
            try {
                $row = vmc_find_user_by_username($pdo, $username);
                if (is_array($row) && $row) {
                    return $row;
                }
            } catch (Throwable $e) {
                // fallback below
            }
        }

        if (!db_has_column($pdo, 'users', 'username')) {
            return null;
        }

        $needle = function_exists('mb_strtolower')
            ? mb_strtolower($username, 'UTF-8')
            : strtolower($username);

        $cols = ['id', 'username'];
        if (db_has_column($pdo, 'users', 'vm_coins_balance')) $cols[] = 'vm_coins_balance';
        if (db_has_column($pdo, 'users', 'full_name')) {
            $cols[] = 'full_name';
        } else {
            if (db_has_column($pdo, 'users', 'first_name')) $cols[] = 'first_name';
            if (db_has_column($pdo, 'users', 'last_name')) $cols[] = 'last_name';
        }

        $sql = "
            SELECT " . implode(',', array_unique($cols)) . "
            FROM users
            WHERE LOWER(username) = ?
            LIMIT 1
        ";
        $st = $pdo->prepare($sql);
        $st->execute([$needle]);

        $row = $st->fetch(PDO::FETCH_ASSOC);
        return $row ?: null;
    }
}

if (!function_exists('vmc_profile_user_label')) {
    function vmc_profile_user_label(array $row): string {
        if (function_exists('vmc_user_display_name')) {
            try {
                $label = trim((string)vmc_user_display_name($row));
                if ($label !== '') return $label;
            } catch (Throwable $e) {
                // fallback below
            }
        }

        $username = trim((string)($row['username'] ?? ''));
        $fullName = trim((string)($row['full_name'] ?? ''));

        if ($fullName === '') {
            $first = trim((string)($row['first_name'] ?? ''));
            $last  = trim((string)($row['last_name'] ?? ''));
            $fullName = trim($first . ' ' . $last);
        }

        if ($fullName !== '' && $username !== '') {
            return $fullName . ' (@' . $username . ')';
        }

        if ($fullName !== '') {
            return $fullName;
        }

        if ($username !== '') {
            return '@' . $username;
        }

        $id = (int)($row['id'] ?? 0);
        return $id > 0 ? ('#' . $id) : '';
    }
}

if (!function_exists('vmc_profile_load_recent_transactions')) {
    function vmc_profile_load_recent_transactions(PDO $pdo, int $userId, int $limit = 5): array {
        if ($userId <= 0 || !vmc_profile_table_exists($pdo, 'vm_coin_transactions')) {
            return [];
        }

        $limit = max(1, min(100, $limit));

        try {
            $sql = "
                SELECT
                    id,
                    user_id,
                    delta_amount,
                    balance_after,
                    event_key,
                    entity_type,
                    entity_id,
                    related_user_id,
                    note,
                    meta_json,
                    created_at
                FROM vm_coin_transactions
                WHERE user_id = ?
                ORDER BY id DESC
                LIMIT {$limit}
            ";
            $st = $pdo->prepare($sql);
            $st->execute([$userId]);
            return $st->fetchAll(PDO::FETCH_ASSOC) ?: [];
        } catch (Throwable $e) {
            return [];
        }
    }
}

if (!function_exists('vmc_profile_load_user_map')) {
    function vmc_profile_load_user_map(PDO $pdo, array $transactions): array {
        if (!$transactions || !vmc_profile_table_exists($pdo, 'users')) {
            return [];
        }

        $ids = [];
        foreach ($transactions as $tx) {
            $rel = (int)($tx['related_user_id'] ?? 0);
            if ($rel > 0) $ids[$rel] = $rel;
        }

        if (!$ids) return [];

        $cols = ['id'];
        if (db_has_column($pdo, 'users', 'username')) $cols[] = 'username';
        if (db_has_column($pdo, 'users', 'full_name')) {
            $cols[] = 'full_name';
        } else {
            if (db_has_column($pdo, 'users', 'first_name')) $cols[] = 'first_name';
            if (db_has_column($pdo, 'users', 'last_name')) $cols[] = 'last_name';
        }

        $placeholders = implode(',', array_fill(0, count($ids), '?'));
        $sql = "SELECT " . implode(',', array_unique($cols)) . " FROM users WHERE id IN ($placeholders)";
        $st = $pdo->prepare($sql);
        $st->execute(array_values($ids));
        $rows = $st->fetchAll(PDO::FETCH_ASSOC) ?: [];

        $map = [];
        foreach ($rows as $row) {
            $id = (int)($row['id'] ?? 0);
            if ($id > 0) $map[$id] = $row;
        }

        return $map;
    }
}

if (!function_exists('vmc_profile_transfer_party_label')) {
    function vmc_profile_transfer_party_label(array $tx, array $userMap): string {
        $relatedUserId = (int)($tx['related_user_id'] ?? 0);
        if ($relatedUserId > 0 && isset($userMap[$relatedUserId]) && is_array($userMap[$relatedUserId])) {
            $label = trim(vmc_profile_user_label($userMap[$relatedUserId]));
            if ($label !== '') return $label;
        }

        if ($relatedUserId > 0) return '#' . $relatedUserId;
        return '';
    }
}

if (!function_exists('vmc_profile_reaction_action_label')) {
    function vmc_profile_reaction_action_label(
        string $entityType,
        string $side,
        string $oldReaction,
        string $newReaction,
        callable $T
    ): string {
        $entityType = trim($entityType) === 'comment' ? 'comment' : 'post';
        $side = trim($side) === 'actor' ? 'actor' : 'author';
        $oldReaction = trim($oldReaction);
        $newReaction = trim($newReaction);

        if ($side === 'actor') {
            if ($oldReaction === '' && $newReaction === 'like') {
                return $entityType === 'comment'
                    ? $T('Ви поставили лайк коментарю', 'Вы поставили лайк комментарию', 'You liked a comment')
                    : $T('Ви поставили лайк посту', 'Вы поставили лайк посту', 'You liked a post');
            }

            if ($oldReaction === '' && $newReaction === 'dislike') {
                return $entityType === 'comment'
                    ? $T('Ви поставили дизлайк коментарю', 'Вы поставили дизлайк комментарию', 'You disliked a comment')
                    : $T('Ви поставили дизлайк посту', 'Вы поставили дизлайк посту', 'You disliked a post');
            }

            if ($oldReaction === 'like' && $newReaction === '') {
                return $entityType === 'comment'
                    ? $T('Ви прибрали лайк з коментаря', 'Вы убрали лайк с комментария', 'You removed a like from a comment')
                    : $T('Ви прибрали лайк з поста', 'Вы убрали лайк с поста', 'You removed a like from a post');
            }

            if ($oldReaction === 'dislike' && $newReaction === '') {
                return $entityType === 'comment'
                    ? $T('Ви прибрали дизлайк з коментаря', 'Вы убрали дизлайк с комментария', 'You removed a dislike from a comment')
                    : $T('Ви прибрали дизлайк з поста', 'Вы убрали дизлайк с поста', 'You removed a dislike from a post');
            }

            if ($oldReaction === 'like' && $newReaction === 'dislike') {
                return $entityType === 'comment'
                    ? $T('Ви змінили лайк на дизлайк у коментаря', 'Вы сменили лайк на дизлайк у комментария', 'You changed like to dislike on a comment')
                    : $T('Ви змінили лайк на дизлайк у поста', 'Вы сменили лайк на дизлайк у поста', 'You changed like to dislike on a post');
            }

            if ($oldReaction === 'dislike' && $newReaction === 'like') {
                return $entityType === 'comment'
                    ? $T('Ви змінили дизлайк на лайк у коментаря', 'Вы сменили дизлайк на лайк у комментария', 'You changed dislike to like on a comment')
                    : $T('Ви змінили дизлайк на лайк у поста', 'Вы сменили дизлайк на лайк у поста', 'You changed dislike to like on a post');
            }

            return $entityType === 'comment'
                ? $T('Ваша реакція на коментар', 'Ваша реакция на комментарий', 'Your reaction to a comment')
                : $T('Ваша реакція на пост', 'Ваша реакция на пост', 'Your reaction to a post');
        }

        if ($oldReaction === '' && $newReaction === 'like') {
            return $entityType === 'comment'
                ? $T('Хтось поставив лайк вашому коментарю', 'Кто-то поставил лайк вашему комментарию', 'Someone liked your comment')
                : $T('Хтось поставив лайк вашому посту', 'Кто-то поставил лайк вашему посту', 'Someone liked your post');
        }

        if ($oldReaction === '' && $newReaction === 'dislike') {
            return $entityType === 'comment'
                ? $T('Хтось поставив дизлайк вашому коментарю', 'Кто-то поставил дизлайк вашему комментарию', 'Someone disliked your comment')
                : $T('Хтось поставив дизлайк вашому посту', 'Кто-то поставил дизлайк вашему посту', 'Someone disliked your post');
        }

        if ($oldReaction === 'like' && $newReaction === '') {
            return $entityType === 'comment'
                ? $T('З вашого коментаря прибрали лайк', 'С вашего комментария убрали лайк', 'A like was removed from your comment')
                : $T('З вашого поста прибрали лайк', 'С вашего поста убрали лайк', 'A like was removed from your post');
        }

        if ($oldReaction === 'dislike' && $newReaction === '') {
            return $entityType === 'comment'
                ? $T('З вашого коментаря прибрали дизлайк', 'С вашего комментария убрали дизлайк', 'A dislike was removed from your comment')
                : $T('З вашого поста прибрали дизлайк', 'С вашего поста убрали дизлайк', 'A dislike was removed from your post');
        }

        if ($oldReaction === 'like' && $newReaction === 'dislike') {
            return $entityType === 'comment'
                ? $T('У вашого коментаря лайк змінили на дизлайк', 'У вашего комментария лайк сменили на дизлайк', 'A like on your comment was changed to a dislike')
                : $T('У вашого поста лайк змінили на дизлайк', 'У вашего поста лайк сменили на дизлайк', 'A like on your post was changed to a dislike');
        }

        if ($oldReaction === 'dislike' && $newReaction === 'like') {
            return $entityType === 'comment'
                ? $T('У вашого коментаря дизлайк змінили на лайк', 'У вашего комментария дизлайк сменили на лайк', 'A dislike on your comment was changed to a like')
                : $T('У вашого поста дизлайк змінили на лайк', 'У вашего поста дизлайк сменили на лайк', 'A dislike on your post was changed to a like');
        }

        return $entityType === 'comment'
            ? $T('Реакція на ваш коментар', 'Реакция на ваш комментарий', 'Reaction to your comment')
            : $T('Реакція на ваш пост', 'Реакция на ваш пост', 'Reaction to your post');
    }
}

if (!function_exists('vmc_profile_event_label')) {
    function vmc_profile_event_label(array $tx, callable $T): string {
        $key = trim((string)($tx['event_key'] ?? ''));
        $meta = vmc_profile_json_decode((string)($tx['meta_json'] ?? ''));
        $entityType = trim((string)($tx['entity_type'] ?? ''));
        $note = trim((string)($tx['note'] ?? ''));

        switch ($key) {
            case 'post_create':
                return $T('Створення поста', 'Создание поста', 'Post creation');

            case 'comment_create':
                return $T('Створення коментаря', 'Создание комментария', 'Comment creation');

            case 'post_like_author':
                return $T('Лайк поста', 'Лайк поста', 'Post like');

            case 'post_dislike_author':
                return $T('Дизлайк поста', 'Дизлайк поста', 'Post dislike');

            case 'comment_like_author':
                return $T('Лайк коментаря', 'Лайк комментария', 'Comment like');

            case 'comment_dislike_author':
                return $T('Дизлайк коментаря', 'Дизлайк комментария', 'Comment dislike');

            case 'referral_referrer_bonus':
            case 'referral_bonus_referrer':
                return $T('Бонус за запрошеного користувача', 'Бонус за приглашённого пользователя', 'Referral inviter bonus');

            case 'referral_referred_bonus':
            case 'referral_bonus_referred':
                return $T('Бонус за застосування промокоду', 'Бонус за применение промокода', 'Referral applied bonus');

            case 'admin_adjust':
                return $T('Коригування адміністратором', 'Корректировка администратором', 'Admin adjustment');

            case 'user_transfer_out':
                return $T('Переказ користувачу', 'Перевод пользователю', 'Transfer to user');

            case 'user_transfer_in':
                return $T('Отримання переказу', 'Получение перевода', 'Incoming transfer');

            case 'post_reaction_adjust':
            case 'comment_reaction_adjust':
                $side = trim((string)($meta['reward_side'] ?? ''));
                if ($side === '' && preg_match('/\((author|actor)\)/i', $note, $m)) {
                    $side = vm_lower((string)($m[1] ?? ''));
                }
                if ($side !== 'author' && $side !== 'actor') {
                    $side = 'author';
                }

                $oldReaction = trim((string)($meta['old_reaction'] ?? ''));
                $newReaction = trim((string)($meta['new_reaction'] ?? ''));

                if ($entityType !== 'post' && $entityType !== 'comment') {
                    $entityType = ($key === 'comment_reaction_adjust') ? 'comment' : 'post';
                }

                return vmc_profile_reaction_action_label($entityType, $side, $oldReaction, $newReaction, $T);

            default:
                return $key !== '' ? $key : $T('Операція', 'Операция', 'Operation');
        }
    }
}

if (!function_exists('vmc_profile_event_subnote')) {
    function vmc_profile_event_subnote(array $tx, callable $T, array $userMap = []): string {
        $key = trim((string)($tx['event_key'] ?? ''));
        $meta = vmc_profile_json_decode((string)($tx['meta_json'] ?? ''));
        $note = trim((string)($tx['note'] ?? ''));

        if ($key === 'user_transfer_out' || $key === 'user_transfer_in') {
            $parts = [];

            $partyLabel = vmc_profile_transfer_party_label($tx, $userMap);
            if ($partyLabel !== '') {
                $parts[] = $key === 'user_transfer_out'
                    ? ($T('Одержувач', 'Получатель', 'Recipient') . ': ' . $partyLabel)
                    : ($T('Відправник', 'Отправитель', 'Sender') . ': ' . $partyLabel);
            }

            $noteLower = vm_lower($note);
            if ($note !== '' && $noteLower !== 'vm coins transfer') {
                $parts[] = $note;
            }

            return implode(' · ', $parts);
        }

        if ($key !== 'post_reaction_adjust' && $key !== 'comment_reaction_adjust') {
            return $note;
        }

        $side = trim((string)($meta['reward_side'] ?? ''));
        $oldReaction = trim((string)($meta['old_reaction'] ?? ''));
        $newReaction = trim((string)($meta['new_reaction'] ?? ''));
        $delta = (int)($meta['delta'] ?? ($tx['delta_amount'] ?? 0));

        $sideLabel = $side === 'actor'
            ? $T('ваша дія', 'ваше действие', 'your action')
            : $T('вплив на автора', 'влияние на автора', 'effect on author');

        $oldLabel = $oldReaction !== '' ? $oldReaction : $T('немає', 'нет', 'none');
        $newLabel = $newReaction !== '' ? $newReaction : $T('немає', 'нет', 'none');

        return $T(
            'Сторона: ' . $sideLabel . ' · ' . $oldLabel . ' → ' . $newLabel . ' · Δ ' . ($delta > 0 ? '+' : '') . $delta,
            'Сторона: ' . $sideLabel . ' · ' . $oldLabel . ' → ' . $newLabel . ' · Δ ' . ($delta > 0 ? '+' : '') . $delta,
            'Side: ' . $sideLabel . ' · ' . $oldLabel . ' → ' . $newLabel . ' · Δ ' . ($delta > 0 ? '+' : '') . $delta
        );
    }
}

/* ===== columns ===== */
$hasFullName       = db_has_column($pdo, 'users', 'full_name');
$hasAvatarCol      = db_has_column($pdo, 'users', 'avatar_path');
$hasVmBalanceCol   = db_has_column($pdo, 'users', 'vm_coins_balance');
$hasVmEarnedCol    = db_has_column($pdo, 'users', 'vm_coins_earned_total');
$hasVmSpentCol     = db_has_column($pdo, 'users', 'vm_coins_spent_total');
$hasVmRefCode      = db_has_column($pdo, 'users', 'vm_ref_code');
$hasVmReferredBy   = db_has_column($pdo, 'users', 'vm_referred_by_user_id');
$hasVmRefAppliedAt = db_has_column($pdo, 'users', 'vm_ref_applied_at');

/* ===== load fresh user ===== */
$cols = ['id','email','username','lang','role'];
if ($hasFullName) $cols[] = 'full_name';
else { $cols[] = 'first_name'; $cols[] = 'last_name'; }
if ($hasAvatarCol) $cols[] = 'avatar_path';
if ($hasVmBalanceCol) $cols[] = 'vm_coins_balance';
if ($hasVmEarnedCol) $cols[] = 'vm_coins_earned_total';
if ($hasVmSpentCol) $cols[] = 'vm_coins_spent_total';
if ($hasVmRefCode) $cols[] = 'vm_ref_code';
if ($hasVmReferredBy) $cols[] = 'vm_referred_by_user_id';
if ($hasVmRefAppliedAt) $cols[] = 'vm_ref_applied_at';

$st = $pdo->prepare("SELECT " . implode(',', array_unique($cols)) . " FROM users WHERE id=? LIMIT 1");
$st->execute([$userId]);
$u = $st->fetch(PDO::FETCH_ASSOC) ?: null;
if (!$u) {
    header('Location: /');
    exit;
}

/* ===== Lang ===== */
$lang = function_exists('lang') ? (string)lang() : (string)($_SESSION['lang'] ?? ($u['lang'] ?? 'uk'));
if (!in_array($lang, ['uk','ru','en'], true)) $lang = 'uk';
$T = function(string $uk, string $ru, string $en) use ($lang): string {
    if ($lang === 'ru') return $ru;
    if ($lang === 'en') return $en;
    return $uk;
};

$title = 'VM Coins';

/* ===== SEO ===== */
$seo_noindex = true;
$meta_robots = 'noindex, nofollow, noarchive, nosnippet';
$meta_desc   = '';
$canonicalPath = '/profile/coins.php';
$canonical = function_exists('abs_url') ? abs_url($canonicalPath) : $canonicalPath;
if (!headers_sent()) {
    header('X-Robots-Tag: ' . $meta_robots, true);
    header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0', true);
    header('Pragma: no-cache', true);
    header('Expires: 0', true);
}

/* ===== state ===== */
$okMsg  = '';
$errMsg = '';

if (function_exists('flash_get')) {
    $okMsg  = (string)(flash_get('ok') ?? '');
    $errMsg = (string)(flash_get('err') ?? flash_get('error') ?? '');
}

$username   = (string)($u['username'] ?? '');
$avatarPath = $hasAvatarCol ? trim((string)($u['avatar_path'] ?? '')) : '';
$profileHref = '/profile/';
if ($username !== '') $profileHref = '/profile/?u=' . rawurlencode($username);

/* ===== transfer form state ===== */
$transferUsernameInput = '';
$transferAmountInput   = '';

/* ===== VM Coins / Promo ===== */
$vmcReady = function_exists('vmc_referral_columns_exist')
    && function_exists('vmc_referrals_enabled')
    && function_exists('vmc_ensure_user_ref_code')
    && function_exists('vmc_apply_referral_code')
    && vmc_referral_columns_exist($pdo);

$vmcCoinsReady = function_exists('vmc_get_balance') && function_exists('vmc_get_user_referrals_count');
$vmcTransferReady = function_exists('vmc_transfer_between_users');
$vmcEnabled = function_exists('vmc_enabled') ? (bool)vmc_enabled($pdo) : true;
$vmcPromoEnabled = $vmcReady ? (bool)vmc_referrals_enabled($pdo) : false;
$vmcRequireActive = function_exists('vmc_referral_require_active') ? (bool)vmc_referral_require_active($pdo) : true;
$vmcUserIsActive = function_exists('vmc_user_is_active') ? (bool)vmc_user_is_active($pdo, $userId) : true;

$vmcBalance        = $hasVmBalanceCol ? (int)($u['vm_coins_balance'] ?? 0) : 0;
$vmcEarnedTotal    = $hasVmEarnedCol ? (int)($u['vm_coins_earned_total'] ?? 0) : 0;
$vmcSpentTotal     = $hasVmSpentCol ? (int)($u['vm_coins_spent_total'] ?? 0) : 0;
$myRefCode         = '';
$myReferrerId      = $hasVmReferredBy ? (int)($u['vm_referred_by_user_id'] ?? 0) : 0;
$myRefAppliedAt    = $hasVmRefAppliedAt ? trim((string)($u['vm_ref_applied_at'] ?? '')) : '';
$myReferralsCount  = 0;
$referrerLabel     = '';
$promoAlreadyApplied = ($myReferrerId > 0 || $myRefAppliedAt !== '');

if ($vmcCoinsReady) {
    try { $vmcBalance = vmc_get_balance($pdo, $userId); } catch (Throwable $e) { /* keep current */ }
    try { $myReferralsCount = vmc_get_user_referrals_count($pdo, $userId); } catch (Throwable $e) { $myReferralsCount = 0; }
}

if ($vmcReady) {
    $myRefCode = trim((string)($u['vm_ref_code'] ?? ''));
    if ($myRefCode === '') {
        try {
            $myRefCode = vmc_ensure_user_ref_code($pdo, $userId, $username);
        } catch (Throwable $e) {
            $myRefCode = '';
        }
    }

    if ($myReferrerId > 0) {
        try {
            $st = $pdo->prepare("
                SELECT id, username, first_name, last_name, full_name
                FROM users
                WHERE id = ?
                LIMIT 1
            ");
            $st->execute([$myReferrerId]);
            $refRow = $st->fetch(PDO::FETCH_ASSOC) ?: null;
            if ($refRow) {
                $referrerLabel = vmc_profile_user_label($refRow);
            } else {
                $referrerLabel = '#' . $myReferrerId;
            }
        } catch (Throwable $e) {
            $referrerLabel = '#' . $myReferrerId;
        }
    }
}

/* ===== recent transactions ===== */
$recentTransactions = vmc_profile_load_recent_transactions($pdo, $userId, 5);
$hasTxTable = vmc_profile_table_exists($pdo, 'vm_coin_transactions');
$recentUserMap = vmc_profile_load_user_map($pdo, $recentTransactions);

/* ===== POST actions ===== */
$selfUrl = '/profile/coins.php';

if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') {
    $action = (string)($_POST['action'] ?? '');
    $csrf = vm_post_csrf_value();

    if (!vm_csrf_ok($csrf)) {
        $errMsg = $T(
            'Помилка безпеки (CSRF). Онови сторінку і спробуй ще раз.',
            'Ошибка безопасности (CSRF). Обнови страницу и попробуй снова.',
            'Security error (CSRF). Refresh and try again.'
        );
    } else {
        try {
            if ($action === 'apply_ref_code') {
                if (!$vmcReady) {
                    $errMsg = $T(
                        'Промокоди ще не підготовлені. Спочатку застосуйте SQL-міграцію Stage 2.',
                        'Промокоды ещё не подготовлены. Сначала примените SQL-миграцию Stage 2.',
                        'Promo codes are not ready yet. Apply the Stage 2 SQL migration first.'
                    );
                } else {
                    $enteredCode = trim((string)($_POST['ref_code'] ?? ''));
                    $res = vmc_apply_referral_code($pdo, $userId, $enteredCode);

                    if (!($res['ok'] ?? false)) {
                        $reason = (string)($res['reason'] ?? '');

                        $errMsg = match ($reason) {
                            'disabled' => $T(
                                'Промокоди зараз вимкнені.',
                                'Промокоды сейчас выключены.',
                                'Promo codes are disabled right now.'
                            ),
                            'bad_code' => $T(
                                'Введіть коректний промокод.',
                                'Введите корректный промокод.',
                                'Enter a valid promo code.'
                            ),
                            'code_not_found' => $T(
                                'Такий промокод не знайдено.',
                                'Такой промокод не найден.',
                                'Promo code not found.'
                            ),
                            'self_code' => $T(
                                'Не можна застосувати власний промокод.',
                                'Нельзя применить собственный промокод.',
                                'You cannot apply your own promo code.'
                            ),
                            'already_applied' => $T(
                                'Промокод уже був застосований раніше.',
                                'Промокод уже был применён ранее.',
                                'A promo code was already applied earlier.'
                            ),
                            'inactive_user' => $T(
                                'Спочатку активуйте акаунт, а потім застосуйте промокод.',
                                'Сначала активируйте аккаунт, а потом применяйте промокод.',
                                'Activate your account first, then apply the promo code.'
                            ),
                            'referrer_inactive' => $T(
                                'Власник цього промокоду ще не активував акаунт.',
                                'Владелец этого промокода ещё не активировал аккаунт.',
                                'The owner of this promo code has not activated their account yet.'
                            ),
                            'schema_missing' => $T(
                                'У базі ще немає потрібних полів для промокодів.',
                                'В базе ещё нет нужных полей для промокодов.',
                                'The database is missing required promo-code fields.'
                            ),
                            default => $T(
                                'Не вдалося застосувати промокод.',
                                'Не удалось применить промокод.',
                                'Failed to apply promo code.'
                            ),
                        };
                    } else {
                        $bonusText = '';
                        $referredBonus = (int)($res['referred_bonus'] ?? 0);

                        if ($referredBonus > 0) {
                            $bonusText = ' +' . $referredBonus . ' VM Coins';
                        }

                        $okMsg = $T(
                            'Промокод застосовано успішно.' . $bonusText,
                            'Промокод успешно применён.' . $bonusText,
                            'Promo code applied successfully.' . $bonusText
                        );

                        if (function_exists('flash_set')) flash_set('ok', $okMsg);
                        vm_redirect($selfUrl);
                    }
                }
            } elseif ($action === 'transfer_coins') {
                $transferUsernameInput = trim((string)($_POST['transfer_username'] ?? ''));
                $transferAmountInput   = trim((string)($_POST['transfer_amount'] ?? ''));

                if (!$vmcEnabled) {
                    $errMsg = $T(
                        'VM Coins зараз вимкнено.',
                        'VM Coins сейчас отключены.',
                        'VM Coins are currently disabled.'
                    );
                } elseif (!$vmcTransferReady) {
                    $errMsg = $T(
                        'Перекази VM Coins ще не готові.',
                        'Переводы VM Coins ещё не готовы.',
                        'VM Coins transfers are not ready yet.'
                    );
                } else {
                    $recipientUsername = ltrim($transferUsernameInput, '@');
                    $amount = is_numeric($transferAmountInput) ? (int)$transferAmountInput : 0;

                    if ($recipientUsername === '') {
                        $errMsg = $T(
                            'Введіть нік користувача.',
                            'Введите ник пользователя.',
                            'Enter the username.'
                        );
                    } elseif ($amount <= 0) {
                        $errMsg = $T(
                            'Вкажіть коректну суму переказу.',
                            'Укажите корректную сумму перевода.',
                            'Enter a valid transfer amount.'
                        );
                    } else {
                        $recipient = vmc_profile_find_user_by_username($pdo, $recipientUsername);

                        if (!$recipient) {
                            $errMsg = $T(
                                'Користувача з таким ніком не знайдено.',
                                'Пользователь с таким ником не найден.',
                                'A user with this username was not found.'
                            );
                        } else {
                            $recipientId = (int)($recipient['id'] ?? 0);

                            $res = vmc_transfer_between_users(
                                $pdo,
                                $userId,
                                $recipientId,
                                $amount,
                                null
                            );

                            if (!($res['ok'] ?? false)) {
                                $reason = (string)($res['reason'] ?? '');

                                if ($reason === 'insufficient_funds') {
                                    $available = (int)(
                                        $res['available_balance']
                                        ?? ($res['balance'] ?? 0)
                                    );

                                    if (isset($res['sender']) && is_array($res['sender'])) {
                                        $available = (int)(
                                            $res['sender']['available_balance']
                                            ?? ($res['sender']['balance'] ?? $available)
                                        );
                                    }

                                    $errMsg = $T(
                                        'Недостатньо VM Coins на рахунку, поповніть рахунок. Поточний баланс: ',
                                        'Недостаточно VM Coins на счёте, пополните счёт. Текущий баланс: ',
                                        'Not enough VM Coins on your balance, please top up your account. Current balance: '
                                    ) . $available;
                                } else {
                                    $errMsg = match ($reason) {
                                        'same_user' => $T(
                                            'Не можна переказати VM Coins самому собі.',
                                            'Нельзя перевести VM Coins самому себе.',
                                            'You cannot transfer VM Coins to yourself.'
                                        ),
                                        'bad_amount' => $T(
                                            'Вкажіть коректну суму переказу.',
                                            'Укажите корректную сумму перевода.',
                                            'Enter a valid transfer amount.'
                                        ),
                                        'recipient_not_found' => $T(
                                            'Одержувача не знайдено.',
                                            'Получатель не найден.',
                                            'Recipient not found.'
                                        ),
                                        'sender_not_found' => $T(
                                            'Ваш акаунт не знайдено.',
                                            'Ваш аккаунт не найден.',
                                            'Your account was not found.'
                                        ),
                                        'disabled' => $T(
                                            'VM Coins зараз вимкнено.',
                                            'VM Coins сейчас отключены.',
                                            'VM Coins are currently disabled.'
                                        ),
                                        default => $T(
                                            'Не вдалося виконати переказ VM Coins.',
                                            'Не удалось выполнить перевод VM Coins.',
                                            'Failed to transfer VM Coins.'
                                        ),
                                    };
                                }
                            } else {
                                $recipientLabel = vmc_profile_user_label($recipient);
                                $okMsg = $T(
                                    'Переказ успішно виконано: ',
                                    'Перевод успешно выполнен: ',
                                    'Transfer completed successfully: '
                                ) . $amount . ' VM Coins → ' . $recipientLabel;

                                if (function_exists('flash_set')) flash_set('ok', $okMsg);
                                vm_redirect($selfUrl);
                            }
                        }
                    }
                }
            } else {
                $errMsg = $T('Невідома дія.', 'Неизвестное действие.', 'Unknown action.');
            }
        } catch (Throwable $e) {
            $errMsg = $T(
                'Сталася помилка. Спробуйте ще раз.',
                'Произошла ошибка. Попробуйте ещё раз.',
                'An error occurred. Please try again.'
            );
        }
    }

    /* refresh after POST without redirect when there is an error */
    $st = $pdo->prepare("SELECT " . implode(',', array_unique($cols)) . " FROM users WHERE id=? LIMIT 1");
    $st->execute([$userId]);
    $u2 = $st->fetch(PDO::FETCH_ASSOC) ?: null;
    if ($u2) {
        $u = $u2;
        $username   = (string)($u['username'] ?? '');
        $avatarPath = $hasAvatarCol ? trim((string)($u['avatar_path'] ?? '')) : '';
        $profileHref = '/profile/';
        if ($username !== '') $profileHref = '/profile/?u=' . rawurlencode($username);

        $vmcBalance       = $hasVmBalanceCol ? (int)($u['vm_coins_balance'] ?? 0) : $vmcBalance;
        $vmcEarnedTotal   = $hasVmEarnedCol ? (int)($u['vm_coins_earned_total'] ?? 0) : $vmcEarnedTotal;
        $vmcSpentTotal    = $hasVmSpentCol ? (int)($u['vm_coins_spent_total'] ?? 0) : $vmcSpentTotal;
        $myReferrerId     = $hasVmReferredBy ? (int)($u['vm_referred_by_user_id'] ?? 0) : 0;
        $myRefAppliedAt   = $hasVmRefAppliedAt ? trim((string)($u['vm_ref_applied_at'] ?? '')) : '';
        $promoAlreadyApplied = ($myReferrerId > 0 || $myRefAppliedAt !== '');

        if ($vmcReady) {
            $myRefCode = trim((string)($u['vm_ref_code'] ?? ''));
            if ($myRefCode === '') {
                try { $myRefCode = vmc_ensure_user_ref_code($pdo, $userId, $username); } catch (Throwable $e) { $myRefCode = ''; }
            }
        }

        if ($vmcCoinsReady) {
            try { $vmcBalance = vmc_get_balance($pdo, $userId); } catch (Throwable $e) { /* keep current */ }
            try { $myReferralsCount = vmc_get_user_referrals_count($pdo, $userId); } catch (Throwable $e) { $myReferralsCount = 0; }
        }
    }

    $recentTransactions = vmc_profile_load_recent_transactions($pdo, $userId, 5);
    $recentUserMap = vmc_profile_load_user_map($pdo, $recentTransactions);
}

/* ===== Header + profile.css ===== */
$headerPath = __DIR__ . '/../includes/header.php';
ob_start();
require $headerPath;
$hdr = (string)ob_get_clean();

$cssHref = '/css/profile.css?v=4';
if (stripos($hdr, $cssHref) === false && strpos($hdr, '</head>') !== false) {
    $hdr = str_replace('</head>', "  <link rel=\"stylesheet\" href=\"" . h($cssHref) . "\">\n</head>", $hdr);
}
echo $hdr;

$csrfField = function_exists('csrf_field')
    ? (string)csrf_field()
    : '<input type="hidden" name="csrf" value="'.h((string)($_SESSION['_csrf'] ?? ($_SESSION['csrf_token'] ?? ''))).'">';
?>
<div class="feed-layout">
  <aside>
    <div class="sidebar-sticky">
      <?php require __DIR__ . '/../blocks/profile.php'; ?>
    </div>
  </aside>

  <section>
    <div class="card card-app p-3 mb-3">
      <div class="d-flex align-items-center justify-content-between gap-2 flex-wrap">
        <div>
          <div class="fw-semibold fs-5">VM Coins</div>
          <div class="text-muted small"><?= h($T('Баланс, промокод і останні операції','Баланс, промокод и последние операции','Balance, promo code, and recent operations')) ?></div>
        </div>
        <a class="btn btn-sm btn-outline-secondary" href="<?= h($profileHref) ?>"><?= h($T('Назад','Назад','Back')) ?></a>
      </div>

      <?php if ($okMsg !== ''): ?>
        <div class="alert alert-success mt-3 mb-0"><?= h($okMsg) ?></div>
      <?php elseif ($errMsg !== ''): ?>
        <div class="alert alert-danger mt-3 mb-0"><?= h($errMsg) ?></div>
      <?php endif; ?>
    </div>

    <div class="card card-app p-3 mb-3">
      <div class="d-flex align-items-center justify-content-between gap-2 flex-wrap mb-3">
        <div class="fw-semibold fs-6">VM Coins</div>
        <span class="badge <?= $vmcEnabled ? 'text-bg-success' : 'text-bg-secondary' ?>">
          <?= h($vmcEnabled ? $T('Увімкнено','Включено','Enabled') : $T('Вимкнено','Выключено','Disabled')) ?>
        </span>
      </div>

      <div class="row g-3">
        <div class="col-md-4">
          <div style="padding:16px;border:1px solid rgba(0,0,0,.08);border-radius:16px;background:linear-gradient(180deg,#ffffff,#f8fbff);height:100%;">
            <div class="text-muted small mb-1"><?= h($T('Баланс','Баланс','Balance')) ?></div>
            <div data-vmc-balance style="font-size:34px;font-weight:900;line-height:1;"><?= h((string)$vmcBalance) ?></div>
          </div>
        </div>

        <div class="col-md-4">
          <div style="padding:16px;border:1px solid rgba(0,0,0,.08);border-radius:16px;background:#fff;height:100%;">
            <div class="text-muted small mb-1"><?= h($T('Зароблено всього','Заработано всего','Earned total')) ?></div>
            <div data-vmc-earned style="font-size:28px;font-weight:800;line-height:1;"><?= h((string)$vmcEarnedTotal) ?></div>
          </div>
        </div>

        <div class="col-md-4">
          <div style="padding:16px;border:1px solid rgba(0,0,0,.08);border-radius:16px;background:#fff;height:100%;">
            <div class="text-muted small mb-1"><?= h($T('Списано всього','Списано всего','Spent total')) ?></div>
            <div data-vmc-spent style="font-size:28px;font-weight:800;line-height:1;"><?= h((string)$vmcSpentTotal) ?></div>
          </div>
        </div>
      </div>
    </div>

    <div class="card card-app p-3 mb-3">
      <div class="fw-semibold fs-6 mb-3"><?= h($T('Промокод і реферальна система','Промокод и реферальная система','Promo code and referrals')) ?></div>

      <?php if (!$vmcReady): ?>
        <div class="text-muted">
          <?= h($T(
            'Промокоди ще не готові. Спочатку застосуйте SQL-міграцію Stage 2.',
            'Промокоды ещё не готовы. Сначала примените SQL-миграцию Stage 2.',
            'Promo codes are not ready yet. Apply the Stage 2 SQL migration first.'
          )) ?>
        </div>
      <?php else: ?>
        <div class="row g-3">
          <div class="col-md-6">
            <label class="form-label"><?= h($T('Ваш промокод','Ваш промокод','Your promo code')) ?></label>
            <input class="form-control" type="text" value="<?= h($myRefCode) ?>" readonly>
            <div class="form-text">
              <?= h($T(
                'Цей код можна передавати іншим користувачам.',
                'Этот код можно передавать другим пользователям.',
                'You can share this code with other users.'
              )) ?>
            </div>
          </div>

          <div class="col-md-3">
            <label class="form-label"><?= h($T('Запрошено','Приглашено','Invited')) ?></label>
            <input class="form-control" type="text" value="<?= h((string)$myReferralsCount) ?>" readonly>
          </div>

          <div class="col-md-3">
            <label class="form-label"><?= h($T('Статус','Статус','Status')) ?></label>
            <input
              class="form-control"
              type="text"
              value="<?= h($promoAlreadyApplied ? $T('Промокод уже застосовано','Промокод уже применён','Promo code applied') : $T('Можна ввести код','Можно ввести код','You can enter a code')) ?>"
              readonly
            >
          </div>
        </div>

        <hr class="my-3">

        <?php if ($promoAlreadyApplied): ?>
          <div class="alert alert-success mb-0">
            <div class="fw-semibold mb-1"><?= h($T('Промокод уже застосовано','Промокод уже применён','Promo code already applied')) ?></div>
            <?php if ($referrerLabel !== ''): ?>
              <div><?= h($T('Вас запросив','Вас пригласил','You were invited by')) ?>: <?= h($referrerLabel) ?></div>
            <?php endif; ?>
            <?php if ($myRefAppliedAt !== ''): ?>
              <div class="small text-muted mt-1"><?= h($T('Дата застосування','Дата применения','Applied at')) ?>: <?= h($myRefAppliedAt) ?></div>
            <?php endif; ?>
          </div>
        <?php else: ?>
          <?php if ($vmcRequireActive && !$vmcUserIsActive): ?>
            <div class="alert alert-warning mb-0">
              <?= h($T(
                'Спочатку активуйте акаунт через лист, після цього зможете застосувати промокод.',
                'Сначала активируйте аккаунт через письмо, после этого сможете применить промокод.',
                'Activate your account by email first, then you can apply a promo code.'
              )) ?>
            </div>
          <?php elseif (!$vmcPromoEnabled): ?>
            <div class="alert alert-secondary mb-0">
              <?= h($T(
                'Промокоди тимчасово вимкнені адміністратором.',
                'Промокоды временно выключены администратором.',
                'Promo codes are temporarily disabled by the administrator.'
              )) ?>
            </div>
          <?php else: ?>
            <form method="post" class="mt-2">
              <?= $csrfField ?>
              <input type="hidden" name="action" value="apply_ref_code">

              <div class="mb-3">
                <label class="form-label"><?= h($T('Ввести промокод','Ввести промокод','Enter promo code')) ?></label>
                <input
                  class="form-control"
                  type="text"
                  name="ref_code"
                  maxlength="32"
                  placeholder="<?= h($T('Наприклад: DEMONX1234','Например: DEMONX1234','For example: DEMONX1234')) ?>"
                  required
                >
                <div class="form-text">
                  <?= h($T(
                    'Промокод можна застосувати лише 1 раз. Власний код застосувати не можна.',
                    'Промокод можно применить только 1 раз. Свой код применять нельзя.',
                    'A promo code can only be applied once. You cannot apply your own code.'
                  )) ?>
                </div>
              </div>

              <button class="btn btn-primary" type="submit"><?= h($T('Застосувати промокод','Применить промокод','Apply promo code')) ?></button>
            </form>
          <?php endif; ?>
        <?php endif; ?>
      <?php endif; ?>
    </div>

    <div class="card card-app p-3 mb-3">
      <div class="d-flex align-items-center justify-content-between gap-2 mb-3 flex-wrap">
        <div class="fw-semibold fs-6"><?= h($T('Останні 5 транзакцій','Последние 5 транзакций','Last 5 transactions')) ?></div>
        <?php if ($hasTxTable): ?>
          <span class="text-muted small"><?= h($T('Історія нарахувань та списань','История начислений и списаний','Credit and debit history')) ?></span>
        <?php endif; ?>
      </div>

      <?php if (!$hasTxTable): ?>
        <div class="text-muted">
          <?= h($T(
            'Таблиця транзакцій ще не створена.',
            'Таблица транзакций ещё не создана.',
            'The transactions table has not been created yet.'
          )) ?>
        </div>
      <?php elseif (!$recentTransactions): ?>
        <div class="text-muted">
          <?= h($T(
            'Транзакцій поки що немає.',
            'Транзакций пока нет.',
            'There are no transactions yet.'
          )) ?>
        </div>
      <?php else: ?>
        <div class="table-responsive">
          <table class="table align-middle mb-0">
            <thead>
              <tr>
                <th>#</th>
                <th><?= h($T('Подія','Событие','Event')) ?></th>
                <th><?= h($T('Сума','Сумма','Amount')) ?></th>
                <th><?= h($T('Баланс після','Баланс после','Balance after')) ?></th>
                <th><?= h($T('Час','Время','Time')) ?></th>
              </tr>
            </thead>
            <tbody>
              <?php foreach ($recentTransactions as $tx): ?>
                <?php
                  $delta = (int)($tx['delta_amount'] ?? 0);
                  $deltaClass = $delta > 0 ? 'text-success' : ($delta < 0 ? 'text-danger' : 'text-muted');
                  $eventLabel = vmc_profile_event_label($tx, $T);
                  $noteText = vmc_profile_event_subnote($tx, $T, $recentUserMap);
                ?>
                <tr>
                  <td><?= h((string)($tx['id'] ?? '')) ?></td>
                  <td>
                    <div class="fw-semibold"><?= h($eventLabel) ?></div>
                    <?php if ($noteText !== ''): ?>
                      <div class="small text-muted"><?= h($noteText) ?></div>
                    <?php endif; ?>
                  </td>
                  <td class="<?= h($deltaClass) ?>" style="font-weight:800;">
                    <?= h(($delta > 0 ? '+' : '') . (string)$delta) ?>
                  </td>
                  <td><?= h((string)($tx['balance_after'] ?? 0)) ?></td>
                  <td><?= h((string)($tx['created_at'] ?? '')) ?></td>
                </tr>
              <?php endforeach; ?>
            </tbody>
          </table>
        </div>
      <?php endif; ?>
    </div>

    <div class="row g-3">
      <div class="col-md-6">
        <div class="card card-app p-3 h-100">
          <div class="fw-semibold fs-6 mb-2"><?= h($T('Перекази між користувачами','Переводы между пользователями','Transfers between users')) ?></div>

          <?php if (!$vmcEnabled): ?>
            <div class="alert alert-secondary mb-0">
              <?= h($T(
                'VM Coins зараз вимкнено адміністратором.',
                'VM Coins сейчас отключены администратором.',
                'VM Coins are currently disabled by the administrator.'
              )) ?>
            </div>
          <?php elseif (!$vmcTransferReady): ?>
            <div class="text-muted"><?= h($T('В процесі розробки','В процессе разработки','In development')) ?></div>
          <?php else: ?>
            <form method="post">
              <?= $csrfField ?>
              <input type="hidden" name="action" value="transfer_coins">

              <div class="mb-3">
                <label class="form-label"><?= h($T('Нік користувача','Ник пользователя','Username')) ?></label>
                <input
                  class="form-control"
                  type="text"
                  name="transfer_username"
                  maxlength="100"
                  value="<?= h($transferUsernameInput) ?>"
                  placeholder="<?= h($T('Наприклад: demonx або @demonx','Например: demonx или @demonx','For example: demonx or @demonx')) ?>"
                  required
                >
                <div class="form-text">
                  <?= h($T(
                    'Вкажіть username користувача, якому хочете переказати VM Coins.',
                    'Укажите username пользователя, которому хотите перевести VM Coins.',
                    'Enter the username of the user you want to transfer VM Coins to.'
                  )) ?>
                </div>
              </div>

              <div class="mb-3">
                <label class="form-label"><?= h($T('Сума переказу','Сумма перевода','Transfer amount')) ?></label>
                <input
                  class="form-control"
                  type="number"
                  name="transfer_amount"
                  min="1"
                  step="1"
                  value="<?= h($transferAmountInput) ?>"
                  placeholder="100"
                  required
                >
                <div class="form-text">
                  <?= h($T(
                    'Якщо на рахунку не вистачає VM Coins, переказ не буде виконано.',
                    'Если на счёте не хватает VM Coins, перевод не будет выполнен.',
                    'If you do not have enough VM Coins, the transfer will not be completed.'
                  )) ?>
                </div>
              </div>

              <button class="btn btn-primary" type="submit">
                <?= h($T('Переказати','Перевести','Transfer')) ?>
              </button>
            </form>
          <?php endif; ?>
        </div>
      </div>

      <div class="col-md-6">
        <div class="card card-app p-3 h-100">
          <div class="fw-semibold fs-6 mb-2"><?= h($T('Покупки за VM Coins','Покупки за VM Coins','Purchases for VM Coins')) ?></div>
          <div class="text-muted"><?= h($T('В процесі розробки','В процессе разработки','In development')) ?></div>
        </div>
      </div>

      <div class="col-md-6">
        <div class="card card-app p-3 h-100">
          <div class="fw-semibold fs-6 mb-2"><?= h($T('Обмін / вивід','Обмен / вывод','Exchange / withdrawal')) ?></div>
          <div class="text-muted"><?= h($T('В процесі розробки','В процессе разработки','In development')) ?></div>
        </div>
      </div>

      <div class="col-md-6">
        <div class="card card-app p-3 h-100">
          <div class="fw-semibold fs-6 mb-2"><?= h($T('Бонусні програми','Бонусные программы','Bonus programs')) ?></div>
          <div class="text-muted"><?= h($T('В процесі розробки','В процессе разработки','In development')) ?></div>
        </div>
      </div>
    </div>
  </section>

  <aside>
    <div class="sidebar-sticky">
      <?php
        $rightBlock = __DIR__ . '/../blocks/groups.php';
        if (is_file($rightBlock)) {
            require $rightBlock;
        }

        $gamesBlock = __DIR__ . '/../blocks/games.php';
        if (is_file($gamesBlock)) {
            echo '<div class="mt-3">';
            require $gamesBlock;
            echo '</div>';
        }
      ?>
    </div>
  </aside>
</div>

<script>
(() => {
  if (window.__vmCoinsPageLiveInit) return;
  window.__vmCoinsPageLiveInit = true;

  const endpoint = '/profile/coins_live.php';
  let inflight = false;

  const updateNodes = (selector, value) => {
    document.querySelectorAll(selector).forEach((el) => {
      const n = Number(value);
      el.textContent = Number.isFinite(n) ? String(Math.trunc(n)) : '0';
    });
  };

  const fetchState = async () => {
    if (inflight) return;
    if (document.hidden) return;

    inflight = true;
    try {
      const res = await fetch(endpoint + '?_=' + Date.now(), {
        method: 'GET',
        credentials: 'same-origin',
        headers: {
          'Accept': 'application/json',
          'X-Requested-With': 'XMLHttpRequest'
        },
        cache: 'no-store'
      });

      if (!res.ok) return;
      const data = await res.json();
      if (!data || !data.ok) return;

      if (Object.prototype.hasOwnProperty.call(data, 'balance')) {
        updateNodes('[data-vmc-balance]', data.balance);
      }
      if (Object.prototype.hasOwnProperty.call(data, 'earned_total')) {
        updateNodes('[data-vmc-earned]', data.earned_total);
      }
      if (Object.prototype.hasOwnProperty.call(data, 'spent_total')) {
        updateNodes('[data-vmc-spent]', data.spent_total);
      }
    } catch (e) {
      // silent
    } finally {
      inflight = false;
    }
  };

  window.setTimeout(fetchState, 1200);
  window.setInterval(fetchState, 5000);

  document.addEventListener('visibilitychange', () => {
    if (!document.hidden) {
      fetchState();
    }
  });

  window.addEventListener('focus', fetchState);
})();
</script>

<?php require __DIR__ . '/../includes/footer.php'; ?>