<?php
declare(strict_types=1);

require_once __DIR__ . '/_auth.php';
tpcms_require_admin();
require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../app/security.php';

// -------- CSRF（GETでもトークン必須）--------
$token = isset($_GET['_csrf']) ? (string)$_GET['_csrf'] : '';
if (!tpcms_verify_csrf($token)) {
    http_response_code(400);
    header('Content-Type: text/plain; charset=UTF-8');
    echo "Bad Request: invalid CSRF token";
    exit;
}

// -------- 設定 --------
$uploadsDir = realpath(TPCMS_UPLOADS) ?: TPCMS_UPLOADS;
$dataDir    = realpath(TPCMS_DATA)    ?: TPCMS_DATA;
$allowedExt = ['jpg','jpeg','png','gif','webp','svg','mp4','webm','mov','ico'];

// 安全確認
if (!is_dir($uploadsDir) || !is_readable($uploadsDir) || !is_writable($uploadsDir)) {
    http_response_code(500);
    header('Content-Type: text/plain; charset=UTF-8');
    echo "Server Error: uploads directory is not accessible";
    exit;
}
if (!is_dir($dataDir) || !is_readable($dataDir)) {
    http_response_code(500);
    header('Content-Type: text/plain; charset=UTF-8');
    echo "Server Error: data directory is not accessible";
    exit;
}

// -------- data/ の全 JSON から /uploads 参照（および拡張子一致の素のファイル名）を収集 --------
$used = [];

/** 再帰で配列/オブジェクト内の文字列を走査し、uploads参照っぽい basename を収集 */
$collectFromNode = function ($node) use (&$collectFromNode, &$used, $allowedExt) {
    if (is_array($node)) {
        foreach ($node as $v) $collectFromNode($v);
        return;
    }
    if (is_object($node)) {
        foreach ((array)$node as $v) $collectFromNode($v);
        return;
    }
    if (!is_string($node)) return;

    $s = trim($node);
    if ($s === '' || preg_match('#^https?://#i', $s)) return;

    // /uploads/ を含む → basename
    if (strpos($s, '/uploads/') !== false) {
        $bn = basename(str_replace('\\', '/', $s));
    } else {
        // 末尾拡張子が許可リストに一致する場合のみ basename
        $bn = basename(str_replace('\\', '/', $s));
        $ext = strtolower(pathinfo($bn, PATHINFO_EXTENSION));
        if ($ext === '' || !in_array($ext, $allowedExt, true)) return;
    }
    if ($bn !== '' && $bn !== '.' && $bn !== '..') {
        $used[$bn] = true;
    }
};

// data配下の *.json を再帰で走査
$rii = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($dataDir, FilesystemIterator::SKIP_DOTS)
);
foreach ($rii as $file) {
    /** @var SplFileInfo $file */
    if (!$file->isFile()) continue;
    if (strtolower($file->getExtension()) !== 'json') continue;

    $raw = @file_get_contents($file->getPathname());
    if ($raw === false || $raw === '') continue;
    $json = json_decode($raw);
    if ($json === null && json_last_error() !== JSON_ERROR_NONE) continue;

    $collectFromNode($json);
}

// -------- uploads/ から未使用ファイルを削除 --------
$deleted = 0;
$it = new DirectoryIterator($uploadsDir);
foreach ($it as $fi) {
    if (!$fi->isFile()) continue;
    $bn  = $fi->getBasename();
    $ext = strtolower(pathinfo($bn, PATHINFO_EXTENSION));

    // .htaccess 等は対象外、許可拡張子のみ
    if ($bn[0] === '.' || !in_array($ext, $allowedExt, true)) continue;

    if (!isset($used[$bn])) {
        $full = $fi->getPathname();
        // 念のため uploads配下かどうかを再確認
        $real = realpath($full);
        if ($real && strpos($real, realpath($uploadsDir)) === 0) {
            @unlink($real);
            $deleted++;
        }
    }
}

// -------- 完了：ダッシュボードへ戻す（控えめ表示） --------
header('Location: ./index.php?cleaned=' . (int)$deleted, true, 303);
exit;
