<?php

function cmsQualityContentTypes()
{
    return [
        'article'=>['label'=>'文章','title'=>'title','content'=>'content','summary'=>'summary','cover'=>'litpic','edit'=>'article'],
        'product'=>['label'=>'产品','title'=>'title','content'=>'content','summary'=>'summary','cover'=>'litpic','edit'=>'product'],
        'page'=>['label'=>'单页','title'=>'page_title','content'=>'page_content','summary'=>'','cover'=>'litpic','edit'=>'page'],
        'download'=>['label'=>'下载','title'=>'title','content'=>'content','summary'=>'','cover'=>'litpic','edit'=>'download'],
        'video'=>['label'=>'视频','title'=>'title','content'=>'content','summary'=>'','cover'=>'litpic','edit'=>'video'],
        'recruit'=>['label'=>'招聘','title'=>'title','content'=>'content','summary'=>'summary','cover'=>'litpic','edit'=>'recruit'],
    ];
}

function cmsQualityPlainText($html)
{
    $text = html_entity_decode(strip_tags((string) $html), ENT_QUOTES, 'UTF-8');
    return trim(preg_replace('/\s+/u', ' ', $text));
}

function cmsQualityTextLength($value)
{
    $text = cmsQualityPlainText($value);
    return function_exists('mb_strlen') ? mb_strlen($text, 'UTF-8') : strlen($text);
}

function cmsQualityExtractInternalLinks($html)
{
    preg_match_all('/\bhref\s*=\s*(["\'])(.*?)\1/iu', (string) $html, $matches);
    $links = [];
    foreach ($matches[2] as $href) {
        $href = html_entity_decode(trim($href), ENT_QUOTES, 'UTF-8');
        if ($href === '' || preg_match('~^(?:mailto:|tel:|javascript:|data:|#)~i', $href)) { continue; }
        $host = parse_url($href, PHP_URL_HOST);
        if ($host) { continue; }
        $path = parse_url($href, PHP_URL_PATH) ?: '';
        if ($path !== '' && substr($path, 0, 1) === '/') { $links[$href] = true; }
    }
    return array_keys($links);
}

function cmsQualityResolveInternalLink($db, $rootPath, $href)
{
    $path = (string) (parse_url($href, PHP_URL_PATH) ?: '');
    $query = []; parse_str((string) (parse_url($href, PHP_URL_QUERY) ?: ''), $query);
    if (preg_match('#^/(article|product|page|image|download|video|recruit)/([0-9]+)\.html$#i', $path, $m)) {
        return cmsQualityContentExists($db, strtolower($m[1]), intval($m[2]));
    }
    if ($path === '/public/index.php' && isset($query['m'], $query['id']) && preg_match('/^(article|product|page|image|download|video|recruit)$/', (string) $query['m'])) {
        return cmsQualityContentExists($db, (string) $query['m'], intval($query['id']));
    }
    if (preg_match('#^/(?:public/|admin/)?uploads/#i', $path)) {
        $candidate = realpath(rtrim((string) $rootPath, '/\\') . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, ltrim(rawurldecode($path), '/')));
        $root = realpath(rtrim((string) $rootPath, '/\\'));
        return $candidate && $root && is_file($candidate) && strpos(strtolower($candidate), strtolower($root . DIRECTORY_SEPARATOR)) === 0;
    }
    return true;
}

function cmsQualityContentExists($db, $type, $id)
{
    if (!isset(cmsQualityContentTypes()[$type]) && $type !== 'image') { return true; }
    try {
        $columns = array_column($db->fetchAll('SHOW COLUMNS FROM ' . $db->table($type)), 'Field');
        $where = 'id=?';
        if (in_array('status', $columns, true)) { $where .= ' AND status=1'; }
        if (in_array('deleted_at', $columns, true)) { $where .= ' AND deleted_at=0'; }
        return (bool) $db->fetch('SELECT id FROM ' . $db->table($type) . ' WHERE ' . $where . ' LIMIT 1', [$id]);
    } catch (Throwable $e) { return true; }
}

function cmsQualityAnalyzeRow(array $row, array $meta, $duplicate = false, array $brokenLinks = [])
{
    $issues = [];
    $add = function($code,$severity,$label,$suggestion) use (&$issues){$issues[]=['code'=>$code,'severity'=>$severity,'label'=>$label,'suggestion'=>$suggestion];};
    if (trim((string) ($row['seo_title'] ?? '')) === '') { $add('seo_title','medium','缺少 SEO 标题','补充独立、清晰的搜索标题'); }
    if (trim((string) ($row['seo_keywords'] ?? '')) === '') { $add('seo_keywords','low','缺少 SEO 关键词','补充与内容匹配的关键词'); }
    if (trim((string) ($row['seo_description'] ?? '')) === '') { $add('seo_description','medium','缺少 SEO 描述','撰写准确的页面摘要'); }
    if ($meta['cover'] !== '' && trim((string) ($row[$meta['cover']] ?? '')) === '') { $add('cover','medium','缺少封面','设置清晰、符合内容的封面图'); }
    if ($meta['summary'] !== '' && trim((string) ($row[$meta['summary']] ?? '')) === '') { $add('summary','low','摘要为空','补充列表页和分享场景使用的摘要'); }
    $length = cmsQualityTextLength($row[$meta['content']] ?? '');
    if ($length < 80) { $add('short_content',$length === 0 ? 'high' : 'medium',$length === 0 ? '正文为空' : '正文过短','完善正文内容，当前约 '.$length.' 字'); }
    if ($duplicate) { $add('duplicate_title','high','标题重复','调整标题以避免内容和搜索结果混淆'); }
    if ($brokenLinks) { $add('broken_link','high','存在失效站内链接','检查：'.implode('、',array_slice($brokenLinks,0,3))); }
    return $issues;
}

function cmsCollectContentQuality($db, $rootPath)
{
    $results = [];
    foreach (cmsQualityContentTypes() as $type => $meta) {
        try {
            $columns = array_column($db->fetchAll('SHOW COLUMNS FROM ' . $db->table($type)), 'Field');
            $needed = array_values(array_unique(array_filter(['id',$meta['title'],$meta['content'],$meta['summary'],$meta['cover'],'seo_title','seo_keywords','seo_description','status','deleted_at'])));
            $fields = array_values(array_intersect($needed, $columns));
            if (!in_array('id',$fields,true) || !in_array($meta['title'],$fields,true)) { continue; }
            $where = in_array('deleted_at',$columns,true) ? ' WHERE deleted_at=0' : '';
            $rows = $db->fetchAll('SELECT `'.implode('`,`',$fields).'` FROM '.$db->table($type).$where.' ORDER BY id DESC');
            $titleCounts=[]; foreach($rows as $row){$title=trim((string)$row[$meta['title']]);if($title!=='')$titleCounts[$title]=intval($titleCounts[$title]??0)+1;}
            foreach ($rows as $row) {
                $broken=[];
                foreach(cmsQualityExtractInternalLinks($row[$meta['content']] ?? '') as $link){if(!cmsQualityResolveInternalLink($db,$rootPath,$link))$broken[]=$link;}
                $title=trim((string)$row[$meta['title']]);
                $issues=cmsQualityAnalyzeRow($row,$meta,$title!==''&&($titleCounts[$title]??0)>1,$broken);
                if(!$issues)continue;
                $results[]=['type'=>$type,'type_label'=>$meta['label'],'id'=>intval($row['id']),'title'=>$title ?: '未命名内容','published'=>intval($row['status'] ?? 0)===1,'issues'=>$issues,'edit_url'=>'?act='.$meta['edit'].'&action=edit&id='.intval($row['id'])];
            }
        } catch (Throwable $e) { continue; }
    }
    return $results;
}

function cmsQualitySummary(array $results)
{
    $summary=['contents'=>count($results),'issues'=>0,'high'=>0,'medium'=>0,'low'=>0];
    foreach($results as $item){foreach($item['issues'] as $issue){$summary['issues']++;$summary[$issue['severity']]++;}}
    return $summary;
}
