<?php
require_once dirname(__DIR__) . '/config/config.php';
require_once dirname(__DIR__) . '/includes/db.php';
require_once dirname(__DIR__) . '/includes/functions.php';
require_once dirname(__DIR__) . '/includes/auth.php';
require_once dirname(__DIR__) . '/includes/layout.php';
require_once dirname(__DIR__) . '/includes/functions_tags.php';
require_once dirname(__DIR__) . '/includes/functions_search.php';
requirePermission('metadata_view');

$pdo = getDBConnection();
$filter = (string)($_GET['filter'] ?? 'needs_review');
$q = trim((string)($_GET['q'] ?? ''));
$sort = (string)($_GET['sort'] ?? 'recent');
$page = max(1, (int)($_GET['page'] ?? 1));
$limit = 50;

$mojibakeSql = "(s.title LIKE '%�%' OR s.artist LIKE '%�%' OR s.album LIKE '%�%' OR s.genre LIKE '%�%'
    OR s.title LIKE '%???%' OR s.artist LIKE '%???%' OR s.album LIKE '%???%'
    OR s.title LIKE '%Array%' OR s.artist LIKE '%Array%' OR s.album LIKE '%Array%')";

$qualityFilters = [
    'needs_review' => ['label' => '정리 필요', 'sql' => "(s.title IS NULL OR TRIM(s.title) = '' OR s.artist IS NULL OR TRIM(s.artist) = '' OR s.album IS NULL OR TRIM(s.album) = '' OR s.genre IS NULL OR TRIM(s.genre) = '' OR s.year IS NULL OR TRIM(s.year) = '' OR s.track_no IS NULL OR s.duration IS NULL OR s.duration <= 0 OR COALESCE(s.has_cover, 0) = 0 OR (s.metadata_error IS NOT NULL AND TRIM(s.metadata_error) != ''))"],
    'missing_title' => ['label' => '제목 없음', 'sql' => "s.title IS NULL OR TRIM(s.title) = ''"],
    'missing_artist' => ['label' => '가수 없음', 'sql' => "s.artist IS NULL OR TRIM(s.artist) = ''"],
    'missing_album' => ['label' => '앨범 없음', 'sql' => "s.album IS NULL OR TRIM(s.album) = ''"],
    'missing_album_artist' => ['label' => '앨범 아티스트 없음', 'sql' => "s.album_artist IS NULL OR TRIM(s.album_artist) = ''"],
    'missing_genre' => ['label' => '장르 없음', 'sql' => "s.genre IS NULL OR TRIM(s.genre) = ''"],
    'missing_year' => ['label' => '연도 없음', 'sql' => "s.year IS NULL OR TRIM(s.year) = ''"],
    'missing_track' => ['label' => '트랙번호 없음', 'sql' => "s.track_no IS NULL OR s.track_no <= 0"],
    'missing_duration' => ['label' => '재생시간 없음', 'sql' => "s.duration IS NULL OR s.duration <= 0"],
    'missing_cover' => ['label' => '앨범아트 없음', 'sql' => "COALESCE(s.has_cover, 0) = 0 OR s.cover_hash IS NULL OR TRIM(s.cover_hash) = ''"],
    'cover_suspicious' => ['label' => '앨범아트 오류 의심', 'sql' => "COALESCE(s.has_cover, 0) = 1 AND (s.cover_mime IS NULL OR TRIM(s.cover_mime) = '' OR s.cover_mime NOT LIKE 'image/%')"],
    'missing_lyrics' => ['label' => '가사 없음', 'sql' => "NOT EXISTS (SELECT 1 FROM lyrics lx WHERE lx.song_id = s.id AND TRIM(COALESCE(lx.lyrics_text, '')) <> '')"],
    'getid3_error' => ['label' => 'getID3 분석 실패', 'sql' => "s.metadata_error IS NOT NULL AND TRIM(s.metadata_error) != ''"],
    'fallback_only' => ['label' => 'fallback 적용', 'sql' => "s.metadata_source IN ('filename', 'mixed', 'unknown')"],
    'mojibake' => ['label' => '한글 깨짐 의심', 'sql' => $mojibakeSql],
    'duplicates' => ['label' => '중복 곡 의심', 'sql' => "EXISTS (
        SELECT 1 FROM songs d
        WHERE d.id <> s.id
          AND COALESCE(d.is_missing, 0) = 0
          AND LOWER(TRIM(COALESCE(d.title, ''))) = LOWER(TRIM(COALESCE(s.title, '')))
          AND LOWER(TRIM(COALESCE(d.artist, ''))) = LOWER(TRIM(COALESCE(s.artist, '')))
          AND COALESCE(d.title, '') <> ''
          AND COALESCE(d.artist, '') <> ''
          AND ABS(COALESCE(d.duration, 0) - COALESCE(s.duration, 0)) <= 2
    )"],
    'missing_file' => ['label' => '파일 없음', 'sql' => "COALESCE(s.is_missing, 0) = 1"],
    'recent_error' => ['label' => '최근 스캔 오류', 'sql' => "s.metadata_error IS NOT NULL AND TRIM(s.metadata_error) != '' AND s.last_metadata_scan_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)"],
    'manual' => ['label' => '수동 수정됨', 'sql' => "COALESCE(s.is_manual_edited, 0) = 1"],
];
if (!isset($qualityFilters[$filter])) $filter = 'needs_review';

$sortOptions = [
    'recent' => 's.id DESC',
    'scan' => 's.last_metadata_scan_at DESC, s.id DESC',
    'updated' => 's.metadata_updated_at DESC, s.id DESC',
    'title' => 's.title ASC, s.artist ASC, s.id DESC',
    'artist' => 's.artist ASC, s.title ASC, s.id DESC',
];
$orderBy = $sortOptions[$sort] ?? $sortOptions['recent'];

$where = [];
$params = [];
if ($filter !== 'missing_file') {
    $where[] = 'COALESCE(s.is_missing, 0) = 0';
}
$where[] = '(' . $qualityFilters[$filter]['sql'] . ')';
if ($q !== '') {
    $where[] = '(s.title LIKE :q OR s.artist LIKE :q OR s.album LIKE :q OR s.genre LIKE :q)';
    $params[':q'] = '%' . normalizeSearchQuery($q) . '%';
}
$whereSql = implode(' AND ', $where);

$total = 0;
$songs = [];
$pages = 1;
try {
    $countStmt = $pdo->prepare("SELECT COUNT(DISTINCT s.id) FROM songs s WHERE $whereSql");
    $countStmt->execute($params);
    $total = (int)$countStmt->fetchColumn();
    $pages = max(1, (int)ceil($total / $limit));
    $page = min($page, $pages);
    $offset = ($page - 1) * $limit;

    $stmt = $pdo->prepare("
        SELECT s.id, s.title, s.artist, s.album, s.album_artist, s.genre, s.year, s.track_no,
               s.disc_no, s.duration, s.extension, s.folder_name, s.relative_path,
               s.metadata_source, s.metadata_error, s.metadata_updated_at, s.last_metadata_scan_at,
               s.is_manual_edited, s.is_missing, s.has_cover, s.cover_hash, s.cover_mime, s.updated_at,
               EXISTS (
                   SELECT 1 FROM lyrics lx
                   WHERE lx.song_id = s.id
                     AND TRIM(COALESCE(lx.lyrics_text, '')) <> ''
               ) AS has_lyrics_text,
               EXISTS (
                   SELECT 1 FROM songs d2
                   WHERE d2.id <> s.id
                     AND COALESCE(d2.is_missing, 0) = 0
                     AND LOWER(TRIM(COALESCE(d2.title, ''))) = LOWER(TRIM(COALESCE(s.title, '')))
                     AND LOWER(TRIM(COALESCE(d2.artist, ''))) = LOWER(TRIM(COALESCE(s.artist, '')))
                     AND COALESCE(d2.title, '') <> ''
                     AND COALESCE(d2.artist, '') <> ''
                     AND ABS(COALESCE(d2.duration, 0) - COALESCE(s.duration, 0)) <= 2
               ) AS duplicate_candidate
        FROM songs s
        WHERE $whereSql
        ORDER BY $orderBy
        LIMIT " . (int)$limit . " OFFSET " . (int)$offset
    );
    $stmt->execute($params);
    $songs = $stmt->fetchAll();
} catch (Throwable $e) {
    if (function_exists('writeAppLog')) {
        writeAppLog('error', 'metadata_error', 'Metadata quality query failed', ['filter' => $filter, 'error' => $e->getMessage()]);
    }
}

function metadataQualityUrl($changes = []) {
    $params = $_GET;
    foreach ($changes as $key => $value) {
        if ($value === null || $value === '') unset($params[$key]);
        else $params[$key] = $value;
    }
    return 'metadata_quality.php?' . http_build_query($params);
}

function metadataLooksBroken($song) {
    foreach (['title', 'artist', 'album', 'genre'] as $field) {
        $value = (string)($song[$field] ?? '');
        if ($value === '') continue;
        if (strpos($value, '�') !== false || stripos($value, 'Array') !== false) return true;
        if (preg_match('/\?{3,}/', $value)) return true;
    }
    return false;
}

function metadataIssueBadges($song) {
    $badges = [];
    if (trim((string)($song['title'] ?? '')) === '') $badges[] = ['text' => '제목 없음', 'type' => 'danger'];
    if (trim((string)($song['artist'] ?? '')) === '') $badges[] = ['text' => '가수 없음', 'type' => 'danger'];
    if (trim((string)($song['album'] ?? '')) === '') $badges[] = ['text' => '앨범 없음', 'type' => 'danger'];
    if (trim((string)($song['album_artist'] ?? '')) === '') $badges[] = ['text' => '앨범 아티스트 없음', 'type' => 'danger'];
    if (trim((string)($song['genre'] ?? '')) === '') $badges[] = ['text' => '장르 없음', 'type' => 'danger'];
    if (trim((string)($song['year'] ?? '')) === '') $badges[] = ['text' => '연도 없음', 'type' => 'danger'];
    if (empty($song['track_no'])) $badges[] = ['text' => '트랙번호 없음', 'type' => 'danger'];
    if (empty($song['duration'])) $badges[] = ['text' => '재생시간 없음', 'type' => 'danger'];
    if (empty($song['has_cover']) || trim((string)($song['cover_hash'] ?? '')) === '') $badges[] = ['text' => '앨범아트 없음', 'type' => 'danger'];
    if (!empty($song['cover_mime']) && stripos((string)$song['cover_mime'], 'image/') !== 0) $badges[] = ['text' => '앨범아트 MIME 의심', 'type' => 'warning'];
    if (!empty($song['metadata_error'])) $badges[] = ['text' => '분석 오류', 'type' => 'danger'];
    if (empty($song['has_lyrics_text'])) $badges[] = ['text' => '가사 없음', 'type' => 'danger'];
    if (in_array((string)($song['metadata_source'] ?? ''), ['filename', 'mixed', 'unknown'], true)) $badges[] = ['text' => 'fallback', 'type' => 'info'];
    if (metadataLooksBroken($song)) $badges[] = ['text' => '한글 깨짐 의심', 'type' => 'warning'];
    if (!empty($song['duplicate_candidate'])) $badges[] = ['text' => '중복 후보', 'type' => 'warning'];
    if (!empty($song['is_manual_edited'])) $badges[] = ['text' => '수동 보호', 'type' => 'success'];
    if (!empty($song['is_missing'])) $badges[] = ['text' => '파일 없음', 'type' => 'danger'];
    return $badges;
}

renderHeader('메타데이터 품질 관리', 'metadata_quality');
?>
<div class="admin-dashboard metadata-quality-page">
    <div class="page-title-section">
        <h1 class="page-main-title">메타데이터 품질 관리</h1>
        <p class="page-subtitle">누락, fallback, 분석 오류, 한글 깨짐 의심, 중복 후보를 확인하고 안전하게 수동 보정합니다.</p>
    </div>

    <section class="home-section metadata-quality-filter-section">
        <form method="GET" class="settings-form compact-filter-form">
            <div class="form-row">
                <div class="form-group">
                    <label for="filter">품질 필터</label>
                    <select id="filter" name="filter">
                        <?php foreach ($qualityFilters as $key => $row): ?>
                            <option value="<?php echo h($key); ?>" <?php echo $filter === $key ? 'selected' : ''; ?>><?php echo h($row['label']); ?></option>
                        <?php endforeach; ?>
                    </select>
                </div>
                <div class="form-group">
                    <label for="q">검색</label>
                    <input id="q" type="search" name="q" value="<?php echo h($q); ?>" placeholder="제목, 가수, 앨범, 장르">
                </div>
                <div class="form-group">
                    <label for="sort">정렬</label>
                    <select id="sort" name="sort">
                        <option value="recent" <?php echo $sort === 'recent' ? 'selected' : ''; ?>>최근 등록순</option>
                        <option value="scan" <?php echo $sort === 'scan' ? 'selected' : ''; ?>>최근 스캔순</option>
                        <option value="updated" <?php echo $sort === 'updated' ? 'selected' : ''; ?>>최근 수정순</option>
                        <option value="title" <?php echo $sort === 'title' ? 'selected' : ''; ?>>제목순</option>
                        <option value="artist" <?php echo $sort === 'artist' ? 'selected' : ''; ?>>가수순</option>
                    </select>
                </div>
                <div class="form-group form-group-actions">
                    <button class="btn btn-secondary" type="submit"><i class="fa-solid fa-filter"></i> 적용</button>
                </div>
            </div>
        </form>
        <div class="filter-tabs metadata-filter-tabs">
            <?php foreach ($qualityFilters as $key => $row): ?>
                <a class="filter-tab <?php echo $filter === $key ? 'active' : ''; ?>" href="<?php echo h(metadataQualityUrl(['filter' => $key, 'page' => 1])); ?>"><?php echo h($row['label']); ?></a>
            <?php endforeach; ?>
        </div>
    </section>

    <section class="home-section metadata-quality-results">
        <div class="section-heading-row">
            <div>
                <h2 class="section-title"><?php echo h($qualityFilters[$filter]['label']); ?> 목록</h2>
                <p class="section-subtitle">필요한 곡만 선택해 재분석하거나 수동으로 보정합니다.</p>
            </div>
            <span class="metadata-result-count"><?php echo number_format($total); ?>곡 · <?php echo number_format($page); ?>/<?php echo number_format($pages); ?> 페이지</span>
        </div>

        <form action="metadata_action.php" method="POST" id="metadata-quality-bulk-form">
            <?php echo csrfInput(); ?>
        </form>
        <div class="metadata-bulk-actions">
            <button form="metadata-quality-bulk-form" name="action" value="reanalyze_selected" class="btn btn-secondary btn-sm" onclick="return confirm('선택한 곡을 재분석할까요? 수동 보호 곡은 기본 메타데이터를 덮어쓰지 않습니다.');">선택 재분석</button>
            <a class="btn btn-secondary btn-sm" href="duplicates.php">중복 후보 상세 보기</a>
            <a class="btn btn-secondary btn-sm" href="metadata.php">기존 메타데이터 관리</a>
        </div>

        <?php if (empty($songs)): ?>
            <p class="empty-text">표시할 품질 이슈가 없습니다.</p>
        <?php else: ?>
            <div class="metadata-card-list metadata-quality-card-list">
                <?php foreach ($songs as $song): ?>
                    <?php $badges = metadataIssueBadges($song); ?>
                    <article class="metadata-mobile-card metadata-quality-card">
                        <div class="metadata-quality-card-head">
                            <label class="metadata-card-check">
                                <input form="metadata-quality-bulk-form" type="checkbox" name="song_ids[]" value="<?php echo h($song['id']); ?>">
                                <span>선택</span>
                            </label>
                            <span class="metadata-card-id">#<?php echo h($song['id']); ?></span>
                        </div>
                        <strong><?php echo h(metaValue($song['title'], '제목 없음')); ?></strong>
                        <span><?php echo h(artistName($song['artist'] ?? '')); ?> · <?php echo h(albumName($song['album'] ?? '')); ?></span>
                        <small><?php echo h(genreName($song['genre'] ?? '')); ?> · <?php echo h(metaValue($song['year'] ?? '', '연도 없음')); ?> · <?php echo h(formatDuration($song['duration'] ?? null)); ?></small>
                        <small><?php echo h(metaValue($song['metadata_source'], 'unknown')); ?> · 스캔 <?php echo h($song['last_metadata_scan_at'] ?: '-'); ?></small>
                        <div class="metadata-badge-row">
                            <?php foreach ($badges as $badge): ?>
                                <span class="metadata-badge badge-<?php echo h($badge['type']); ?>"><?php echo h($badge['text']); ?></span>
                            <?php endforeach; ?>
                        </div>
                        <?php if (!empty($song['metadata_error'])): ?><p class="metadata-error"><?php echo h($song['metadata_error']); ?></p><?php endif; ?>
                        <div class="song-action-group">
                            <a class="btn btn-secondary btn-sm" href="../song_edit.php?id=<?php echo h($song['id']); ?>">수정</a>
                            <a class="btn btn-secondary btn-sm" href="../lyrics_edit.php?song_id=<?php echo h($song['id']); ?>">가사</a>
                            <form action="metadata_action.php" method="POST" class="inline-action-form">
                                <?php echo csrfInput(); ?>
                                <input type="hidden" name="song_id" value="<?php echo h($song['id']); ?>">
                                <button name="action" value="reanalyze_one" class="btn btn-secondary btn-sm">재분석</button>
                            </form>
                        </div>
                    </article>
                <?php endforeach; ?>
            </div>

            <?php renderSimplePager($page, $pages, '메타데이터 품질 페이지'); ?>
        <?php endif; ?>
    </section>
</div>
<?php renderFooter(); ?>
