<?php
declare(strict_types=1);

/**
 * /functional/group/view.php
 * Перегляд групи
 */

require_once __DIR__ . '/../../includes/start.php';
require_once __DIR__ . '/_lib.php';
require_once __DIR__ . '/_view_helpers.php';

$pdo = g_db();
$me  = g_me();

$hasGroups = g_table_exists($pdo, 'groups') && g_table_exists($pdo, 'group_members');

if (!$hasGroups) {
    http_response_code(500);
    echo "DB schema missing: groups/group_members. Run migration.";
    exit;
}

$id   = (int)($_GET['id'] ?? 0);
$slug = trim((string)($_GET['g'] ?? ''));

$g = null;
if ($slug !== '') $g = g_group_get_by_slug($pdo, $slug);
if (!$g && $id > 0) $g = g_group_get($pdo, $id);

if (!$g) {
    http_response_code(404);
    echo "Group not found";
    exit;
}

/* ===== canonical slug from DB ===== */
$dbSlug = '';
if (is_array($g) && array_key_exists('slug', $g)) {
    $dbSlug = trim((string)($g['slug'] ?? ''));
}

if ($dbSlug !== '') {
    $needRedirect = false;

    if ($id > 0) $needRedirect = true;
    if ($slug !== '' && $slug !== $dbSlug) $needRedirect = true;

    if ($needRedirect && (string)($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'GET') {
        $langQ = trim((string)($_GET['lang'] ?? ''));
        $url = '/functional/group/view.php?g=' . rawurlencode($dbSlug);
        if ($langQ !== '') $url .= '&lang=' . rawurlencode($langQ);

        header('Location: ' . $url, true, 301);
        exit;
    }
}

/* ===== schema flags ===== */
$g_has_topic        = g_column_exists($pdo, 'groups', 'topic');
$g_has_about        = g_column_exists($pdo, 'groups', 'about');
$hasIsClosed        = g_column_exists($pdo, 'groups', 'is_closed');
$gm_has_status      = g_column_exists($pdo, 'group_members', 'status');
$gm_has_pendingKind = g_column_exists($pdo, 'group_members', 'pending_kind');

/* ===== perms/membership ===== */
$isManager = g_can_manage_group($me, $g);
$canViewMembers = function_exists('g_can_view_members') ? g_can_view_members($me, $g) : $isManager;
$canManageMembers = function_exists('g_can_manage_members') ? g_can_manage_members($me, $g) : $isManager;

$membership = null;
if ($me) $membership = g_membership($pdo, (int)$g['id'], (int)$me['id']);

$membershipStatus = '';
if ($membership && $gm_has_status) {
    $membershipStatus = (string)($membership['status'] ?? '');
}

$membershipPendingKind = '';
if ($membership && $gm_has_pendingKind) {
    $membershipPendingKind = trim((string)($membership['pending_kind'] ?? ''));
}

$isMember = false;
if ($membership) {
    $isMember = $gm_has_status ? ($membershipStatus === 'active') : true;
}

$isPendingInvite = false;
$isPendingRequest = false;

if ($membership && $gm_has_status && $membershipStatus === 'pending') {
    if (!$gm_has_pendingKind || $membershipPendingKind === '' || $membershipPendingKind === 'invite') {
        $isPendingInvite = true;
    } elseif ($membershipPendingKind === 'request') {
        $isPendingRequest = true;
    }
}

$isBannedMember  = ($membership && $gm_has_status && $membershipStatus === 'banned');
$viewerIsAdmin   = $me ? (function_exists('g_is_admin') ? (bool)g_is_admin($me) : false) : false;

/* group closed state */
$isClosed = false;
if ($hasIsClosed) {
    $isClosed = ((int)($g['is_closed'] ?? 0) === 1);
}

/* ===== comment permission ===== */
$canComment = (bool)$me && !$isPendingInvite && !$isPendingRequest && !$isBannedMember && ($isManager || $isMember);

/* ===== members count ===== */
$membersCount = 0;
try {
    if ($gm_has_status) {
        $stC = $pdo->prepare("SELECT COUNT(*) FROM group_members WHERE group_id=? AND status='active'");
        $stC->execute([(int)$g['id']]);
        $membersCount = (int)$stC->fetchColumn();
    } else {
        $stC = $pdo->prepare("SELECT COUNT(*) FROM group_members WHERE group_id=?");
        $stC->execute([(int)$g['id']]);
        $membersCount = (int)$stC->fetchColumn();
    }
} catch (Throwable $e) {
    $membersCount = (int)($g['members_count'] ?? 0);
}

/* ===== group avatar/cover ===== */
$groupAvatar = trim((string)($g['avatar_path'] ?? ''));
$groupCover  = trim((string)($g['cover_path'] ?? ''));
$groupIni    = vm_first_char((string)($g['name'] ?? ''));

/* ===== SEO ===== */
$title = (string)($g['name'] ?? '');

$topic = $g_has_topic ? trim((string)($g['topic'] ?? '')) : '';
$about = $g_has_about ? trim((string)($g['about'] ?? '')) : '';

if ($about !== '') {
    $desc = vm_norm_spaces($about);
    $meta_desc = vm_clip($desc, 180);
} else {
    $meta_desc = g_t(
        'Група у VMEREGI: ' . $title . ($topic !== '' ? ' — ' . $topic : '') . '. Учасників: ' . $membersCount . '.',
        'Группа в VMEREGI: ' . $title . ($topic !== '' ? ' — ' . $topic : '') . '. Участников: ' . $membersCount . '.',
        'VMEREGI group: ' . $title . ($topic !== '' ? ' — ' . $topic : '') . '. Members: ' . $membersCount . '.'
    );
}

if ($dbSlug !== '') {
    $canonical = abs_url('/functional/group/view.php?g=' . rawurlencode($dbSlug));
} elseif ($slug !== '') {
    $canonical = abs_url('/functional/group/view.php?g=' . rawurlencode($slug));
} else {
    $canonical = abs_url('/functional/group/view.php?id=' . (int)$g['id']);
}

$og_image = $groupCover !== '' ? abs_url($groupCover) : ($groupAvatar !== '' ? abs_url($groupAvatar) : '');

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

$injectCss = "  <link rel=\"stylesheet\" href=\"/css/group.css?v=6\">\n";
if (strpos($hdr, '/css/group.css') === false) {
    if (strpos($hdr, '</head>') !== false) {
        $hdr = str_replace('</head>', $injectCss . "</head>", $hdr);
    } else {
        $hdr .= "\n" . $injectCss . "\n";
    }
}
echo $hdr;

/* ===== message ===== */
$backUri     = g_group_url($g);
$m = trim((string)($_GET['m'] ?? ''));
$alert = null;

if ($m === 'closed') {
    $alert = ['type' => 'warning', 'msg' => g_t(
        'Група закрита. Для вступу треба подати заявку.',
        'Группа закрыта. Для вступления нужно подать заявку.',
        'Group is closed. You need to send a join request.'
    )];
} elseif ($m === 'owner_cant_leave') {
    $alert = ['type' => 'warning', 'msg' => g_t(
        'Власник не може вийти з групи.',
        'Владелец не может выйти из группы.',
        'Owner cannot leave the group.'
    )];
} elseif ($m === 'csrf') {
    $alert = ['type' => 'danger', 'msg' => g_t(
        'Помилка безпеки (CSRF).',
        'Ошибка безопасности (CSRF).',
        'Security error (CSRF).'
    )];
} elseif ($m === 'banned') {
    $alert = ['type' => 'danger', 'msg' => g_t(
        'Ви заблоковані у цій групі.',
        'Вы заблокированы в этой группе.',
        'You are banned in this group.'
    )];
} elseif ($m === 'invite_sent') {
    $alert = ['type' => 'info', 'msg' => g_t(
        'Запрошення в групу надіслано.',
        'Приглашение в группу отправлено.',
        'Group invite sent.'
    )];
} elseif ($m === 'invite_pending') {
    $alert = ['type' => 'info', 'msg' => g_t(
        'У вас є запрошення в цю групу. Підтвердіть або відхиліть його.',
        'У вас есть приглашение в эту группу. Подтвердите или отклоните его.',
        'You have an invite to this group. Accept or decline it.'
    )];
} elseif ($m === 'request_sent') {
    $alert = ['type' => 'info', 'msg' => g_t(
        'Заявку на вступ надіслано. Тепер адміністратор має її підтвердити.',
        'Заявка на вступление отправлена. Теперь администратор должен её подтвердить.',
        'Your join request has been sent. An admin must approve it now.'
    )];
} elseif ($m === 'joined') {
    $alert = ['type' => 'success', 'msg' => g_t(
        'Ви успішно приєдналися до групи.',
        'Вы успешно присоединились к группе.',
        'You joined the group successfully.'
    )];
} elseif ($m === 'join_error') {
    $alert = ['type' => 'danger', 'msg' => g_t(
        'Не вдалося виконати дію. Спробуйте ще раз.',
        'Не удалось выполнить действие. Попробуйте ещё раз.',
        'Could not complete the action. Please try again.'
    )];
}

/* ===== group links ===== */
$groupLinks = [];
if (
    g_table_exists($pdo, 'group_links')
    && g_column_exists($pdo, 'group_links', 'group_id')
    && g_column_exists($pdo, 'group_links', 'url')
    && g_column_exists($pdo, 'group_links', 'label')
) {
    try {
        $order = g_column_exists($pdo, 'group_links', 'sort_order') ? 'sort_order ASC, id ASC' : 'id ASC';
        $stL = $pdo->prepare("SELECT id, url, label FROM group_links WHERE group_id=? ORDER BY {$order} LIMIT 5");
        $stL->execute([(int)$g['id']]);
        $groupLinks = $stL->fetchAll(PDO::FETCH_ASSOC) ?: [];
    } catch (Throwable $e) {
        $groupLinks = [];
    }
}

/* ===== load group posts ===== */
$posts = [];
$hasPosts = g_table_exists($pdo, 'posts') && g_column_exists($pdo, 'posts', 'group_id');

$postsOrder = 'p.id DESC';
$postsHasCreated = $hasPosts && g_column_exists($pdo, 'posts', 'created_at');
if ($postsHasCreated) $postsOrder = 'p.created_at DESC';

if ($hasPosts) {
    $st = $pdo->prepare("
        SELECT p.*, u.username, u.first_name, u.last_name, u.avatar_path AS user_avatar
        FROM posts p
        JOIN users u ON u.id = p.user_id
        WHERE p.group_id = ?
        ORDER BY {$postsOrder}
        LIMIT 50
    ");
    $st->execute([(int)$g['id']]);
    $posts = $st->fetchAll(PDO::FETCH_ASSOC) ?: [];
}

/* ===== attachments ===== */
$postIds = array_values(array_filter(array_map(fn($p) => (int)($p['id'] ?? 0), $posts), fn($id) => $id > 0));
$attByPost = [];

$hasAttachments = g_table_exists($pdo, 'post_attachments') && g_column_exists($pdo, 'post_attachments', 'post_id');

if ($hasAttachments && $postIds) {
    $in = implode(',', array_fill(0, count($postIds), '?'));
    $stA = $pdo->prepare("SELECT * FROM post_attachments WHERE post_id IN ($in) ORDER BY id ASC");
    $stA->execute($postIds);
    while ($a = $stA->fetch(PDO::FETCH_ASSOC)) {
        $pid = (int)($a['post_id'] ?? 0);
        if ($pid <= 0) continue;
        $attByPost[$pid][] = $a;
    }
}

/* ===== reactions ===== */
$reactCounts = [];
$myReact = [];
$hasReacts = g_table_exists($pdo, 'post_reactions')
    && g_column_exists($pdo, 'post_reactions', 'post_id')
    && g_column_exists($pdo, 'post_reactions', 'user_id')
    && g_column_exists($pdo, 'post_reactions', 'reaction');

if ($hasReacts && $postIds) {
    try {
        $in = implode(',', array_fill(0, count($postIds), '?'));

        $stR = $pdo->prepare("
            SELECT post_id,
                   SUM(reaction='like') AS likes,
                   SUM(reaction='dislike') AS dislikes
            FROM post_reactions
            WHERE post_id IN ($in)
            GROUP BY post_id
        ");
        $stR->execute($postIds);
        while ($r = $stR->fetch(PDO::FETCH_ASSOC)) {
            $pid = (int)($r['post_id'] ?? 0);
            if ($pid <= 0) continue;
            $reactCounts[$pid] = [
                'likes' => (int)($r['likes'] ?? 0),
                'dislikes' => (int)($r['dislikes'] ?? 0),
            ];
        }

        if ($me) {
            $params = $postIds;
            $params[] = (int)($me['id'] ?? 0);

            $stM = $pdo->prepare("
                SELECT post_id, reaction
                FROM post_reactions
                WHERE post_id IN ($in) AND user_id=?
            ");
            $stM->execute($params);
            while ($r = $stM->fetch(PDO::FETCH_ASSOC)) {
                $pid = (int)($r['post_id'] ?? 0);
                $rx  = (string)($r['reaction'] ?? '');
                if ($pid > 0 && ($rx === 'like' || $rx === 'dislike')) {
                    $myReact[$pid] = $rx;
                }
            }
        }
    } catch (Throwable $e) {
        $reactCounts = [];
        $myReact = [];
    }

}

/* ===== comments ===== */
$commentsByPost = [];
$repliesByParent = [];
$commentAttById = [];
$commentIds = [];

$hasComments = g_table_exists($pdo, 'comments')
    && g_column_exists($pdo, 'comments', 'post_id');

if ($hasComments && $postIds) {
    try {
        $in = implode(',', array_fill(0, count($postIds), '?'));

        $commentsOrder = 'c.id ASC';
        if (g_column_exists($pdo, 'comments', 'created_at')) {
            $commentsOrder = 'c.created_at ASC, c.id ASC';
        }

        $stC = $pdo->prepare("
            SELECT
              c.*,
              u.username,
              u.first_name,
              u.last_name,
              u.avatar_path
            FROM comments c
            JOIN users u ON u.id = c.user_id
            WHERE c.post_id IN ($in)
            ORDER BY {$commentsOrder}
        ");
        $stC->execute($postIds);
        $tmpComments = [];
        while ($c = $stC->fetch(PDO::FETCH_ASSOC)) {
            $cid = (int)($c['id'] ?? 0);
            if ($cid <= 0) continue;
            $commentIds[] = $cid;
            $tmpComments[$cid] = $c;
        }

        $commentLikesById = [];
        $commentDislikesById = [];
        $myCommentReactionById = [];

        $hasCommentReacts = g_table_exists($pdo, 'comment_reactions')
            && g_column_exists($pdo, 'comment_reactions', 'comment_id')
            && g_column_exists($pdo, 'comment_reactions', 'user_id')
            && g_column_exists($pdo, 'comment_reactions', 'reaction');

        if ($hasCommentReacts && $commentIds) {
            $commentIds = array_values(array_unique($commentIds));
            $cin = implode(',', array_fill(0, count($commentIds), '?'));

            $stCR = $pdo->prepare("
                SELECT comment_id,
                       SUM(reaction='like') AS likes,
                       SUM(reaction='dislike') AS dislikes
                FROM comment_reactions
                WHERE comment_id IN ($cin)
                GROUP BY comment_id
            ");
            $stCR->execute($commentIds);
            while ($r = $stCR->fetch(PDO::FETCH_ASSOC)) {
                $cid = (int)($r['comment_id'] ?? 0);
                if ($cid <= 0) continue;
                $commentLikesById[$cid] = (int)($r['likes'] ?? 0);
                $commentDislikesById[$cid] = (int)($r['dislikes'] ?? 0);
            }

            if ($me) {
                $params = $commentIds;
                $params[] = (int)($me['id'] ?? 0);

                $stCM = $pdo->prepare("
                    SELECT comment_id, reaction
                    FROM comment_reactions
                    WHERE comment_id IN ($cin) AND user_id=?
                ");
                $stCM->execute($params);
                while ($r = $stCM->fetch(PDO::FETCH_ASSOC)) {
                    $cid = (int)($r['comment_id'] ?? 0);
                    $rx  = (string)($r['reaction'] ?? '');
                    if ($cid > 0 && ($rx === 'like' || $rx === 'dislike')) {
                        $myCommentReactionById[$cid] = $rx;
                    }
                }
            }
        }

        foreach ($tmpComments as $cid => $c) {
            $c['likes'] = (int)($commentLikesById[$cid] ?? 0);
            $c['dislikes'] = (int)($commentDislikesById[$cid] ?? 0);
            $c['my_reaction'] = (string)($myCommentReactionById[$cid] ?? '');

            $pid = (int)($c['post_id'] ?? 0);
            $parentId = (int)($c['parent_id'] ?? 0);

            if ($parentId > 0) {
                $repliesByParent[$parentId][] = $c;
            } else {
                $commentsByPost[$pid][] = $c;
            }
        }

        $hasCommentAtt = g_table_exists($pdo, 'comment_attachments')
            && g_column_exists($pdo, 'comment_attachments', 'comment_id');

        if ($hasCommentAtt && $commentIds) {
            $commentIds = array_values(array_unique($commentIds));
            $cin = implode(',', array_fill(0, count($commentIds), '?'));
            $stCA = $pdo->prepare("SELECT * FROM comment_attachments WHERE comment_id IN ($cin) ORDER BY id ASC");
            $stCA->execute($commentIds);
            while ($a = $stCA->fetch(PDO::FETCH_ASSOC)) {
                $cid = (int)($a['comment_id'] ?? 0);
                if ($cid <= 0) continue;
                $commentAttById[$cid][] = $a;
            }
        }
    } catch (Throwable $e) {
        $commentsByPost = [];
        $repliesByParent = [];
        $commentAttById = [];
    }
}

/* ===== Emoji i18n ===== */
$lang = (string)g_lang();
if (!in_array($lang, ['uk','ru','en'], true)) $lang = 'uk';

$vmEmojiI18n = [
    'searchPh'     => g_t('Пошук емодзі...', 'Поиск эмодзи...', 'Search emoji...'),
    'recentEmpty'  => g_t('Нещодавніх емодзі ще немає', 'Недавних эмодзи ещё нет', 'No recent emoji yet'),
    'tabRecent'    => g_t('Нещодавні', 'Недавние', 'Recent'),
    'tabSmileys'   => g_t('Смайли', 'Смайлы', 'Smileys'),
    'tabGestures'  => g_t('Жести', 'Жесты', 'Gestures'),
    'tabLove'      => g_t('Любов', 'Любовь', 'Love'),
    'tabFood'      => g_t('Їжа', 'Еда', 'Food'),
    'tabObjects'   => g_t('Обʼєкти', 'Объекты', 'Objects'),
];
?>

<style>
.g-head-card{
  display:grid !important;
  grid-template-columns: 170px 1fr;
  grid-template-rows: auto auto;
  column-gap: 18px;
  align-items: start;
}
.g-avatar-wrap{
  grid-column: 1;
  grid-row: 1 / span 2;
}
.g-head-actions{
  grid-column: 2;
  grid-row: 1;
  justify-self: end;
  align-self: start;
  display:flex;
  gap:8px;
  flex-wrap:wrap;
}
.g-head-main{
  grid-column: 2;
  grid-row: 2;
  padding-top: 6px;
}
@media (max-width: 768px){
  .g-head-card{
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto;
  }
  .g-avatar-wrap{
    grid-column: 1;
    grid-row: 1;
    justify-self: start;
  }
  .g-head-actions{
    grid-column: 1;
    grid-row: 2;
    justify-self: start;
  }
  .g-head-main{
    grid-column: 1;
    grid-row: 3;
  }
}
.g-post-authorline{ display:flex; flex-direction:column; line-height:1.1; }
.g-post-subline{ font-size:12px; color:#6c757d; }
.g-post-subline a{ color:inherit; text-decoration:none; }
.g-post-subline a:hover{ text-decoration:underline; }
.g-links{ margin-top:10px; display:flex; flex-wrap:wrap; gap:8px; }
.g-links .btn{ border-radius:999px; }
.lp-card-feed{ border:1px solid rgba(0,0,0,.12); border-radius:14px; overflow:hidden; background:#fff; }
.lp-card-feed .lp-card-inner{ display:flex; gap:12px; text-decoration:none; color:inherit; padding:12px; }
.lp-card-feed .lp-img{ width:110px; height:80px; border-radius:12px; overflow:hidden; flex:0 0 auto; background:#f1f3f5; display:flex; align-items:center; justify-content:center; }
.lp-card-feed .lp-img img{ width:100%; height:100%; object-fit:cover; display:none; }
.lp-card-feed .lp-meta{ min-width:0; }
.lp-card-feed .lp-title{ font-weight:700; line-height:1.2; margin-bottom:4px; }
.lp-card-feed .lp-desc{ color:#495057; font-size:13px; line-height:1.25; max-height:2.5em; overflow:hidden; }
.lp-card-feed .lp-site{ color:#6c757d; font-size:12px; margin-top:6px; }
.g-react-btn{
  display:inline-flex;
  align-items:center;
  gap:6px;
}
.g-react-btn .count{
  min-width: 14px;
  text-align:center;
  font-weight:700;
  line-height:1;
}
.vm-ava-sm {
  width: 34px;
  height: 34px;
  border-radius: 999px;
  overflow: hidden;
  flex: 0 0 auto;
}
.vm-ava-sm img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display:block;
}
.vm-ava-ph {
  width:100%;
  height:100%;
  display:flex;
  align-items:center;
  justify-content:center;
  background:#e9ecef;
  color:#495057;
  font-weight:700;
  border-radius:999px;
  font-size:14px;
}
.vm-menu { position:relative; }
.vm-menu-btn { list-style:none; cursor:pointer; user-select:none; border:0; background:transparent; padding:2px 6px; border-radius:8px; }
.vm-menu-btn::-webkit-details-marker { display:none; }
.vm-menu[open] .vm-menu-box { display:block; }
.vm-menu-box { display:none; position:absolute; right:0; top:24px; min-width:160px; background:#fff; border:1px solid rgba(0,0,0,.12); border-radius:12px; padding:6px; z-index:50; box-shadow:0 8px 24px rgba(0,0,0,.12); }
.vm-menu-item { display:block; width:100%; text-decoration:none; color:#212529; padding:8px 10px; border-radius:10px; }
.vm-menu-item:hover { background:#f1f3f5; }
.vm-menu-danger { color:#dc3545; background:transparent; border:0; text-align:left; }
.comment.is-reply { margin-left: 26px; padding-left: 12px; border-left: 2px solid rgba(0,0,0,.08); }
.comment-body { margin-top: 8px; }
.comment-replies { margin-top: 10px; display: grid; gap: 10px; }
.comment-actions .count { min-width: 14px; text-align:center; font-weight:700; line-height:1; }
.g-comments-wrap { margin-top: 14px; }
</style>

<div class="feed-layout">
    <aside>
        <div class="sidebar-sticky">
            <?php require __DIR__ . '/../../blocks/profile.php'; ?>
        </div>
    </aside>

    <section>
        <div class="container my-4">

            <?php if ($alert): ?>
                <div class="alert alert-<?= g_h($alert['type']) ?>"><?= g_h($alert['msg']) ?></div>
            <?php endif; ?>

            <div class="g-group-header">
                <div class="g-cover">
                    <?php if ($groupCover !== ''): ?>
                        <img src="<?= g_h($groupCover) ?>" alt="">
                    <?php else: ?>
                        <div class="g-cover-ph"></div>
                    <?php endif; ?>
                </div>

                <div class="g-head-card">

                    <div class="g-avatar-wrap">
                        <?php if ($groupAvatar !== ''): ?>
                            <img class="g-avatar" src="<?= g_h($groupAvatar) ?>" alt="">
                        <?php else: ?>
                            <div class="g-avatar g-avatar-ph"><?= g_h($groupIni) ?></div>
                        <?php endif; ?>
                    </div>

                    <div class="g-head-main">
                        <div class="g-head-title"><?= g_h((string)($g['name'] ?? '')) ?></div>
                        <div class="g-head-meta">
                            <?php if ($g_has_topic && !empty($g['topic'])): ?>
                                <span><?= g_h((string)$g['topic']) ?></span>
                                <span class="mx-2">•</span>
                            <?php endif; ?>
                            <span><?= (int)$membersCount ?> <?= g_h(g_t('учасників', 'участников', 'members')) ?></span>

                            <?php if ($hasIsClosed): ?>
                                <span class="mx-2">•</span>
                                <span class="text-muted"><?= g_h($isClosed ? g_t('закрита', 'закрыта', 'closed') : g_t('відкрита', 'открыта', 'open')) ?></span>
                            <?php endif; ?>

                            <?php if ($isPendingInvite): ?>
                                <span class="mx-2">•</span>
                                <span class="text-warning-emphasis"><?= g_h(g_t('є запрошення', 'есть приглашение', 'invite pending')) ?></span>
                            <?php elseif ($isPendingRequest): ?>
                                <span class="mx-2">•</span>
                                <span class="text-warning-emphasis"><?= g_h(g_t('заявка подана', 'заявка отправлена', 'request sent')) ?></span>
                            <?php endif; ?>
                        </div>

                        <?php if ($g_has_about && !empty($g['about'])): ?>
                            <div class="g-head-about"><?= nl2br(g_h((string)$g['about'])) ?></div>
                        <?php endif; ?>

                        <?php if ($groupLinks): ?>
                            <div class="g-links">
                                <?php foreach ($groupLinks as $lnk): ?>
                                    <?php
                                    $u = trim((string)($lnk['url'] ?? ''));
                                    $lab = trim((string)($lnk['label'] ?? ''));
                                    if ($u === '' || !preg_match('~^https?://~i', $u)) continue;
                                    if ($lab === '') $lab = $u;
                                    $lab = vm_clip($lab, 40);
                                    ?>
                                    <a class="btn btn-sm btn-outline-secondary" href="<?= g_h($u) ?>" target="_blank" rel="noopener nofollow ugc">
                                        <?= g_h($lab) ?>
                                    </a>
                                <?php endforeach; ?>
                            </div>
                        <?php endif; ?>
                    </div>

                    <div class="g-head-actions">
                        <?php if ($me): ?>
                            <?php if ($canViewMembers): ?>
                                <a class="btn btn-sm btn-outline-dark" href="/functional/group/members.php?id=<?= (int)$g['id'] ?>">
                                    <?= g_h(g_t('Список учасників', 'Список участников', 'Members list')) ?>
                                </a>
                            <?php endif; ?>

                            <?php if ($isManager): ?>
                                <a class="btn btn-sm btn-outline-primary" href="/functional/group/edit.php?id=<?= (int)$g['id'] ?>"><?= g_h(g_t('Налаштування', 'Настройки', 'Settings')) ?></a>

                                <a class="btn btn-sm btn-outline-success"
                                   href="/users.php?invite_group=<?= (int)$g['id'] ?>&back=<?= urlencode($backUri) ?>">
                                    <?= g_h(g_t('Запросити людей', 'Пригласить людей', 'Invite people')) ?>
                                </a>

                                <?php if ($hasIsClosed): ?>
                                    <form method="post" action="/functional/group/toggle_closed.php" class="d-inline">
                                        <?php g_csrf_field_fallback(); ?>
                                        <input type="hidden" name="id" value="<?= (int)$g['id'] ?>">
                                        <input type="hidden" name="back" value="<?= g_h($backUri) ?>">
                                        <button class="btn btn-sm <?= $isClosed ? 'btn-outline-success' : 'btn-outline-warning' ?>" type="submit">
                                            <?= g_h($isClosed ? g_t('Відкрити групу','Открыть группу','Open group') : g_t('Закрити групу','Закрыть группу','Close group')) ?>
                                        </button>
                                    </form>
                                <?php endif; ?>

                                <a class="btn btn-sm btn-outline-danger" href="/functional/group/delete.php?id=<?= (int)$g['id'] ?>"><?= g_h(g_t('Видалити', 'Удалить', 'Delete')) ?></a>

                            <?php else: ?>
                                <?php if ($isMember): ?>
                                    <form method="post" action="/functional/group/leave.php?id=<?= (int)$g['id'] ?>" class="d-inline">
                                        <input type="hidden" name="csrf" value="<?= g_h(vm_csrf_token()) ?>">
                                        <button class="btn btn-sm btn-outline-secondary" type="submit">
                                            <?= g_h(g_t('Вийти з групи', 'Выйти из группы', 'Leave')) ?>
                                        </button>
                                    </form>
                                <?php elseif ($isPendingInvite): ?>
                                    <form method="post" action="/functional/group/invite_action.php" class="d-inline">
                                        <input type="hidden" name="csrf" value="<?= g_h(vm_csrf_token()) ?>">
                                        <input type="hidden" name="group_id" value="<?= (int)$g['id'] ?>">
                                        <input type="hidden" name="action" value="accept">
                                        <input type="hidden" name="back" value="<?= g_h($backUri) ?>">
                                        <button class="btn btn-sm btn-success" type="submit">
                                            <?= g_h(g_t('Прийняти запрошення', 'Принять приглашение', 'Accept invite')) ?>
                                        </button>
                                    </form>

                                    <form method="post" action="/functional/group/invite_action.php" class="d-inline">
                                        <input type="hidden" name="csrf" value="<?= g_h(vm_csrf_token()) ?>">
                                        <input type="hidden" name="group_id" value="<?= (int)$g['id'] ?>">
                                        <input type="hidden" name="action" value="reject">
                                        <input type="hidden" name="back" value="<?= g_h($backUri) ?>">
                                        <button class="btn btn-sm btn-outline-danger" type="submit">
                                            <?= g_h(g_t('Відхилити', 'Отклонить', 'Decline')) ?>
                                        </button>
                                    </form>
                                <?php elseif ($isPendingRequest): ?>
                                    <button class="btn btn-sm btn-outline-secondary" type="button" disabled>
                                        <?= g_h(g_t('Заявка подана', 'Заявка отправлена', 'Request sent')) ?>
                                    </button>
                                <?php elseif ($isBannedMember): ?>
                                    <button class="btn btn-sm btn-danger" type="button" disabled><?= g_h(g_t('Вас заблоковано', 'Вы заблокированы', 'You are banned')) ?></button>
                                <?php else: ?>
                                    <form method="post" action="/functional/group/join.php?id=<?= (int)$g['id'] ?>" class="d-inline">
                                        <input type="hidden" name="csrf" value="<?= g_h(vm_csrf_token()) ?>">
                                        <button class="btn btn-sm btn-primary" type="submit">
                                            <?= g_h($isClosed ? g_t('Подати заявку', 'Подать заявку', 'Send request') : g_t('Вступити', 'Вступить', 'Join')) ?>
                                        </button>
                                    </form>
                                <?php endif; ?>
                            <?php endif; ?>
                        <?php else: ?>
                            <a class="btn btn-sm btn-primary" href="/login.php"><?= g_h(g_t('Увійти', 'Войти', 'Log in')) ?></a>
                        <?php endif; ?>
                    </div>
                </div>
            </div>

            <div class="card mb-3">
                <div class="card-body">
                    <?php if (!$me): ?>
                        <div class="text-muted"><?= g_h(g_t('Щоб писати пости — увійди.', 'Чтобы писать посты — войди.', 'Log in to create posts.')) ?></div>
                    <?php elseif ($isPendingInvite): ?>
                        <div class="text-muted"><?= g_h(g_t(
                            'У вас є запрошення в цю групу. Спочатку прийміть його, щоб публікувати пости.',
                            'У вас есть приглашение в эту группу. Сначала примите его, чтобы публиковать посты.',
                            'You have an invite to this group. Accept it first to create posts.'
                        )) ?></div>
                    <?php elseif ($isPendingRequest): ?>
                        <div class="text-muted"><?= g_h(g_t(
                            'Ваша заявка на вступ очікує підтвердження адміністратора.',
                            'Ваша заявка на вступление ожидает подтверждения администратора.',
                            'Your join request is waiting for admin approval.'
                        )) ?></div>
                    <?php elseif (!$isMember && !$isManager): ?>
                        <?php if ($isClosed): ?>
                            <div class="text-muted"><?= g_h(g_t('Це закрита група. Подайте заявку, щоб стати учасником.', 'Это закрытая группа. Подайте заявку, чтобы стать участником.', 'This is a closed group. Send a request to join.')) ?></div>
                        <?php else: ?>
                            <div class="text-muted"><?= g_h(g_t('Щоб писати пости в цій групі — вступи.', 'Чтобы писать посты в этой группе — вступи.', 'Join the group to post.')) ?></div>
                        <?php endif; ?>
                    <?php else: ?>
                        <?php
                        $postAction = '/functional/group/post_create.php';
                        $postGroupId = (int)$g['id'];
                        $postBack = $backUri;
                        $postFormId = 'vmGroupCreatePost_' . (int)$g['id'];
                        $postTextareaName = 'body';
                        $postSubmitLabel = g_t('Опублікувати', 'Опубликовать', 'Publish');
                        $postPlaceholder = g_t('Що у вас нового?', 'Что у вас нового?', "What's new?");
                        $postPollEnabled = true;
                        $postAllowFiles = true;
                        $postMaxFilesLabel = g_t('Можна вибрати кілька файлів', 'Можно выбрать несколько файлов', 'You can select multiple files');
                        $postAccept = 'image/*,audio/*,video/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.zip,.rar,.7z,.webp';
                        $postEmojiLabel = 'Emoji';
                        $postPollLabel = g_t('Опитування', 'Опрос', 'Poll');
                        $postFilesLabel = g_t('Файли', 'Файлы', 'Files');
                        $postNoFileLabel = g_t('Файл не вибрано', 'Файл не выбран', 'No file selected');
                        $postManyFilesTpl = g_t('Обрано файлів: %d', 'Выбрано файлов: %d', 'Selected files: %d');
                        $postPollQuestionPlaceholder = g_t('Питання опитування', 'Вопрос опроса', 'Poll question');
                        $postPollOption1Placeholder = g_t('Варіант 1', 'Вариант 1', 'Option 1');
                        $postPollOption2Placeholder = g_t('Варіант 2', 'Вариант 2', 'Option 2');
                        $postPollOption3Placeholder = g_t('Варіант 3', 'Вариант 3', 'Option 3');
                        $postPollOption4Placeholder = g_t('Варіант 4', 'Вариант 4', 'Option 4');

                        require __DIR__ . '/../../blocks/create_post.php';
                        ?>
                    <?php endif; ?>
                </div>
            </div>

            <?php if (!$hasPosts): ?>
                <div class="alert alert-warning">
                    <?= g_h(g_t(
                        'Пости для груп ще не підключені (потрібно posts.group_id).',
                        'Посты для групп ещё не подключены (нужно posts.group_id).',
                        'Group posts are not enabled yet (need posts.group_id).'
                    )) ?>
                </div>
            <?php elseif (!$posts): ?>
                <div class="text-muted"><?= g_h(g_t('Поки що немає постів.', 'Пока что нет постов.', 'No posts yet.')) ?></div>
            <?php else: ?>
                <?php foreach ($posts as $p): ?>
                    <?php require __DIR__ . '/_post_card.php'; ?>
                <?php endforeach; ?>
            <?php endif; ?>
        </div>
    </section>

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

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

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

  const IS_LOGGED = <?= $me ? 'true' : 'false' ?>;
  const CSRF = <?= json_encode(vm_csrf_token(), JSON_UNESCAPED_UNICODE) ?>;
  const REACT_I18N = <?= json_encode([
    'likes' => g_t('Лайків', 'Лайков', 'Likes'),
    'dislikes' => g_t('Дизлайків', 'Дизлайков', 'Dislikes'),
  ], JSON_UNESCAPED_UNICODE) ?>;

  async function hydratePreview(el){
    const url = el.getAttribute('data-lp-url');
    if (!url) return;

    const a = el.querySelector('a.lp-card-inner');
    const img = el.querySelector('img');
    const title = el.querySelector('.lp-title');
    const desc = el.querySelector('.lp-desc');
    const site = el.querySelector('.lp-site');

    try{
      const res = await fetch('/link_preview.php?url=' + encodeURIComponent(url), {
        headers:{'Accept':'application/json'},
        credentials:'same-origin',
        cache:'no-store'
      });
      const data = await res.json();
      if (!data || !data.ok) return;

      if (a) a.href = data.url || url;
      if (title) title.textContent = (data.title || data.url || url).trim();

      if (desc) {
        const d = (data.description || '').trim();
        if (d) { desc.style.display = ''; desc.textContent = d; } else { desc.style.display = 'none'; }
      }
      if (site) {
        const s = (data.site_name || '').trim();
        if (s) { site.style.display = ''; site.textContent = s; } else { site.style.display = 'none'; }
      }

      if (img) {
        const im = (data.image || '').trim();
        if (im) {
          img.src = im;
          img.style.display = 'block';
        } else {
          img.style.display = 'none';
        }
      }
    }catch(e){}
  }

  async function parseJsonSafe(res){
    try {
      return await res.json();
    } catch (e) {
      return null;
    }
  }

  function setBusy(form, busy){
    form.dataset.busy = busy ? '1' : '0';
    const btns = form.querySelectorAll('button');
    btns.forEach((b) => { b.disabled = !!busy; });
  }

  async function submitPostReaction(form){
    if (!form || form.dataset.busy === '1') return;

    const postId = String(form.querySelector('input[name="post_id"]')?.value || '').trim();
    const reaction = String(form.querySelector('input[name="reaction"]')?.value || '').trim();
    if (!postId || !reaction) return;

    setBusy(form, true);

    try {
      const body = new URLSearchParams();
      body.set('csrf', CSRF);
      body.set('post_id', postId);
      body.set('reaction', reaction);
      body.set('back', location.pathname + location.search + '#post-' + postId);

      const res = await fetch('/post_react.php', {
        method: 'POST',
        credentials: 'same-origin',
        cache: 'no-store',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
          'X-Requested-With': 'XMLHttpRequest',
          'Accept': 'application/json'
        },
        body
      });

      const data = await parseJsonSafe(res);
      if (!res.ok || !data || !data.ok) {
        location.reload();
        return;
      }

      const wrap = document.getElementById('post-' + postId);
      const likesEl = document.getElementById('likes-' + postId);
      const dislikesEl = document.getElementById('dislikes-' + postId);

      if (likesEl) likesEl.textContent = String(data.likes ?? 0);
      if (dislikesEl) dislikesEl.textContent = String(data.dislikes ?? 0);

      if (wrap) {
        const likeBtn = wrap.querySelector('button[data-react="like"]');
        const disBtn  = wrap.querySelector('button[data-react="dislike"]');

        if (likeBtn) {
          likeBtn.classList.remove('btn-outline-success', 'btn-success');
          likeBtn.classList.add(data.my === 'like' ? 'btn-success' : 'btn-outline-success');
          likeBtn.title = (REACT_I18N.likes || 'Likes') + ': ' + String(data.likes ?? 0);
        }

        if (disBtn) {
          disBtn.classList.remove('btn-outline-danger', 'btn-danger');
          disBtn.classList.add(data.my === 'dislike' ? 'btn-danger' : 'btn-outline-danger');
          disBtn.title = (REACT_I18N.dislikes || 'Dislikes') + ': ' + String(data.dislikes ?? 0);
        }
      }

      window.setTimeout(() => {
        window.dispatchEvent(new CustomEvent('vmcoins:refresh'));
      }, 120);
    } catch (err) {
      location.reload();
    } finally {
      setBusy(form, false);
    }
  }

  async function submitCommentReaction(form){
    if (!form || form.dataset.busy === '1') return;

    const commentId = String(form.querySelector('input[name="comment_id"]')?.value || '').trim();
    const reaction = String(form.querySelector('input[name="reaction"]')?.value || '').trim();
    if (!commentId || !reaction) return;

    setBusy(form, true);

    try {
      const body = new URLSearchParams();
      body.set('csrf', CSRF);
      body.set('comment_id', commentId);
      body.set('reaction', reaction);
      body.set('back', location.pathname + location.search + '#comment-' + commentId);

      const res = await fetch('/comment_react.php', {
        method: 'POST',
        credentials: 'same-origin',
        cache: 'no-store',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
          'X-Requested-With': 'XMLHttpRequest',
          'Accept': 'application/json'
        },
        body
      });

      const data = await parseJsonSafe(res);
      if (!res.ok || !data || !data.ok) {
        location.reload();
        return;
      }

      const likesEl = document.getElementById('clikes-' + commentId);
      const dislikesEl = document.getElementById('cdislikes-' + commentId);

      if (likesEl) likesEl.textContent = String(data.likes ?? 0);
      if (dislikesEl) dislikesEl.textContent = String(data.dislikes ?? 0);

      const root = document.getElementById('comment-' + commentId);
      if (root) {
        const likeBtn = root.querySelector('button[data-cmtreact="like"]');
        const disBtn  = root.querySelector('button[data-cmtreact="dislike"]');

        if (likeBtn) {
          likeBtn.classList.remove('btn-outline-success', 'btn-success');
          likeBtn.classList.add(data.my === 'like' ? 'btn-success' : 'btn-outline-success');
          likeBtn.title = (REACT_I18N.likes || 'Likes') + ': ' + String(data.likes ?? 0);
        }

        if (disBtn) {
          disBtn.classList.remove('btn-outline-danger', 'btn-danger');
          disBtn.classList.add(data.my === 'dislike' ? 'btn-danger' : 'btn-outline-danger');
          disBtn.title = (REACT_I18N.dislikes || 'Dislikes') + ': ' + String(data.dislikes ?? 0);
        }
      }

      window.setTimeout(() => {
        window.dispatchEvent(new CustomEvent('vmcoins:refresh'));
      }, 120);
    } catch (err) {
      location.reload();
    } finally {
      setBusy(form, false);
    }
  }

  document.querySelectorAll('.lp-card-feed[data-lp-url]').forEach(hydratePreview);

  document.addEventListener('submit', (e) => {
    if (!IS_LOGGED) return;

    const form = e.target;
    if (!(form instanceof HTMLFormElement)) return;

    if (form.matches('form.js-post-react-form')) {
      e.preventDefault();
      e.stopPropagation();
      if (typeof e.stopImmediatePropagation === 'function') e.stopImmediatePropagation();
      submitPostReaction(form);
      return;
    }

    if (form.matches('form.js-comment-react-form')) {
      e.preventDefault();
      e.stopPropagation();
      if (typeof e.stopImmediatePropagation === 'function') e.stopImmediatePropagation();
      submitCommentReaction(form);
      return;
    }
  }, true);

  document.addEventListener('click', (e) => {
    const openBtn = e.target.closest('[data-reply-toggle]');
    if (openBtn) {
      const id = openBtn.getAttribute('data-reply-toggle');
      const box = document.getElementById('reply-form-' + id);
      if (box) box.classList.toggle('d-none');
      if (window.VMEmojiInit) window.VMEmojiInit();
      return;
    }

    const cancelBtn = e.target.closest('[data-reply-cancel]');
    if (cancelBtn) {
      const id = cancelBtn.getAttribute('data-reply-cancel');
      const box = document.getElementById('reply-form-' + id);
      if (box) box.classList.add('d-none');
    }
  });

  if (window.VMEmojiInit) window.VMEmojiInit();
})();
</script>

<?php
require __DIR__ . '/../../includes/emoji_picker.php';
require __DIR__ . '/../../includes/lightbox.php';
require __DIR__ . '/../../includes/footer.php';