<?php
declare(strict_types=1);

/**
 * /functional/albums/view.php
 * Перегляд одного фотоальбому.
 *
 * GET:
 * - album_id
 * - u (optional owner username for nicer back-link)
 *
 * Правила:
 * - public  => видно всім
 * - friends => тільки друзям / owner / admin
 * - private => тільки owner / admin
 *
 * UI:
 * - показує обкладинку, опис, owner/meta
 * - для owner/admin:
 *   - upload кількох фото
 *   - видалення альбому
 *   - видалення окремих фото
 */

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

$pdo = alb_db();
$me  = alb_me();

if (!function_exists('alb_view_redirect')) {
    function alb_view_redirect(string $url, int $code = 302): void
    {
        header('Location: ' . $url, true, $code);
        exit;
    }
}

if (!function_exists('alb_view_tr')) {
    function alb_view_tr(string $uk, string $ru, string $en): string
    {
        return alb_t($uk, $ru, $en);
    }
}

if (!function_exists('alb_view_require_header')) {
    function alb_view_require_header(): void
    {
        $header = __DIR__ . '/../../includes/header.php';
        if (is_file($header)) {
            require $header;
        }
    }
}

if (!function_exists('alb_view_require_footer')) {
    function alb_view_require_footer(): void
    {
        $footer = __DIR__ . '/../../includes/footer.php';
        if (is_file($footer)) {
            require $footer;
        }
    }
}

if (!function_exists('alb_view_html_date')) {
    function alb_view_html_date(?string $dt): string
    {
        $raw = trim((string)$dt);
        if ($raw === '') {
            return '';
        }

        $ts = strtotime($raw);
        if ($ts === false || $ts <= 0) {
            return $raw;
        }

        return date('d.m.Y H:i', $ts);
    }
}

if (!function_exists('alb_view_photo_url')) {
    function alb_view_photo_url(array $photo): string
    {
        $path = trim((string)($photo['file_path'] ?? ''));
        if ($path === '' || str_contains($path, '..')) {
            return '';
        }

        if (preg_match('~^https?://~i', $path)) {
            return $path;
        }

        if (str_starts_with($path, '/')) {
            return $path;
        }

        if (preg_match('~^upload/~i', $path) || preg_match('~^uploads/~i', $path)) {
            return '/' . ltrim($path, '/');
        }

        return '/' . ltrim($path, '/');
    }
}

if (!function_exists('alb_view_initial')) {
    function alb_view_initial(string $name, string $fallback = 'U'): string
    {
        $name = trim($name);
        if ($name === '') {
            return $fallback;
        }

        if (function_exists('mb_substr')) {
            $ch = (string)mb_substr($name, 0, 1, 'UTF-8');
            if (function_exists('mb_strtoupper')) {
                return (string)mb_strtoupper($ch, 'UTF-8');
            }
            return strtoupper($ch);
        }

        return strtoupper(substr($name, 0, 1));
    }
}

if (!function_exists('alb_view_format_mb')) {
    function alb_view_format_mb(int $bytes): string
    {
        if ($bytes <= 0) {
            return '0 MB';
        }

        return number_format($bytes / 1024 / 1024, 2) . ' MB';
    }
}

if (!function_exists('alb_view_message_text')) {
    function alb_view_message_text(string $code, array $query = []): array
    {
        $uploaded = (int)($query['uploaded'] ?? 0);
        $failed   = (int)($query['failed'] ?? 0);
        $max      = (int)($query['max'] ?? 0);
        $attempt  = (int)($query['attempt'] ?? 0);

        return match ($code) {
            'deleted' => ['success', alb_view_tr('Фотоальбом видалено.', 'Фотоальбом удалён.', 'Album deleted.')],
            'uploaded' => ['success',
                trim(
                    alb_view_tr(
                        'Фотографії завантажено.',
                        'Фотографии загружены.',
                        'Photos uploaded.'
                    )
                    . ($uploaded > 0 ? (' ' . alb_view_tr('Успішно:', 'Успешно:', 'Uploaded:') . ' ' . $uploaded . '.') : '')
                    . ($failed > 0 ? (' ' . alb_view_tr('Не вдалося:', 'Не удалось:', 'Failed:') . ' ' . $failed . '.') : '')
                )
            ],
            'nofiles' => ['warning', alb_view_tr('Оберіть хоча б один файл для завантаження.', 'Выберите хотя бы один файл для загрузки.', 'Choose at least one file to upload.')],
            'limit' => ['warning',
                trim(
                    alb_view_tr(
                        'Забагато файлів за один раз.',
                        'Слишком много файлов за один раз.',
                        'Too many files in one request.'
                    )
                    . ($max > 0 ? (' ' . alb_view_tr('Ліміт:', 'Лимит:', 'Limit:') . ' ' . $max . '.') : '')
                    . ($attempt > 0 ? (' ' . alb_view_tr('Передано:', 'Передано:', 'Provided:') . ' ' . $attempt . '.') : '')
                )
            ],
            'schema'  => ['danger', alb_view_tr('У БД не знайдено потрібні таблиці photo_albums / album_photos.', 'В БД не найдены нужные таблицы photo_albums / album_photos.', 'Required tables photo_albums / album_photos were not found.')],
            'db'      => ['danger', alb_view_tr('Помилка бази даних.', 'Ошибка базы данных.', 'Database error.')],
            'csrf'    => ['danger', alb_view_tr('Помилка CSRF. Оновіть сторінку.', 'Ошибка CSRF. Обновите страницу.', 'CSRF error. Refresh the page.')],
            'denied'  => ['danger', alb_view_tr('Недостатньо прав.', 'Недостаточно прав.', 'Access denied.')],
            default   => ['', ''],
        };
    }
}

if (!function_exists('alb_view_photo_message_text')) {
    function alb_view_photo_message_text(string $code): array
    {
        return match ($code) {
            'deleted' => ['success', alb_view_tr('Фото видалено.', 'Фото удалено.', 'Photo deleted.')],
            default   => ['', ''],
        };
    }
}

$albumId = (int)($_GET['album_id'] ?? 0);
if ($albumId <= 0) {
    http_response_code(404);
    $title = alb_view_tr('Фотоальбом не знайдено', 'Фотоальбом не найден', 'Album not found');
    $seo_noindex = true;
    alb_view_require_header();
    ?>
    <div class="container my-4">
        <div class="alert alert-danger"><?= alb_h($title) ?></div>
    </div>
    <?php
    alb_view_require_footer();
    exit;
}

if (!alb_ready($pdo)) {
    http_response_code(500);
    $title = alb_view_tr('Фотоальбоми ще не готові', 'Фотоальбомы ещё не готовы', 'Albums module is not ready');
    $seo_noindex = true;
    alb_view_require_header();
    ?>
    <div class="container my-4">
        <div class="alert alert-danger">
            <?= alb_h(alb_view_tr(
                'У БД не знайдено потрібні таблиці photo_albums / album_photos.',
                'В БД не найдены таблицы photo_albums / album_photos.',
                'Required tables photo_albums / album_photos were not found.'
            )) ?>
        </div>
    </div>
    <?php
    alb_view_require_footer();
    exit;
}

$album = alb_album_get($pdo, $albumId);
if (!$album) {
    http_response_code(404);
    $title = alb_view_tr('Фотоальбом не знайдено', 'Фотоальбом не найден', 'Album not found');
    $seo_noindex = true;
    alb_view_require_header();
    ?>
    <div class="container my-4">
        <div class="alert alert-danger"><?= alb_h($title) ?></div>
    </div>
    <?php
    alb_view_require_footer();
    exit;
}

$owner = alb_user_get($pdo, (int)($album['user_id'] ?? 0));
if (!$owner) {
    http_response_code(404);
    $title = alb_view_tr('Користувача не знайдено', 'Пользователь не найден', 'User not found');
    $seo_noindex = true;
    alb_view_require_header();
    ?>
    <div class="container my-4">
        <div class="alert alert-danger"><?= alb_h($title) ?></div>
    </div>
    <?php
    alb_view_require_footer();
    exit;
}

$canView = alb_can_view_album($pdo, $album, $owner, $me);
if (!$canView) {
    $meId = alb_current_user_id($me);
    if ($meId <= 0) {
        $to = '/functional/albums/view.php?' . http_build_query([
            'album_id' => $albumId,
            'u'        => (string)($owner['username'] ?? ''),
        ]);
        alb_view_redirect('/login.php?to=' . urlencode($to));
    }

    http_response_code(403);
    $title = alb_view_tr('Немає доступу', 'Нет доступа', 'Access denied');
    $seo_noindex = true;
    alb_view_require_header();
    ?>
    <div class="container my-4">
        <div class="alert alert-warning">
            <?= alb_h(alb_view_tr(
                'Ви не маєте доступу до цього фотоальбому.',
                'У вас нет доступа к этому фотоальбому.',
                'You do not have access to this album.'
            )) ?>
        </div>
        <a class="btn btn-outline-secondary" href="<?= alb_h(alb_profile_albums_url($owner)) ?>">
            <?= alb_h(alb_view_tr('Назад до профілю', 'Назад к профилю', 'Back to profile')) ?>
        </a>
    </div>
    <?php
    alb_view_require_footer();
    exit;
}

$photos = alb_list_album_photos($pdo, $albumId, 1000, 0);
$canManage = alb_can_manage_album($album, $me);
$ownerName = alb_user_display_name($owner);
$ownerUsername = trim((string)($owner['username'] ?? ''));
$ownerAvatar = alb_user_avatar_url($owner);
$profileAlbumsUrl = alb_profile_albums_url($owner);
$backUrl = $profileAlbumsUrl;
$coverUrl = alb_album_cover_url($pdo, $album);
$currentCoverId = (int)($album['cover_photo_id'] ?? 0);
$privacyOptions = function_exists('alb_privacy_options') ? alb_privacy_options() : [
    'public'  => alb_view_tr('Усі', 'Все', 'Public'),
    'friends' => alb_view_tr('Тільки друзі', 'Только друзья', 'Friends only'),
    'private' => alb_view_tr('Тільки я', 'Только я', 'Only me'),
];
$editTitleValue = trim((string)($album['title'] ?? ''));
$editDescriptionValue = trim((string)($album['description'] ?? ''));
$editPrivacyValue = function_exists('alb_privacy_normalize')
    ? alb_privacy_normalize((string)($album['privacy'] ?? 'public'))
    : (in_array((string)($album['privacy'] ?? 'public'), ['public', 'friends', 'private'], true) ? (string)$album['privacy'] : 'public');

$amCode = trim((string)($_GET['am'] ?? ''));
$pmCode = trim((string)($_GET['pm'] ?? ''));

[$msgType, $msgText] = alb_view_message_text($amCode, $_GET);
[$msgType2, $msgText2] = alb_view_photo_message_text($pmCode);

$galleryItems = [];
foreach ($photos as $photoForGallery) {
    $galleryUrl = alb_view_photo_url($photoForGallery);
    if ($galleryUrl === '') {
        continue;
    }

    $galleryCaption = trim((string)($photoForGallery['caption'] ?? ''));
    $galleryOriginal = trim((string)($photoForGallery['original_name'] ?? ''));
    $galleryAlt = $galleryCaption !== ''
        ? $galleryCaption
        : ($galleryOriginal !== '' ? $galleryOriginal : trim((string)($album['title'] ?? '')));

    $galleryItems[] = [
        'url'      => $galleryUrl,
        'caption'  => $galleryCaption,
        'original' => $galleryOriginal,
        'alt'      => $galleryAlt,
        'width'    => (int)($photoForGallery['width'] ?? 0),
        'height'   => (int)($photoForGallery['height'] ?? 0),
    ];
}

$title = trim((string)($album['title'] ?? ''));
$pageTitle = $title !== ''
    ? ($title . ' — ' . alb_view_tr('Фотоальбом', 'Фотоальбом', 'Photo album'))
    : alb_view_tr('Фотоальбом', 'Фотоальбом', 'Photo album');

$meta_desc = trim((string)($album['description'] ?? ''));
if ($meta_desc === '') {
    $meta_desc = alb_view_tr(
        'Перегляд фотоальбому користувача.',
        'Просмотр фотоальбома пользователя.',
        'View user photo album.'
    );
}
$canonical = function_exists('abs_url')
    ? abs_url('/functional/albums/view.php?' . http_build_query([
        'album_id' => $albumId,
        'u'        => $ownerUsername,
    ]))
    : null;
$seo_noindex = true;

$title = $pageTitle;


alb_view_require_header();
?>
<style>
.alb-page-card{
    border:1px solid rgba(148,163,184,.18);
    border-radius:18px;
    background:#fff;
    box-shadow:0 10px 30px rgba(15,23,42,.05);
}
.alb-cover{
    width:100%;
    height:260px;
    border-radius:18px;
    overflow:hidden;
    background:linear-gradient(135deg,#f1f5f9,#e2e8f0);
    display:flex;
    align-items:center;
    justify-content:center;
    margin-bottom:18px;
}
.alb-cover img{
    width:100%;
    height:100%;
    object-fit:cover;
    display:block;
}
.alb-cover-placeholder{
    color:#64748b;
    font-weight:600;
}
.alb-owner{
    display:flex;
    align-items:center;
    gap:14px;
}
.alb-owner-avatar{
    width:64px;
    height:64px;
    border-radius:16px;
    object-fit:cover;
    background:#e2e8f0;
    display:block;
}
.alb-owner-avatar-placeholder{
    width:64px;
    height:64px;
    border-radius:16px;
    background:#e2e8f0;
    display:flex;
    align-items:center;
    justify-content:center;
    font-weight:700;
    color:#475569;
}
.alb-meta{
    display:flex;
    flex-wrap:wrap;
    gap:10px;
    margin-top:10px;
}
.alb-meta .badge{
    font-size:.88rem;
    padding:.55rem .75rem;
    border-radius:999px;
}
.alb-actions{
    display:flex;
    flex-wrap:wrap;
    gap:10px;
}
.alb-gallery-wrap{
    margin-top:24px;
}
.alb-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill,minmax(220px,1fr));
    gap:16px;
}
.alb-photo-card{
    border:1px solid rgba(148,163,184,.16);
    border-radius:16px;
    background:#fff;
    overflow:hidden;
    box-shadow:0 8px 24px rgba(15,23,42,.04);
}
.alb-photo-link{
    display:block;
    text-decoration:none;
    color:inherit;
}
.alb-photo-thumb-wrap{
    position:relative;
}
.alb-photo-thumb{
    width:100%;
    height:220px;
    background:#f8fafc;
    display:block;
    object-fit:cover;
}
.alb-cover-badge{
    position:absolute;
    left:10px;
    top:10px;
    z-index:2;
    border-radius:999px;
    padding:.38rem .62rem;
    font-size:.78rem;
    font-weight:600;
    background:rgba(15,23,42,.82);
    color:#fff;
}
.alb-photo-info{
    padding:12px;
}
.alb-photo-caption{
    margin:0 0 8px 0;
    font-size:.95rem;
    color:#334155;
    white-space:pre-wrap;
    word-break:break-word;
}
.alb-empty{
    border:1px dashed rgba(148,163,184,.45);
    border-radius:16px;
    padding:28px;
    text-align:center;
    color:#64748b;
    background:#f8fafc;
}
.alb-upload-card{
    border:1px solid rgba(148,163,184,.18);
    border-radius:18px;
    background:#fff;
    box-shadow:0 10px 30px rgba(15,23,42,.05);
    margin-top:28px;
}
.alb-upload-head{
    display:flex;
    align-items:center;
    justify-content:space-between;
    flex-wrap:wrap;
    gap:10px 16px;
    margin-bottom:18px;
}
.alb-upload-form{
    margin-top:2px;
}
.alb-upload-form .form-label{
    margin-bottom:10px;
    font-weight:600;
}
.alb-upload-form .form-control{
    min-height:52px;
}
.alb-upload-note{
    color:#64748b;
    font-size:.92rem;
    line-height:1.55;
}
.alb-settings-card{
    border:1px solid rgba(148,163,184,.18);
    border-radius:18px;
    background:#fff;
    box-shadow:0 10px 30px rgba(15,23,42,.05);
}
.alb-settings-help{
    color:#64748b;
    font-size:.92rem;
}
.alb-settings-toggle-row{
    display:flex;
    justify-content:flex-end;
    margin:-6px 0 12px;
}
.alb-settings-card[hidden]{
    display:none !important;
}
.alb-photo-actions{
    display:flex;
    flex-wrap:wrap;
    gap:8px;
    margin-top:10px;
}
.alb-lightbox{
    position:fixed;
    inset:0;
    z-index:1060;
    background:rgba(2,6,23,.92);
    display:none;
    align-items:center;
    justify-content:center;
    padding:24px;
}
.alb-lightbox.is-open{
    display:flex;
}
.alb-lightbox-dialog{
    position:relative;
    width:min(1100px,100%);
    max-height:100%;
    display:flex;
    flex-direction:column;
    gap:14px;
}
.alb-lightbox-stage{
    position:relative;
    min-height:220px;
    background:rgba(15,23,42,.35);
    border:1px solid rgba(148,163,184,.2);
    border-radius:18px;
    overflow:hidden;
    display:flex;
    align-items:center;
    justify-content:center;
    touch-action:pan-y;
    user-select:none;
    -webkit-user-select:none;
}
.alb-lightbox-image{
    display:block;
    max-width:100%;
    max-height:min(78vh,900px);
    width:auto;
    height:auto;
    object-fit:contain;
    margin:0 auto;
}
.alb-lightbox-btn{
    position:absolute;
    top:50%;
    transform:translateY(-50%);
    width:48px;
    height:48px;
    border:none;
    border-radius:999px;
    background:rgba(15,23,42,.72);
    color:#fff;
    font-size:28px;
    line-height:1;
    display:flex;
    align-items:center;
    justify-content:center;
    cursor:pointer;
    transition:background .15s ease;
}
.alb-lightbox-btn:hover{
    background:rgba(15,23,42,.9);
}
.alb-lightbox-btn:disabled{
    opacity:.45;
    cursor:default;
}
.alb-lightbox-btn-prev{ left:14px; }
.alb-lightbox-btn-next{ right:14px; }
.alb-lightbox-close{
    position:absolute;
    top:14px;
    right:14px;
    width:44px;
    height:44px;
    border:none;
    border-radius:999px;
    background:rgba(15,23,42,.78);
    color:#fff;
    font-size:28px;
    line-height:1;
    display:flex;
    align-items:center;
    justify-content:center;
    cursor:pointer;
}
.alb-lightbox-meta{
    border:1px solid rgba(148,163,184,.18);
    border-radius:18px;
    background:#fff;
    padding:14px 16px;
}
.alb-lightbox-caption{
    margin:0 0 6px;
    font-weight:600;
    color:#0f172a;
    white-space:pre-wrap;
    word-break:break-word;
}
.alb-lightbox-sub{
    color:#64748b;
    font-size:.94rem;
    word-break:break-word;
}
.alb-lightbox-counter{
    color:#64748b;
    font-size:.94rem;
    margin-top:6px;
}
body.alb-lightbox-open{
    overflow:hidden;
}
@media (max-width: 767px){
    .alb-cover{ height:190px; }
    .alb-photo-thumb{ height:180px; }
    .alb-lightbox{
        padding:12px;
    }
    .alb-lightbox-stage{
        border-radius:14px;
    }
    .alb-lightbox-image{
        max-height:70vh;
    }
    .alb-lightbox-btn{
        width:42px;
        height:42px;
        font-size:24px;
    }
    .alb-lightbox-btn-prev{ left:10px; }
    .alb-lightbox-btn-next{ right:10px; }
    .alb-lightbox-close{
        top:10px;
        right:10px;
        width:40px;
        height:40px;
        font-size:24px;
    }
    .alb-settings-toggle-row{
        justify-content:stretch;
    }
    .alb-settings-toggle-row .btn{
        width:100%;
    }
    .alb-upload-card{
        margin-top:22px;
    }
    .alb-upload-head{
        margin-bottom:14px;
    }
}
</style>

<div class="container my-4" id="albPageTop">
    <?php if ($msgText !== '' && $msgType !== ''): ?>
        <div class="alert alert-<?= alb_h($msgType) ?>"><?= alb_h($msgText) ?></div>
    <?php endif; ?>

    <?php if ($msgText2 !== '' && $msgType2 !== ''): ?>
        <div class="alert alert-<?= alb_h($msgType2) ?>"><?= alb_h($msgText2) ?></div>
    <?php endif; ?>

    <div class="alb-page-card p-3 p-md-4 mb-4">
        <div class="d-flex flex-wrap align-items-center justify-content-between gap-3 mb-3">
            <a class="btn btn-outline-secondary" href="<?= alb_h($backUrl) ?>">
                ← <?= alb_h(alb_view_tr('Назад до фотоальбомів', 'Назад к фотоальбомам', 'Back to albums')) ?>
            </a>

            <div class="alb-actions">
                <?php if ($canManage): ?>
                    <form method="post" action="/functional/albums/delete.php" class="m-0" onsubmit="return confirm('<?= alb_h(alb_view_tr('Видалити цей фотоальбом разом з усіма фотографіями?', 'Удалить этот фотоальбом вместе со всеми фотографиями?', 'Delete this album with all photos?')) ?>');">
                        <input type="hidden" name="csrf" value="<?= alb_h(alb_csrf_token()) ?>">
                        <input type="hidden" name="album_id" value="<?= (int)$albumId ?>">
                        <input type="hidden" name="back" value="<?= alb_h($backUrl) ?>">
                        <button type="submit" class="btn btn-outline-danger">
                            <?= alb_h(alb_view_tr('Видалити альбом', 'Удалить альбом', 'Delete album')) ?>
                        </button>
                    </form>
                <?php endif; ?>
            </div>
        </div>

        <?php if ($coverUrl !== ''): ?>
            <div class="alb-cover">
                <img src="<?= alb_h($coverUrl) ?>" alt="<?= alb_h($title) ?>">
            </div>
        <?php else: ?>
            <div class="alb-cover">
                <div class="alb-cover-placeholder"><?= alb_h(alb_view_tr('Обкладинка альбому', 'Обложка альбома', 'Album cover')) ?></div>
            </div>
        <?php endif; ?>

        <div class="d-flex flex-wrap justify-content-between gap-3 mb-3">
            <div class="alb-owner">
                <?php if ($ownerAvatar !== ''): ?>
                    <img class="alb-owner-avatar" src="<?= alb_h($ownerAvatar) ?>" alt="<?= alb_h($ownerName) ?>">
                <?php else: ?>
                    <div class="alb-owner-avatar-placeholder">
                        <?= alb_h(alb_view_initial($ownerName !== '' ? $ownerName : $ownerUsername)) ?>
                    </div>
                <?php endif; ?>

                <div>
                    <h1 class="h4 mb-1"><?= alb_h($title !== '' ? $title : alb_view_tr('Без назви', 'Без названия', 'Untitled')) ?></h1>
                    <div class="text-muted">
                        <?= alb_h(alb_view_tr('Автор', 'Автор', 'Owner')) ?>:
                        <a href="<?= alb_h('/profile/index.php?' . http_build_query($ownerUsername !== '' ? ['u' => $ownerUsername] : ['id' => (int)$owner['id']])) ?>">
                            <?= alb_h($ownerName) ?>
                        </a>
                        <?php if ($ownerUsername !== ''): ?>
                            <span class="text-muted">@<?= alb_h($ownerUsername) ?></span>
                        <?php endif; ?>
                    </div>
                </div>
            </div>

            <div class="text-muted small text-md-end">
                <div><?= alb_h(alb_view_tr('Створено', 'Создано', 'Created')) ?>: <?= alb_h(alb_view_html_date((string)($album['created_at'] ?? ''))) ?></div>
                <div><?= alb_h(alb_view_tr('Оновлено', 'Обновлено', 'Updated')) ?>: <?= alb_h(alb_view_html_date((string)($album['updated_at'] ?? ''))) ?></div>
            </div>
        </div>

        <div class="alb-meta">
            <span class="badge bg-light text-dark">
                <?= alb_h(alb_view_tr('Фотографій', 'Фотографий', 'Photos')) ?>:
                <?= (int)($album['photos_count'] ?? count($photos)) ?>
            </span>
            <span class="badge bg-light text-dark">
                <?= alb_h(alb_view_tr('Доступ', 'Доступ', 'Privacy')) ?>:
                <?= alb_h(alb_privacy_label((string)($album['privacy'] ?? 'public'))) ?>
            </span>
            <?php if ($currentCoverId > 0): ?>
                <span class="badge bg-light text-dark">
                    <?= alb_h(alb_view_tr('Є обкладинка', 'Есть обложка', 'Cover set')) ?>
                </span>
            <?php endif; ?>
        </div>

        <?php $desc = trim((string)($album['description'] ?? '')); ?>
        <?php if ($desc !== ''): ?>
            <div class="mt-3" style="white-space:pre-wrap;word-break:break-word;"><?= alb_h($desc) ?></div>
        <?php endif; ?>
    </div>

    <?php if ($canManage): ?>
        <div class="alb-settings-toggle-row">
            <button
                type="button"
                class="btn btn-outline-primary"
                id="albEditToggleBtn"
                aria-expanded="false"
                aria-controls="albEditAlbumPanel"
            >
                <?= alb_h(alb_view_tr('Редагування альбому', 'Редактирование альбома', 'Edit album')) ?>
            </button>
        </div>

        <div class="alb-settings-card p-3 p-md-4 mb-4" id="albEditAlbumPanel" hidden>
            <div class="d-flex align-items-center justify-content-between flex-wrap gap-2 mb-2">
                <div class="fw-semibold"><?= alb_h(alb_view_tr('Редагування альбому', 'Редактирование альбома', 'Edit album')) ?></div>
                <div class="small text-muted"><?= alb_h(alb_view_tr('Тут можна змінити назву, опис і приватність.', 'Здесь можно изменить название, описание и приватность.', 'Here you can change the title, description and privacy.')) ?></div>
            </div>

            <form method="post" action="/functional/albums/update.php" class="vstack gap-3">
                <input type="hidden" name="csrf" value="<?= alb_h(alb_csrf_token()) ?>">
                <input type="hidden" name="album_id" value="<?= (int)$albumId ?>">
                <input type="hidden" name="back" value="<?= alb_h(alb_album_url($album, $owner)) ?>">

                <div>
                    <label class="form-label"><?= alb_h(alb_view_tr('Назва', 'Название', 'Title')) ?></label>
                    <input
                        type="text"
                        class="form-control"
                        name="title"
                        maxlength="190"
                        required
                        value="<?= alb_h($editTitleValue) ?>"
                    >
                </div>

                <div>
                    <label class="form-label"><?= alb_h(alb_view_tr('Опис', 'Описание', 'Description')) ?></label>
                    <textarea class="form-control" name="description" rows="4" maxlength="5000"><?= alb_h($editDescriptionValue) ?></textarea>
                </div>

                <div>
                    <label class="form-label"><?= alb_h(alb_view_tr('Доступ', 'Доступ', 'Privacy')) ?></label>
                    <select class="form-select" name="privacy">
                        <?php foreach ($privacyOptions as $privacyValue => $privacyLabel): ?>
                            <option value="<?= alb_h($privacyValue) ?>" <?= $editPrivacyValue === $privacyValue ? 'selected' : '' ?>>
                                <?= alb_h($privacyLabel) ?>
                            </option>
                        <?php endforeach; ?>
                    </select>
                </div>

                <div class="alb-settings-help">
                    <?= alb_h(alb_view_tr(
                        'Обкладинка змінюється окремо — кнопкою під потрібною фотографією нижче, без її видалення.',
                        'Обложка меняется отдельно — кнопкой под нужной фотографией ниже, без её удаления.',
                        'The cover is changed separately using the button under the needed photo below, without deleting it.'
                    )) ?>
                </div>

                <div>
                    <button type="submit" class="btn btn-primary">
                        <?= alb_h(alb_view_tr('Зберегти зміни', 'Сохранить изменения', 'Save changes')) ?>
                    </button>
                </div>
            </form>
        </div>
    <?php endif; ?>

    <div class="alb-gallery-wrap">
        <?php if ($photos): ?>
            <div class="alb-grid">
                <?php
                $visibleGalleryIndex = 0;
                foreach ($photos as $photo):
                    $photoId  = (int)($photo['id'] ?? 0);
                    $photoUrl = alb_view_photo_url($photo);
                    if ($photoUrl === '') {
                        continue;
                    }

                    $caption  = trim((string)($photo['caption'] ?? ''));
                    $original = trim((string)($photo['original_name'] ?? ''));
                    $isCover  = ($currentCoverId > 0 && $currentCoverId === $photoId)
                        || ($currentCoverId <= 0 && $coverUrl !== '' && $photoUrl === $coverUrl);
                    ?>
                    <div class="alb-photo-card">
                        <div class="alb-photo-thumb-wrap">
                            <?php if ($isCover): ?>
                                <div class="alb-cover-badge"><?= alb_h(alb_view_tr('Обкладинка', 'Обложка', 'Cover')) ?></div>
                            <?php endif; ?>

                            <button
                                type="button"
                                class="alb-photo-link border-0 bg-transparent p-0 js-alb-open-photo"
                                data-gallery-index="<?= (int)$visibleGalleryIndex ?>"
                                aria-label="<?= alb_h(alb_view_tr('Відкрити фото', 'Открыть фото', 'Open photo')) ?>"
                            >
                                <img
                                    class="alb-photo-thumb"
                                    src="<?= alb_h($photoUrl) ?>"
                                    alt="<?= alb_h($caption !== '' ? $caption : ($original !== '' ? $original : $title)) ?>"
                                    loading="lazy"
                                >
                            </button>
                        </div>

                        <div class="alb-photo-info">
                            <?php if ($caption !== ''): ?>
                                <p class="alb-photo-caption"><?= alb_h($caption) ?></p>
                            <?php endif; ?>

                            <div class="small text-muted">
                                <?php if ((int)($photo['width'] ?? 0) > 0 && (int)($photo['height'] ?? 0) > 0): ?>
                                    <span><?= (int)$photo['width'] ?>×<?= (int)$photo['height'] ?></span>
                                <?php endif; ?>
                                <?php if ((int)($photo['size_bytes'] ?? 0) > 0): ?>
                                    <span class="ms-2"><?= alb_h(alb_view_format_mb((int)$photo['size_bytes'])) ?></span>
                                <?php endif; ?>
                            </div>

                            <?php if ($original !== ''): ?>
                                <div class="small text-muted mt-1" style="word-break:break-word;">
                                    <?= alb_h($original) ?>
                                </div>
                            <?php endif; ?>

                            <?php if ($canManage): ?>
                                <div class="alb-photo-actions">
                                    <?php if (!$isCover): ?>
                                        <form method="post" action="/functional/albums/cover_set.php" class="m-0">
                                            <input type="hidden" name="csrf" value="<?= alb_h(alb_csrf_token()) ?>">
                                            <input type="hidden" name="album_id" value="<?= (int)$albumId ?>">
                                            <input type="hidden" name="photo_id" value="<?= $photoId ?>">
                                            <input type="hidden" name="back" value="<?= alb_h(alb_album_url($album, $owner)) ?>">
                                            <button type="submit" class="btn btn-sm btn-outline-primary">
                                                <?= alb_h(alb_view_tr('Зробити обкладинкою', 'Сделать обложкой', 'Make cover')) ?>
                                            </button>
                                        </form>
                                    <?php else: ?>
                                        <span class="btn btn-sm btn-primary disabled" aria-disabled="true">
                                            <?= alb_h(alb_view_tr('Поточна обкладинка', 'Текущая обложка', 'Current cover')) ?>
                                        </span>
                                    <?php endif; ?>

                                    <button
                                        type="button"
                                        class="btn btn-sm btn-outline-secondary js-alb-open-photo"
                                        data-gallery-index="<?= (int)$visibleGalleryIndex ?>"
                                    >
                                        <?= alb_h(alb_view_tr('Відкрити', 'Открыть', 'Open')) ?>
                                    </button>

                                    <form method="post" action="/functional/albums/photo_delete.php" class="m-0" onsubmit="return confirm('<?= alb_h(alb_view_tr('Видалити це фото?', 'Удалить это фото?', 'Delete this photo?')) ?>');">
                                        <input type="hidden" name="csrf" value="<?= alb_h(alb_csrf_token()) ?>">
                                        <input type="hidden" name="photo_id" value="<?= $photoId ?>">
                                        <input type="hidden" name="back" value="<?= alb_h(alb_album_url($album, $owner)) ?>">
                                        <button type="submit" class="btn btn-sm btn-outline-danger">
                                            <?= alb_h(alb_view_tr('Видалити', 'Удалить', 'Delete')) ?>
                                        </button>
                                    </form>
                                </div>
                            <?php else: ?>
                                <div class="alb-photo-actions">
                                    <button
                                        type="button"
                                        class="btn btn-sm btn-outline-secondary js-alb-open-photo"
                                        data-gallery-index="<?= (int)$visibleGalleryIndex ?>"
                                    >
                                        <?= alb_h(alb_view_tr('Відкрити', 'Открыть', 'Open')) ?>
                                    </button>
                                </div>
                            <?php endif; ?>
                        </div>
                    </div>
                    <?php
                    $visibleGalleryIndex++;
                endforeach;
                ?>
            </div>
        <?php else: ?>
            <div class="alb-empty">
                <?= alb_h(alb_view_tr(
                    'У цьому альбомі ще немає фотографій.',
                    'В этом альбоме ещё нет фотографий.',
                    'This album does not have any photos yet.'
                )) ?>
            </div>
        <?php endif; ?>
    </div>

    <?php if ($canManage): ?>
        <div class="alb-upload-card p-3 p-md-4 mb-4">
            <div class="alb-upload-head">
                <div class="fw-semibold"><?= alb_h(alb_view_tr('Завантаження фотографій', 'Загрузка фотографий', 'Upload photos')) ?></div>
                <div class="small text-muted"><?= alb_h(alb_view_tr('До 20 файлів за раз, до 10 MB кожен', 'До 20 файлов за раз, до 10 MB каждый', 'Up to 20 files at once, up to 10 MB each')) ?></div>
            </div>

            <form method="post" action="/functional/albums/upload.php" enctype="multipart/form-data" class="alb-upload-form">
                <input type="hidden" name="csrf" value="<?= alb_h(alb_csrf_token()) ?>">
                <input type="hidden" name="album_id" value="<?= (int)$albumId ?>">
                <input type="hidden" name="back" value="<?= alb_h(alb_album_url($album, $owner)) ?>">

                <div class="mb-3">
                    <label class="form-label"><?= alb_h(alb_view_tr('Файли', 'Файлы', 'Files')) ?></label>
                    <input
                        type="file"
                        class="form-control"
                        name="photos[]"
                        accept="image/jpeg,image/png,image/webp,image/gif"
                        multiple
                        required
                    >
                </div>

                <div class="form-check mb-3">
                    <input
                        class="form-check-input"
                        type="checkbox"
                        value="1"
                        id="make_first_uploaded_cover"
                        name="make_first_uploaded_cover"
                        <?= $currentCoverId <= 0 ? 'checked' : '' ?>
                    >
                    <label class="form-check-label" for="make_first_uploaded_cover">
                        <?= alb_h(alb_view_tr('Зробити перше з нових фото обкладинкою альбому', 'Сделать первое из новых фото обложкой альбома', 'Make the first newly uploaded photo the album cover')) ?>
                    </label>
                </div>

                <div class="alb-upload-note mb-3">
                    <?= alb_h(alb_view_tr(
                        'Підписи до окремих фото додамо наступним кроком. Зараз можна швидко завантажувати кілька зображень одразу.',
                        'Подписи к отдельным фото добавим следующим шагом. Сейчас можно быстро загружать несколько изображений сразу.',
                        'Per-photo captions will be added next. Right now you can quickly upload multiple images at once.'
                    )) ?>
                </div>

                <button type="submit" class="btn btn-primary">
                    <?= alb_h(alb_view_tr('Завантажити фото', 'Загрузить фото', 'Upload photos')) ?>
                </button>
            </form>
        </div>
    <?php endif; ?>
</div>

<?php if ($galleryItems): ?>
    <div class="alb-lightbox" id="albLightbox" hidden aria-hidden="true">
        <div class="alb-lightbox-dialog" role="dialog" aria-modal="true" aria-label="<?= alb_h(alb_view_tr('Перегляд фотографії', 'Просмотр фотографии', 'Photo viewer')) ?>">
            <div class="alb-lightbox-stage">
                <button type="button" class="alb-lightbox-close" id="albLightboxClose" aria-label="<?= alb_h(alb_view_tr('Закрити', 'Закрыть', 'Close')) ?>">&times;</button>
                <button type="button" class="alb-lightbox-btn alb-lightbox-btn-prev" id="albLightboxPrev" aria-label="<?= alb_h(alb_view_tr('Попереднє фото', 'Предыдущее фото', 'Previous photo')) ?>">&lsaquo;</button>
                <img class="alb-lightbox-image" id="albLightboxImage" src="" alt="">
                <button type="button" class="alb-lightbox-btn alb-lightbox-btn-next" id="albLightboxNext" aria-label="<?= alb_h(alb_view_tr('Наступне фото', 'Следующее фото', 'Next photo')) ?>">&rsaquo;</button>
            </div>
            <div class="alb-lightbox-meta">
                <p class="alb-lightbox-caption" id="albLightboxCaption"></p>
                <div class="alb-lightbox-sub" id="albLightboxSub"></div>
                <div class="alb-lightbox-counter" id="albLightboxCounter"></div>
            </div>
        </div>
    </div>
<?php endif; ?>

<script>
(function () {
    const editToggleBtn = document.getElementById('albEditToggleBtn');
    const editPanel = document.getElementById('albEditAlbumPanel');

    if (editToggleBtn && editPanel) {
        editToggleBtn.addEventListener('click', function () {
            const willOpen = editPanel.hasAttribute('hidden');
            if (willOpen) {
                editPanel.removeAttribute('hidden');
            } else {
                editPanel.setAttribute('hidden', 'hidden');
            }
            editToggleBtn.setAttribute('aria-expanded', willOpen ? 'true' : 'false');
        });
    }

    const galleryItems = <?= json_encode($galleryItems, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
    if (!Array.isArray(galleryItems) || !galleryItems.length) {
        return;
    }

    const body = document.body;
    const modal = document.getElementById('albLightbox');
    const modalImage = document.getElementById('albLightboxImage');
    const modalCaption = document.getElementById('albLightboxCaption');
    const modalSub = document.getElementById('albLightboxSub');
    const modalCounter = document.getElementById('albLightboxCounter');
    const modalStage = modal ? modal.querySelector('.alb-lightbox-stage') : null;
    const prevBtn = document.getElementById('albLightboxPrev');
    const nextBtn = document.getElementById('albLightboxNext');
    const closeBtn = document.getElementById('albLightboxClose');
    const openButtons = Array.from(document.querySelectorAll('.js-alb-open-photo'));

    let currentIndex = 0;
    let lastTrigger = null;
    let touchStartX = null;
    let touchStartY = null;
    let touchMoved = false;
    const swipeThreshold = 45;
    const swipeRestraint = 80;

    function renderImage(index) {
        if (!galleryItems[index]) {
            return;
        }

        currentIndex = index;
        const item = galleryItems[index];
        const caption = (item.caption || '').trim();
        const original = (item.original || '').trim();
        const metaParts = [];

        if (original !== '') {
            metaParts.push(original);
        }
        if (Number(item.width) > 0 && Number(item.height) > 0) {
            metaParts.push(String(item.width) + '×' + String(item.height));
        }

        modalImage.src = item.url || '';
        modalImage.alt = item.alt || caption || original || '';
        modalCaption.textContent = caption !== '' ? caption : (original !== '' ? original : '');
        modalCaption.hidden = modalCaption.textContent === '';
        modalSub.textContent = metaParts.join(' • ');
        modalSub.hidden = modalSub.textContent === '';
        modalCounter.textContent = String(index + 1) + ' / ' + String(galleryItems.length);

        if (prevBtn) prevBtn.disabled = galleryItems.length <= 1;
        if (nextBtn) nextBtn.disabled = galleryItems.length <= 1;
    }

    function openModal(index, triggerEl) {
        if (!galleryItems[index] || !modal) {
            return;
        }

        lastTrigger = triggerEl || null;
        renderImage(index);
        modal.hidden = false;
        modal.classList.add('is-open');
        modal.setAttribute('aria-hidden', 'false');
        body.classList.add('alb-lightbox-open');

        if (closeBtn) {
            closeBtn.focus();
        }
    }

    function closeModal() {
        if (!modal) {
            return;
        }

        modal.classList.remove('is-open');
        modal.setAttribute('aria-hidden', 'true');
        modal.hidden = true;
        touchStartX = null;
        touchStartY = null;
        touchMoved = false;
        body.classList.remove('alb-lightbox-open');
        if (modalImage) {
            modalImage.removeAttribute('src');
        }

        if (lastTrigger && typeof lastTrigger.focus === 'function') {
            lastTrigger.focus();
        }
    }

    function showPrev() {
        renderImage((currentIndex - 1 + galleryItems.length) % galleryItems.length);
    }

    function showNext() {
        renderImage((currentIndex + 1) % galleryItems.length);
    }

    openButtons.forEach(function (button) {
        button.addEventListener('click', function () {
            const index = Number(button.getAttribute('data-gallery-index') || '0');
            openModal(index, button);
        });
    });

    if (prevBtn) prevBtn.addEventListener('click', showPrev);
    if (nextBtn) nextBtn.addEventListener('click', showNext);
    if (closeBtn) closeBtn.addEventListener('click', closeModal);

    if (modal) {
        modal.addEventListener('click', function (event) {
            if (event.target === modal) {
                closeModal();
            }
        });
    }

    if (modalStage) {
        modalStage.addEventListener('touchstart', function (event) {
            if (!modal || !modal.classList.contains('is-open') || !event.touches || event.touches.length !== 1) {
                return;
            }
            touchStartX = event.touches[0].clientX;
            touchStartY = event.touches[0].clientY;
            touchMoved = false;
        }, { passive: true });

        modalStage.addEventListener('touchmove', function (event) {
            if (touchStartX === null || touchStartY === null || !event.touches || event.touches.length !== 1) {
                return;
            }

            const deltaX = event.touches[0].clientX - touchStartX;
            const deltaY = event.touches[0].clientY - touchStartY;
            if (Math.abs(deltaX) > 8 || Math.abs(deltaY) > 8) {
                touchMoved = true;
            }

            if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 12) {
                event.preventDefault();
            }
        }, { passive: false });

        modalStage.addEventListener('touchend', function (event) {
            if (touchStartX === null || touchStartY === null || !touchMoved || !event.changedTouches || event.changedTouches.length !== 1) {
                touchStartX = null;
                touchStartY = null;
                touchMoved = false;
                return;
            }

            const deltaX = event.changedTouches[0].clientX - touchStartX;
            const deltaY = event.changedTouches[0].clientY - touchStartY;

            if (Math.abs(deltaX) >= swipeThreshold && Math.abs(deltaY) <= swipeRestraint) {
                if (deltaX < 0) {
                    showNext();
                } else {
                    showPrev();
                }
            }

            touchStartX = null;
            touchStartY = null;
            touchMoved = false;
        }, { passive: true });

        modalStage.addEventListener('touchcancel', function () {
            touchStartX = null;
            touchStartY = null;
            touchMoved = false;
        }, { passive: true });
    }

    document.addEventListener('keydown', function (event) {
        if (!modal || !modal.classList.contains('is-open')) {
            return;
        }

        if (event.key === 'Escape') {
            event.preventDefault();
            closeModal();
        } else if (event.key === 'ArrowLeft') {
            event.preventDefault();
            showPrev();
        } else if (event.key === 'ArrowRight') {
            event.preventDefault();
            showNext();
        }
    });
})();
</script>

<?php
alb_view_require_footer();