<?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/functions_search.php';
require_once dirname(__DIR__) . '/includes/api.php';

ini_set('display_errors', 0);
header('Content-Type: application/json; charset=utf-8');

function searchSuggestTableExists(PDO $pdo, string $table): bool {
    $stmt = $pdo->prepare("
        SELECT COUNT(*)
        FROM information_schema.tables
        WHERE table_schema = DATABASE() AND table_name = :table_name
    ");
    $stmt->execute([':table_name' => $table]);
    return (int)$stmt->fetchColumn() > 0;
}

function searchSuggestMinimumLength(string $query): int {
    return preg_match('/[ㄱ-ㅎㅏ-ㅣ가-힣]/u', $query) === 1 ? 1 : 2;
}

try {
    $query = normalizeSearchQuery($_GET['q'] ?? '');
    $queryLength = function_exists('mb_strlen') ? mb_strlen($query, 'UTF-8') : strlen($query);
    if ($queryLength < searchSuggestMinimumLength($query)) {
        apiSuccess(['query' => $query, 'items' => []], '', ['count' => 0], ['query' => $query, 'items' => []]);
    }

    $pdo = getDBConnection();
    $like = '%' . $query . '%';
    $items = [];

    $stmt = $pdo->prepare("
        SELECT id, title, artist, album, duration, cover_hash, metadata_updated_at, updated_at
        FROM songs
        WHERE COALESCE(is_missing, 0) = 0 AND COALESCE(is_hidden, 0) = 0
          AND (title LIKE :song_title OR artist LIKE :song_artist OR album LIKE :song_album OR genre LIKE :song_genre)
        ORDER BY play_count DESC, title ASC
        LIMIT 8
    ");
    $stmt->execute([
        ':song_title' => $like,
        ':song_artist' => $like,
        ':song_album' => $like,
        ':song_genre' => $like,
    ]);
    foreach ($stmt->fetchAll() as $row) {
        $id = (int)$row['id'];
        $items[] = [
            'type' => 'song',
            'label' => ensureUtf8String($row['title'] ?? ''),
            'sub' => artistName($row['artist'] ?? '') . (($row['album'] ?? '') ? ' · ' . albumName($row['album']) : ''),
            'url' => 'song.php?id=' . $id,
            'play_id' => $id,
            'song_id' => $id,
            'title' => ensureUtf8String($row['title'] ?? ''),
            'artist' => artistName($row['artist'] ?? ''),
            'album' => albumName($row['album'] ?? ''),
            'duration' => (int)($row['duration'] ?? 0),
            'cover_url' => coverUrl($row),
            'stream_url' => 'stream.php?id=' . $id,
        ];
    }

    $stmt = $pdo->prepare("
        SELECT COALESCE(NULLIF(TRIM(artist), ''), '알 수 없는 아티스트') AS artist_name, COUNT(*) AS song_count
        FROM songs
        WHERE COALESCE(is_missing, 0) = 0 AND COALESCE(is_hidden, 0) = 0 AND artist LIKE :artist
        GROUP BY artist_name
        ORDER BY song_count DESC, artist_name ASC
        LIMIT 5
    ");
    $stmt->execute([':artist' => $like]);
    foreach ($stmt->fetchAll() as $row) {
        $artist = ensureUtf8String($row['artist_name'] ?? '');
        $items[] = [
            'type' => 'artist',
            'label' => $artist,
            'sub' => number_format((int)$row['song_count']) . '곡',
            'url' => 'artist.php?name=' . urlencode($artist),
        ];
    }

    $stmt = $pdo->prepare("
        SELECT COALESCE(NULLIF(TRIM(album), ''), '알 수 없는 앨범') AS album_name,
               COALESCE(NULLIF(TRIM(artist), ''), '알 수 없는 아티스트') AS artist_name,
               COUNT(*) AS song_count
        FROM songs
        WHERE COALESCE(is_missing, 0) = 0 AND COALESCE(is_hidden, 0) = 0
          AND (album LIKE :album OR artist LIKE :album_artist)
        GROUP BY album_name, artist_name
        ORDER BY song_count DESC, album_name ASC
        LIMIT 5
    ");
    $stmt->execute([':album' => $like, ':album_artist' => $like]);
    foreach ($stmt->fetchAll() as $row) {
        $album = ensureUtf8String($row['album_name'] ?? '');
        $artist = ensureUtf8String($row['artist_name'] ?? '');
        $items[] = [
            'type' => 'album',
            'label' => $album,
            'sub' => $artist . ' · ' . number_format((int)$row['song_count']) . '곡',
            'url' => 'album.php?album=' . urlencode($album) . '&artist=' . urlencode($artist),
        ];
    }

    if (searchSuggestTableExists($pdo, 'tags') && searchSuggestTableExists($pdo, 'song_tags')) {
        $stmt = $pdo->prepare("
            SELECT t.id, t.name, COUNT(st.song_id) AS song_count
            FROM tags t
            LEFT JOIN song_tags st ON st.tag_id = t.id
            WHERE t.name LIKE :tag_name
            GROUP BY t.id, t.name
            ORDER BY song_count DESC, t.name ASC
            LIMIT 5
        ");
        $stmt->execute([':tag_name' => $like]);
        foreach ($stmt->fetchAll() as $row) {
            $tagName = ensureUtf8String($row['name'] ?? '');
            $items[] = [
                'type' => 'tag',
                'label' => $tagName,
                'sub' => number_format((int)$row['song_count']) . '곡',
                'url' => 'tags.php?tag=' . urlencode($tagName),
                'tag_id' => (int)$row['id'],
            ];
        }
    }

    $stmt = $pdo->prepare("
        SELECT p.id, p.name, COUNT(ps.id) AS song_count
        FROM playlists p
        LEFT JOIN playlist_songs ps ON ps.playlist_id = p.id
        WHERE COALESCE(p.display_scope, 'private') != 'hidden'
          AND (p.name LIKE :playlist_name OR p.description LIKE :playlist_desc)
        GROUP BY p.id, p.name, p.display_scope
        ORDER BY (p.display_scope = 'home') DESC, p.name ASC
        LIMIT 5
    ");
    $stmt->execute([':playlist_name' => $like, ':playlist_desc' => $like]);
    foreach ($stmt->fetchAll() as $row) {
        $items[] = [
            'type' => 'playlist',
            'label' => ensureUtf8String($row['name'] ?? ''),
            'sub' => number_format((int)$row['song_count']) . '곡',
            'url' => 'playlist_view.php?id=' . (int)$row['id'],
        ];
    }

    $items = array_slice($items, 0, 20);
    apiSuccess(['query' => $query, 'items' => $items], '', ['count' => count($items)], ['query' => $query, 'items' => $items]);
} catch (Throwable $e) {
    if (function_exists('writeAppLog')) writeAppLog('error', 'search_error', 'Search suggest failed', ['error' => $e->getMessage()]);
    apiError('검색 제안을 불러오지 못했습니다.', 'server_error', 500);
}
