<?php
declare(strict_types=1);

/**
 * /functional/group/delete.php
 *
 * Видалення групи (owner/admin).
 *
 * Відповідає за:
 * - SEO: noindex + no-store
 * - можна відкривати ?id= або ?g=slug
 * - підтвердження назвою групи (anti-mistake)
 * - перевірку прав: власник групи / admin групи / site admin
 * - видалення ВСІХ постів групи без сиріт у /upload
 * - видалення avatar/cover групи
 * - cleanup папки /upload/group/<slug>/ після commit
 *
 * Важливо:
 * - пости групи не видаляються "в лоб" без збору шляхів файлів
 * - спочатку збираємо шляхи, потім транзакція, потім commit,
 *   і лише після commit фізично чистимо файли/папки
 */

require_once dirname(__DIR__, 2) . '/includes/start.php';
require_once dirname(__DIR__, 2) . '/functional/post/manage.php';

header('X-Robots-Tag: noindex, nofollow, noarchive', true);
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');

require_login();

if (!isset($pdo) || !($pdo instanceof PDO)) {
    $pdo = db();
}
if (!isset($me) || !is_array($me)) {
    $me = current_user();
}

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

if (!function_exists('gd_redirect')) {
    function gd_redirect(string $to): never
    {
        header('Location: ' . $to);
        exit;
    }
}

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

if (!function_exists('gd_flash_get')) {
    function gd_flash_get(string $key): ?string
    {
        if (!isset($_SESSION['flash'][$key])) return null;
        $msg = (string)$_SESSION['flash'][$key];
        unset($_SESSION['flash'][$key]);
        return $msg;
    }
}

if (!function_exists('gd_is_post')) {
    function gd_is_post(): bool
    {
        return strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET')) === 'POST';
    }
}

if (!function_exists('gd_safe_back_url')) {
    function gd_safe_back_url(string $raw): string
    {
        $raw = trim($raw);
        if ($raw === '') return '/group.php';

        if (preg_match('~^https?://~i', $raw)) {
            $p = parse_url($raw);
            $path  = (string)($p['path'] ?? '/group.php');
            $query = isset($p['query']) && $p['query'] !== '' ? ('?' . $p['query']) : '';
            $raw   = $path . $query;
        }

        if ($raw === '' || $raw[0] !== '/') return '/group.php';
        if (str_starts_with($raw, '//')) return '/group.php';
        if (strpos($raw, "\0") !== false) return '/group.php';

        return $raw;
    }
}

if (!function_exists('gd_table_exists')) {
    function gd_table_exists(PDO $pdo, string $table): bool
    {
        if (!preg_match('/^[a-zA-Z0-9_]+$/', $table)) return false;

        $st = $pdo->prepare('SHOW TABLES LIKE ?');
        $st->execute([$table]);

        return (bool)$st->fetchColumn();
    }
}

if (!function_exists('gd_has_column')) {
    function gd_has_column(PDO $pdo, string $table, string $column): bool
    {
        if (!gd_table_exists($pdo, $table)) return false;
        if (!preg_match('/^[a-zA-Z0-9_]+$/', $table)) return false;
        if (!preg_match('/^[a-zA-Z0-9_]+$/', $column)) return false;

        $st = $pdo->prepare("SHOW COLUMNS FROM `{$table}` LIKE ?");
        $st->execute([$column]);

        return (bool)$st->fetch(PDO::FETCH_ASSOC);
    }
}

if (!function_exists('gd_upload_root')) {
    function gd_upload_root(): string
    {
        return dirname(__DIR__, 2);
    }
}

if (!function_exists('gd_unlink_upload_webpath')) {
    function gd_unlink_upload_webpath(string $webPath): void
    {
        $webPath = trim($webPath);
        if ($webPath === '') return;

        if ($webPath[0] !== '/') {
            $webPath = '/' . $webPath;
        }

        if (!str_starts_with($webPath, '/upload/')) return;
        if (str_contains($webPath, '..')) return;

        $abs = gd_upload_root() . $webPath;
        $uploadRoot = realpath(gd_upload_root() . '/upload');
        $realDir = realpath(dirname($abs));

        if ($uploadRoot === false || $realDir === false) return;
        if (!str_starts_with($realDir, $uploadRoot)) return;

        if (is_file($abs)) {
            @unlink($abs);
        }
    }
}

if (!function_exists('gd_safe_remove_dir_recursive')) {
    function gd_safe_remove_dir_recursive(string $absDir): void
    {
        $absDir = rtrim($absDir, '/\\');
        if ($absDir === '') return;
        if (!is_dir($absDir)) return;

        $uploadGroupRoot = realpath(gd_upload_root() . '/upload/group');
        $real = realpath($absDir);

        if ($uploadGroupRoot === false || $real === false) return;
        if (!str_starts_with($real, $uploadGroupRoot)) return;
        if ($real === $uploadGroupRoot) return;

        $items = scandir($real);
        if ($items === false) return;

        foreach ($items as $item) {
            if ($item === '.' || $item === '..') continue;

            $path = $real . DIRECTORY_SEPARATOR . $item;

            if (is_dir($path) && !is_link($path)) {
                gd_safe_remove_dir_recursive($path);
            } else {
                @unlink($path);
            }
        }

        @rmdir($real);
    }
}

if (!function_exists('gd_group_row')) {
    function gd_group_row(PDO $pdo, int $groupId = 0, string $slug = ''): ?array
    {
        if ($groupId > 0) {
            $st = $pdo->prepare('SELECT * FROM groups WHERE id = ? LIMIT 1');
            $st->execute([$groupId]);
            $row = $st->fetch(PDO::FETCH_ASSOC);
            return $row ?: null;
        }

        $slug = trim($slug);
        if ($slug !== '') {
            $st = $pdo->prepare('SELECT * FROM groups WHERE slug = ? LIMIT 1');
            $st->execute([$slug]);
            $row = $st->fetch(PDO::FETCH_ASSOC);
            return $row ?: null;
        }

        return null;
    }
}

if (!function_exists('gd_is_group_manager')) {
    function gd_is_group_manager(PDO $pdo, int $groupId, int $userId): bool
    {
        if ($groupId <= 0 || $userId <= 0 || !gd_table_exists($pdo, 'group_members')) {
            return false;
        }

        $st = $pdo->prepare("
            SELECT 1
            FROM group_members
            WHERE group_id = ?
              AND user_id = ?
              AND status = 'active'
              AND role IN ('owner','admin')
            LIMIT 1
        ");
        $st->execute([$groupId, $userId]);

        return (bool)$st->fetchColumn();
    }
}

if (!function_exists('gd_user_can_delete_group')) {
    function gd_user_can_delete_group(PDO $pdo, array $me, array $group): bool
    {
        $uid  = (int)($me['id'] ?? 0);
        $role = (string)($me['role'] ?? '');

        if ($uid <= 0) return false;
        if ($role === 'admin') return true;
        if ((int)($group['owner_user_id'] ?? 0) === $uid) return true;

        return gd_is_group_manager($pdo, (int)($group['id'] ?? 0), $uid);
    }
}

if (!function_exists('gd_group_post_ids')) {
    function gd_group_post_ids(PDO $pdo, int $groupId): array
    {
        $st = $pdo->prepare('SELECT id FROM posts WHERE group_id = ? ORDER BY id ASC');
        $st->execute([$groupId]);

        return array_map('intval', $st->fetchAll(PDO::FETCH_COLUMN) ?: []);
    }
}

if (!function_exists('gd_post_attachment_paths')) {
    function gd_post_attachment_paths(PDO $pdo, int $postId): array
    {
        if (function_exists('pm_post_attachment_paths')) {
            return pm_post_attachment_paths($pdo, $postId);
        }

        if (!gd_table_exists($pdo, 'post_attachments')) return [];

        $pathCol = gd_has_column($pdo, 'post_attachments', 'path') ? 'path' : (gd_has_column($pdo, 'post_attachments', 'rel_path') ? 'rel_path' : '');
        if ($pathCol === '') return [];

        $st = $pdo->prepare("SELECT `{$pathCol}` FROM post_attachments WHERE post_id = ?");
        $st->execute([$postId]);

        $rows = $st->fetchAll(PDO::FETCH_COLUMN) ?: [];
        $out = [];
        foreach ($rows as $p) {
            $p = (string)$p;
            if ($p !== '') $out[] = $p;
        }
        return array_values(array_unique($out));
    }
}

if (!function_exists('gd_comment_attachment_paths_for_post')) {
    function gd_comment_attachment_paths_for_post(PDO $pdo, int $postId): array
    {
        if (function_exists('pm_comment_attachment_paths_for_post')) {
            return pm_comment_attachment_paths_for_post($pdo, $postId);
        }

        if (!gd_table_exists($pdo, 'comments') || !gd_table_exists($pdo, 'comment_attachments')) {
            return [];
        }

        $pathCol = gd_has_column($pdo, 'comment_attachments', 'path') ? 'path' : (gd_has_column($pdo, 'comment_attachments', 'rel_path') ? 'rel_path' : '');
        if ($pathCol === '') return [];

        $sql = "
            SELECT ca.`{$pathCol}` AS path_value
            FROM comment_attachments ca
            INNER JOIN comments c ON c.id = ca.comment_id
            WHERE c.post_id = ?
        ";
        $st = $pdo->prepare($sql);
        $st->execute([$postId]);

        $rows = $st->fetchAll(PDO::FETCH_ASSOC) ?: [];
        $out = [];

        foreach ($rows as $row) {
            $p = (string)($row['path_value'] ?? '');
            if ($p !== '') $out[] = $p;
        }

        return array_values(array_unique($out));
    }
}

if (!function_exists('gd_collect_group_cleanup_paths')) {
    function gd_collect_group_cleanup_paths(PDO $pdo, array $group, array $postIds): array
    {
        $paths = [];

        $avatar = (string)($group['avatar_path'] ?? '');
        $cover  = (string)($group['cover_path'] ?? '');

        if ($avatar !== '') $paths[] = $avatar;
        if ($cover !== '')  $paths[] = $cover;

        foreach ($postIds as $postId) {
            foreach (gd_post_attachment_paths($pdo, (int)$postId) as $p) {
                $paths[] = $p;
            }
            foreach (gd_comment_attachment_paths_for_post($pdo, (int)$postId) as $p) {
                $paths[] = $p;
            }
        }

        $paths = array_values(array_unique(array_filter(array_map('trim', $paths), static fn($v) => $v !== '')));
        return $paths;
    }
}

if (!function_exists('gd_delete_group_core')) {
    function gd_delete_group_core(PDO $pdo, array $group): void
    {
        $groupId = (int)($group['id'] ?? 0);
        if ($groupId <= 0) {
            throw new RuntimeException('Group not found.');
        }

        $slug = trim((string)($group['slug'] ?? ''));
        $postIds = gd_group_post_ids($pdo, $groupId);
        $pathsToDeleteAfterCommit = gd_collect_group_cleanup_paths($pdo, $group, $postIds);

        try {
            if (!$pdo->inTransaction()) {
                $pdo->beginTransaction();
            }

            if ($postIds && gd_has_column($pdo, 'posts', 'repost_post_id')) {
                $in = implode(',', array_fill(0, count($postIds), '?'));
                $sql = "UPDATE posts SET repost_post_id = NULL WHERE repost_post_id IN ({$in})";
                $st = $pdo->prepare($sql);
                $st->execute($postIds);
            }

            if ($postIds) {
                $in = implode(',', array_fill(0, count($postIds), '?'));
                $sql = "DELETE FROM posts WHERE id IN ({$in})";
                $st = $pdo->prepare($sql);
                $st->execute($postIds);
            }

            $stGroup = $pdo->prepare('DELETE FROM groups WHERE id = ? LIMIT 1');
            $stGroup->execute([$groupId]);

            $pdo->commit();

            foreach ($pathsToDeleteAfterCommit as $path) {
                gd_unlink_upload_webpath($path);
            }

            if ($slug !== '') {
                gd_safe_remove_dir_recursive(gd_upload_root() . '/upload/group/' . $slug);
            }
        } catch (Throwable $e) {
            if ($pdo->inTransaction()) {
                $pdo->rollBack();
            }
            throw $e;
        }
    }
}

if (!function_exists('gd_t')) {
    function gd_t(string $key, string $fallback): string
    {
        if (function_exists('t')) {
            $translated = (string)t($key);
            if ($translated !== '' && $translated !== $key) {
                return $translated;
            }
        }
        return $fallback;
    }
}

$groupId = (int)($_GET['id'] ?? $_POST['id'] ?? 0);
$slug    = trim((string)($_GET['g'] ?? $_POST['g'] ?? ''));
$group   = gd_group_row($pdo, $groupId, $slug);

if (!$group) {
    http_response_code(404);
    echo 'Group not found.';
    exit;
}

if (!gd_user_can_delete_group($pdo, $me, $group)) {
    http_response_code(403);
    echo 'Access denied.';
    exit;
}

$defaultBack = ($me['role'] ?? '') === 'admin' ? '/admin/groups.php' : '/functional/group/view.php?g=' . rawurlencode((string)$group['slug']);
$back = gd_safe_back_url((string)($_POST['back'] ?? $_GET['back'] ?? ($_SERVER['HTTP_REFERER'] ?? $defaultBack)));

if (gd_is_post()) {
    $csrf = (string)($_POST['csrf'] ?? $_POST['csrf_token'] ?? '');
    if (!function_exists('csrf_check') || !csrf_check($csrf)) {
        gd_flash_set('err', 'Bad CSRF token.');
        gd_redirect($back);
    }

    $confirmName = trim((string)($_POST['confirm_name'] ?? ''));
    $realName    = trim((string)($group['name'] ?? ''));

    if ($confirmName === '' || $confirmName !== $realName) {
        gd_flash_set('err', 'Назва групи введена невірно.');
        gd_redirect('/functional/group/delete.php?id=' . (int)$group['id'] . '&back=' . rawurlencode($back));
    }

    try {
        gd_delete_group_core($pdo, $group);
        gd_flash_set('ok', 'Групу видалено.');
        gd_redirect($back);
    } catch (Throwable $e) {
        gd_flash_set('err', $e->getMessage());
        gd_redirect('/functional/group/delete.php?id=' . (int)$group['id'] . '&back=' . rawurlencode($back));
    }
}

$title = gd_t('group_delete_title', 'Видалення групи');

require dirname(__DIR__, 2) . '/includes/header.php';
?>

<div class="container" style="max-width:860px;margin:24px auto;">
  <div class="card" style="padding:22px;">
    <h1 style="margin:0 0 18px;"><?= gd_h(gd_t('group_delete_title', 'Видалення групи')) ?></h1>

    <?php if ($msg = gd_flash_get('err')): ?>
      <div style="margin:0 0 16px;padding:12px 14px;border:1px solid #e0b4b4;border-radius:10px;background:#fff6f6;color:#9f3a38;">
        <?= gd_h($msg) ?>
      </div>
    <?php endif; ?>

    <?php if ($msg = gd_flash_get('ok')): ?>
      <div style="margin:0 0 16px;padding:12px 14px;border:1px solid #b7ebc6;border-radius:10px;background:#f6fff8;color:#1e7a35;">
        <?= gd_h($msg) ?>
      </div>
    <?php endif; ?>

    <div style="margin:0 0 18px;padding:14px;border:1px solid #eee;border-radius:12px;background:#fff;">
      <div style="font-size:18px;font-weight:700;margin-bottom:6px;"><?= gd_h((string)$group['name']) ?></div>
      <div style="color:#666;margin-bottom:6px;">slug: <?= gd_h((string)$group['slug']) ?></div>

      <?php
        $postCount = count(gd_group_post_ids($pdo, (int)$group['id']));
      ?>
      <div style="color:#666;">
        <?= gd_h(gd_t('posts', 'Пости')) ?>: <?= (int)$postCount ?>
      </div>
    </div>

    <div style="margin:0 0 18px;padding:14px;border:1px solid #f1d38a;border-radius:12px;background:#fffaf0;color:#7a5612;">
      <?= gd_h(gd_t('group_delete_warning', 'Ця дія безповоротно видалить групу, її пости, коментарі та вкладення.')) ?>
    </div>

    <form method="post" accept-charset="UTF-8">
      <input type="hidden" name="csrf" value="<?= gd_h(function_exists('csrf_token') ? csrf_token() : '') ?>">
      <input type="hidden" name="id" value="<?= (int)$group['id'] ?>">
      <input type="hidden" name="back" value="<?= gd_h($back) ?>">

      <div style="margin-bottom:14px;">
        <label for="confirm_name" style="display:block;margin-bottom:8px;font-weight:600;">
          <?= gd_h(gd_t('group_delete_confirm_label', 'Введи точну назву групи для підтвердження')) ?>
        </label>
        <input
          id="confirm_name"
          type="text"
          name="confirm_name"
          value=""
          placeholder="<?= gd_h((string)$group['name']) ?>"
          autocomplete="off"
          style="width:100%;padding:12px;border:1px solid #dcdfe6;border-radius:12px;box-sizing:border-box;"
        >
      </div>

      <div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;">
        <button
          type="submit"
          style="padding:10px 16px;border:0;border-radius:10px;cursor:pointer;background:#c0392b;color:#fff;"
        >
          <?= gd_h(gd_t('delete', 'Видалити')) ?>
        </button>

        <a
          href="<?= gd_h($back) ?>"
          style="padding:10px 16px;border:1px solid #ddd;border-radius:10px;text-decoration:none;color:inherit;"
        >
          <?= gd_h(gd_t('cancel', 'Скасувати')) ?>
        </a>
      </div>
    </form>
  </div>
</div>

<?php require dirname(__DIR__, 2) . '/includes/footer.php'; ?>