<?php

function cmsMediaRoots($rootPath)
{
    $root = rtrim((string) $rootPath, '/\\');
    return [
        ['path' => $root . '/uploads', 'url' => '/uploads'],
        ['path' => $root . '/public/uploads', 'url' => '/public/uploads'],
        ['path' => $root . '/admin/uploads', 'url' => '/admin/uploads'],
    ];
}

function cmsNormalizeMediaUrl($value)
{
    $value = html_entity_decode(trim((string) $value), ENT_QUOTES, 'UTF-8');
    $path = parse_url($value, PHP_URL_PATH);
    $path = $path === false || $path === null ? $value : $path;
    $path = '/' . ltrim(str_replace('\\', '/', rawurldecode($path)), '/');
    return preg_match('#^/(?:public/|admin/)?uploads/#i', $path) ? $path : '';
}

function cmsExtractMediaUrls($value)
{
    $value = str_replace('\\/', '/', (string) $value);
    preg_match_all('#(?:https?://[^\s"\'<>]+)?/(?:public/|admin/)?uploads/[^\s"\'<>\)]+#iu', $value, $matches);
    $urls = [];
    foreach ($matches[0] as $url) {
        $normalized = cmsNormalizeMediaUrl(rtrim($url, '.,;'));
        if ($normalized !== '') { $urls[$normalized] = true; }
    }
    return array_keys($urls);
}

function cmsMediaType($extension)
{
    $extension = strtolower(ltrim((string) $extension, '.'));
    if (in_array($extension, ['jpg','jpeg','png','gif','webp','bmp','ico'], true)) { return 'image'; }
    if (in_array($extension, ['mp4','webm','mov','avi','mkv','wmv','mpeg','mpg','ogv'], true)) { return 'video'; }
    if (in_array($extension, ['mp3','wav','ogg'], true)) { return 'audio'; }
    if (in_array($extension, ['pdf','doc','docx','xls','xlsx','ppt','pptx','txt','md','csv'], true)) { return 'document'; }
    if (in_array($extension, ['zip','rar','7z','tar','gz','bz2'], true)) { return 'archive'; }
    return 'other';
}

function cmsScanMediaFiles($rootPath)
{
    $files = [];
    foreach (cmsMediaRoots($rootPath) as $root) {
        if (!is_dir($root['path'])) { continue; }
        $base = realpath($root['path']);
        $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($base, FilesystemIterator::SKIP_DOTS));
        foreach ($iterator as $item) {
            if (!$item->isFile() || $item->isLink() || substr($item->getFilename(), 0, 1) === '.') { continue; }
            $path = $item->getRealPath();
            if ($path === false || strpos(strtolower($path), strtolower($base . DIRECTORY_SEPARATOR)) !== 0) { continue; }
            $relative = str_replace('\\', '/', substr($path, strlen($base) + 1));
            $url = $root['url'] . '/' . $relative;
            $files[$url] = ['url'=>$url,'path'=>$path,'name'=>$item->getFilename(),'extension'=>strtolower($item->getExtension()),'type'=>cmsMediaType($item->getExtension()),'size'=>$item->getSize(),'modified_at'=>$item->getMTime()];
        }
    }
    return $files;
}

function cmsMediaReferenceFields()
{
    return [
        'article'=>['litpic','content','attachment_url'], 'product'=>['litpic','pictures','content','main_video_url','consult_wechat_qr'],
        'page'=>['page_content','litpic'], 'image'=>['litpic','albums','content'], 'download'=>['file_path','content','litpic'],
        'video'=>['litpic','video_path','video_cover','content'], 'recruit'=>['litpic','content'], 'slide'=>['litpic'],
        'ads'=>['ad_code','content'], 'link'=>['link_logo'], 'channel'=>['channel_thumb','channel_intro'], 'config'=>['config_value'],
        'custom_var'=>['var_value'], 'builder_page'=>['layout_json'], 'builder_page_history'=>['layout_json'],
        'member'=>['avatar'], 'admin'=>['avatar'], 'contribute'=>['litpic','content'], 'installation'=>['image','icon'],
        'template_showcase'=>['thumb','images','description'], 'order_product'=>['litpic','product_image'], 'icon'=>['litpic','file_path'],
    ];
}

function cmsCollectMediaReferences($db, $rootPath = null)
{
    $references = [];
    foreach (cmsMediaReferenceFields() as $table => $wantedFields) {
        try {
            $fullTable = $db->table($table);
            $columns = $db->fetchAll("SHOW COLUMNS FROM {$fullTable}");
            $available = array_column($columns, 'Field');
            $fields = array_values(array_intersect($wantedFields, $available));
            if (!$fields) { continue; }
            $idField = in_array('id', $available, true) ? 'id' : $fields[0];
            $rows = $db->fetchAll('SELECT `' . $idField . '`, `' . implode('`,`', $fields) . "` FROM {$fullTable}");
            foreach ($rows as $row) {
                foreach ($fields as $field) {
                    foreach (cmsExtractMediaUrls($row[$field] ?? '') as $url) {
                        $references[$url][] = ['source'=>$table,'field'=>$field,'id'=>(string) ($row[$idField] ?? '')];
                    }
                }
            }
        } catch (Throwable $e) { continue; }
    }
    if ($rootPath) {
        $templateRoot = rtrim((string) $rootPath, '/\\') . '/template';
        if (is_dir($templateRoot)) {
            $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($templateRoot, FilesystemIterator::SKIP_DOTS));
            foreach ($iterator as $item) {
                if (!$item->isFile() || $item->getSize() > 2 * 1024 * 1024 || !preg_match('/\.(php|html?|css|js|json)$/i', $item->getFilename())) { continue; }
                foreach (cmsExtractMediaUrls((string) @file_get_contents($item->getPathname())) as $url) {
                    $references[$url][] = ['source'=>'template','field'=>str_replace('\\','/',substr($item->getPathname(),strlen($templateRoot)+1)),'id'=>''];
                }
            }
        }
    }
    return $references;
}

function cmsResolveMediaFile($rootPath, $url)
{
    $url = cmsNormalizeMediaUrl($url);
    if ($url === '') { return null; }
    foreach (cmsMediaRoots($rootPath) as $root) {
        if ($url !== $root['url'] && strpos($url, $root['url'] . '/') !== 0) { continue; }
        $base = realpath($root['path']);
        if ($base === false) { return null; }
        $candidate = realpath($base . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, substr($url, strlen($root['url']) + 1)));
        if ($candidate && is_file($candidate) && !is_link($candidate) && strpos(strtolower($candidate), strtolower($base . DIRECTORY_SEPARATOR)) === 0) { return $candidate; }
    }
    return null;
}

function cmsDeleteUnusedMedia($db, $rootPath, $url)
{
    $path = cmsResolveMediaFile($rootPath, $url);
    if (!$path) { return ['success'=>false,'message'=>'资源不存在或路径不安全']; }
    $references = cmsCollectMediaReferences($db, $rootPath);
    $url = cmsNormalizeMediaUrl($url);
    if (!empty($references[$url])) { return ['success'=>false,'message'=>'资源仍被引用，不能删除','references'=>$references[$url]]; }
    return @unlink($path) ? ['success'=>true,'message'=>'资源已安全删除'] : ['success'=>false,'message'=>'文件删除失败，请检查目录权限'];
}
