<?php
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/functions.php';

function ensureTagTables() {
    static $done = false;
    if ($done) return;
    $pdo = getDBConnection();
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS tags (
            id INT AUTO_INCREMENT PRIMARY KEY,
            name VARCHAR(100) NOT NULL,
            normalized_name VARCHAR(120) NOT NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            UNIQUE KEY uniq_normalized_name (normalized_name),
            INDEX idx_name (name)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
    ");
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS song_tags (
            id INT AUTO_INCREMENT PRIMARY KEY,
            song_id INT NOT NULL,
            tag_id INT NOT NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            UNIQUE KEY uniq_song_tag (song_id, tag_id),
            INDEX idx_song_id (song_id),
            INDEX idx_tag_id (tag_id)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
    ");
    $done = true;
}

function normalizeTagName($name) {
    $name = trim(preg_replace('/\s+/u', ' ', (string)$name));
    if (function_exists('mb_strtolower')) {
        return mb_strtolower($name, 'UTF-8');
    }
    return strtolower($name);
}

function cleanTagName($name) {
    $name = trim(preg_replace('/\s+/u', ' ', (string)$name));
    if (function_exists('mb_substr')) return mb_substr($name, 0, 100, 'UTF-8');
    return substr($name, 0, 100);
}

function getOrCreateTag($name) {
    ensureTagTables();
    $pdo = getDBConnection();
    $clean = cleanTagName($name);
    $normalized = normalizeTagName($clean);
    if ($clean === '' || $normalized === '') return 0;

    $stmt = $pdo->prepare("SELECT id FROM tags WHERE normalized_name = :normalized");
    $stmt->execute([':normalized' => $normalized]);
    $id = (int)$stmt->fetchColumn();
    if ($id > 0) return $id;

    $insert = $pdo->prepare("INSERT INTO tags (name, normalized_name) VALUES (:name, :normalized)");
    $insert->execute([':name' => $clean, ':normalized' => $normalized]);
    return (int)$pdo->lastInsertId();
}

function getPopularTags($limit = 30) {
    ensureTagTables();
    $pdo = getDBConnection();
    $limit = max(1, min(100, (int)$limit));
    $stmt = $pdo->prepare("
        SELECT t.id, t.name, COUNT(st.id) AS song_count
        FROM tags t
        LEFT JOIN song_tags st ON st.tag_id = t.id
        GROUP BY t.id, t.name
        ORDER BY song_count DESC, t.name ASC
        LIMIT $limit
    ");
    $stmt->execute();
    return $stmt->fetchAll();
}

function getSongTags($songId) {
    ensureTagTables();
    $pdo = getDBConnection();
    $stmt = $pdo->prepare("
        SELECT t.id, t.name
        FROM song_tags st
        INNER JOIN tags t ON t.id = st.tag_id
        WHERE st.song_id = :song_id
        ORDER BY t.name ASC
    ");
    $stmt->execute([':song_id' => (int)$songId]);
    return $stmt->fetchAll();
}

function addTagToSong($songId, $tagName) {
    ensureTagTables();
    $tagId = getOrCreateTag($tagName);
    if ($tagId <= 0 || (int)$songId <= 0) return false;
    $pdo = getDBConnection();
    $stmt = $pdo->prepare("INSERT IGNORE INTO song_tags (song_id, tag_id) VALUES (:song_id, :tag_id)");
    $stmt->execute([':song_id' => (int)$songId, ':tag_id' => $tagId]);
    return true;
}

function removeTagFromSong($songId, $tagId) {
    ensureTagTables();
    $pdo = getDBConnection();
    $stmt = $pdo->prepare("DELETE FROM song_tags WHERE song_id = :song_id AND tag_id = :tag_id");
    $stmt->execute([':song_id' => (int)$songId, ':tag_id' => (int)$tagId]);
    return $stmt->rowCount() > 0;
}

function songsByTag($tagId, $limit = 200) {
    ensureTagTables();
    $pdo = getDBConnection();
    $limit = max(1, min(500, (int)$limit));
    $stmt = $pdo->prepare("
        SELECT s.id, s.title, s.artist, s.album, s.genre, s.duration, s.extension, s.play_count,
               IF(l.id IS NOT NULL, 1, 0) AS is_liked
        FROM song_tags st
        INNER JOIN songs s ON s.id = st.song_id
        LEFT JOIN liked_songs l ON l.song_id = s.id
        WHERE st.tag_id = :tag_id AND COALESCE(s.is_missing, 0) = 0
        ORDER BY s.title ASC
        LIMIT $limit
    ");
    $stmt->execute([':tag_id' => (int)$tagId]);
    return $stmt->fetchAll();
}

function tagInfo($tagId) {
    ensureTagTables();
    $pdo = getDBConnection();
    $stmt = $pdo->prepare("SELECT * FROM tags WHERE id = :id");
    $stmt->execute([':id' => (int)$tagId]);
    return $stmt->fetch();
}

function renderTagBadges($tags, $basePath = './', $editableSongId = null) {
    if (empty($tags)) {
        echo '<span class="tag-empty">태그 없음</span>';
        return;
    }
    foreach ($tags as $tag) {
        echo '<a class="tag-badge" href="' . h($basePath . 'tag.php?id=' . (int)$tag['id']) . '">' . h($tag['name']) . '</a>';
        if ($editableSongId !== null) {
            echo '<button type="button" class="tag-remove-btn" data-song-id="' . h($editableSongId) . '" data-tag-id="' . h($tag['id']) . '" title="태그 제거">×</button>';
        }
    }
}

function smartMetadataSuggestion($song) {
    $title = trim((string)($song['title'] ?? ''));
    $file = basename((string)($song['relative_path'] ?? $song['file_path'] ?? ''));
    $file = preg_replace('/\.[^.]+$/', '', $file);
    $file = preg_replace('/^\s*\d+[\.\-\s_]+/u', '', $file);
    $file = trim(str_replace('_', ' ', $file));
    $parts = preg_split('/\s+-\s+/u', $file);
    $suggest = ['title' => $title, 'artist' => trim((string)($song['artist'] ?? '')), 'album' => trim((string)($song['album'] ?? ''))];
    if (count($parts) >= 2) {
        $suggest['artist'] = $suggest['artist'] ?: trim($parts[0]);
        $suggest['title'] = $title ?: trim(end($parts));
        if (count($parts) >= 3) $suggest['album'] = $suggest['album'] ?: trim($parts[1]);
    } elseif ($title === '' && $file !== '') {
        $suggest['title'] = $file;
    }
    if ($suggest['album'] === '' && !empty($song['folder_name'])) $suggest['album'] = trim((string)$song['folder_name']);
    return $suggest;
}
