<?php
declare(strict_types=1);

/**
 * /functional/albums/photo_delete.php
 * Видалення одного фото з альбому.
 *
 * POST:
 * - csrf
 * - photo_id
 * - back (optional)
 *
 * Поведінка:
 * - видаляє запис з album_photos
 * - якщо фото було cover_photo_id альбому:
 *   - ставить наступне перше фото як обкладинку
 *   - або NULL, якщо фото більше не лишилось
 * - оновлює updated_at альбому
 * - намагається видалити файл з /upload/...
 */

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

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

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

if (!function_exists('alb_photo_delete_require_login')) {
    function alb_photo_delete_require_login(): void
    {
        if (function_exists('require_login')) {
            require_login();
            return;
        }

        $me = alb_me();
        if (!$me || (int)($me['id'] ?? 0) <= 0) {
            alb_photo_delete_redirect('/login.php');
        }
    }
}

if (!function_exists('alb_photo_delete_safe_back_url')) {
    function alb_photo_delete_safe_back_url(string $back, string $fallback): string
    {
        $back = trim($back);
        if ($back === '') {
            return $fallback;
        }

        if (str_contains($back, "\r") || str_contains($back, "\n")) {
            return $fallback;
        }

        if (!str_starts_with($back, '/')) {
            return $fallback;
        }

        return $back;
    }
}

if (!function_exists('alb_photo_delete_append_query')) {
    function alb_photo_delete_append_query(string $url, array $params): string
    {
        $url = trim($url);
        if ($url === '') {
            $url = '/profile/index.php?tab=albums';
        }

        $fragment = '';
        if (str_contains($url, '#')) {
            [$url, $fragment] = explode('#', $url, 2);
            $fragment = '#' . $fragment;
        }

        $path = $url;
        $query = '';

        if (str_contains($url, '?')) {
            [$path, $query] = explode('?', $url, 2);
        }

        $current = [];
        if ($query !== '') {
            parse_str($query, $current);
            if (!is_array($current)) {
                $current = [];
            }
        }

        foreach ($params as $k => $v) {
            $current[(string)$k] = $v;
        }

        $qs = http_build_query($current);
        return $path . ($qs !== '' ? ('?' . $qs) : '') . $fragment;
    }
}

if (!function_exists('alb_photo_delete_abs_from_path')) {
    function alb_photo_delete_abs_from_path(string $path): string
    {
        $path = trim($path);
        $path = strtok($path, '?') ?: $path;
        $relative = ltrim($path, '/');

        if (preg_match('~^upload/~i', $relative)) {
            $relative = preg_replace('~^upload/~i', '', $relative) ?? $relative;
            $relative = ltrim($relative, '/');
        }

        return rtrim(alb_upload_root_abs(), '/') . '/' . $relative;
    }
}

alb_photo_delete_require_login();

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

if (strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET')) !== 'POST') {
    alb_photo_delete_redirect('/profile/index.php?tab=albums');
}

if (!alb_ready($pdo)) {
    alb_photo_delete_redirect('/profile/index.php?tab=albums&am=schema');
}

$photoId = (int)($_POST['photo_id'] ?? 0);
if ($photoId <= 0) {
    alb_photo_delete_redirect('/profile/index.php?tab=albums');
}

$photo = alb_photo_get($pdo, $photoId);
if (!$photo) {
    alb_photo_delete_redirect('/profile/index.php?tab=albums');
}

$albumId = (int)($photo['album_id'] ?? 0);
$album = alb_album_get($pdo, $albumId);
if (!$album) {
    alb_photo_delete_redirect('/profile/index.php?tab=albums');
}

$owner = alb_user_get($pdo, (int)($album['user_id'] ?? 0));
$fallbackBack = $owner ? alb_album_url($album, $owner) : '/profile/index.php?tab=albums';

$rawBack = (string)($_POST['back'] ?? '');
$back = alb_photo_delete_safe_back_url($rawBack, $fallbackBack);

if (!alb_csrf_check((string)($_POST['csrf'] ?? ''))) {
    alb_photo_delete_redirect(alb_photo_delete_append_query($back, ['am' => 'csrf']));
}

if (!alb_can_manage_album($album, $me)) {
    alb_photo_delete_redirect(alb_photo_delete_append_query($back, ['am' => 'denied']));
}

$filePath = trim((string)($photo['file_path'] ?? ''));
$fileAbs  = ($filePath !== '' && !str_contains($filePath, '..'))
    ? alb_photo_delete_abs_from_path($filePath)
    : '';

$wasCover = ((int)($album['cover_photo_id'] ?? 0) === $photoId);
$ownTx = !$pdo->inTransaction();

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

    $st = $pdo->prepare("DELETE FROM album_photos WHERE id = ? LIMIT 1");
    $st->execute([$photoId]);

    if ($wasCover) {
        $newCover = alb_album_first_photo($pdo, $albumId);
        $newCoverId = (int)($newCover['id'] ?? 0);

        if ($newCoverId > 0) {
            $st = $pdo->prepare("
                UPDATE photo_albums
                SET cover_photo_id = ?, updated_at = NOW()
                WHERE id = ?
                LIMIT 1
            ");
            $st->execute([$newCoverId, $albumId]);
        } else {
            $st = $pdo->prepare("
                UPDATE photo_albums
                SET cover_photo_id = NULL, updated_at = NOW()
                WHERE id = ?
                LIMIT 1
            ");
            $st->execute([$albumId]);
        }
    } else {
        $st = $pdo->prepare("
            UPDATE photo_albums
            SET updated_at = NOW()
            WHERE id = ?
            LIMIT 1
        ");
        $st->execute([$albumId]);
    }

    if ($ownTx) {
        $pdo->commit();
    }
} catch (Throwable $e) {
    if ($ownTx && $pdo->inTransaction()) {
        $pdo->rollBack();
    }

    alb_photo_delete_redirect(alb_photo_delete_append_query($back, ['am' => 'db']));
}

/* файл видаляємо вже після commit */
if ($fileAbs !== '') {
    alb_safe_unlink_under_upload($fileAbs);
}

alb_photo_delete_redirect(alb_photo_delete_append_query($back, [
    'pm' => 'deleted',
]));