#!/usr/bin/env python3
"""
SUNO AI ML MUSIC SEARCH DEMO
User: valkst
Date: 2025-08-02 11:18:00 UTC
Complete ML system demonstration
"""

import sqlite3
import numpy as np
import pickle
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
import pandas as pd

class SunoMLDemo:
    def __init__(self):
        self.db_path = "tracks.sqlite"
        self.model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
        print("🎵 SUNO AI ML MUSIC SEARCH SYSTEM DEMO")
        print("="*50)
        
    def semantic_search(self, query, limit=10):
        """Семантический поиск по запросу"""
        print(f"🔍 Поиск: '{query}'")
        
        # Создаем вектор запроса
        query_vector = self.model.encode([query], normalize_embeddings=True)
        
        # Получаем все векторы из базы
        conn = sqlite3.connect(self.db_path)
        
        # Получаем треки с векторами
        cursor = conn.execute("""
        SELECT t.id, t.title, t.artist, emb.embedding_vector,
               ml.ml_emotion_dominant, ml.ml_emotion_confidence
        FROM tracks t
        JOIN ml_embeddings emb ON t.id = emb.track_id
        JOIN ml_analysis ml ON t.id = ml.track_id
        ORDER BY t.quality_score DESC
        LIMIT 1000
        """)
        
        results = []
        for row in cursor.fetchall():
            track_id, title, artist, vector_blob, emotion, emotion_conf = row
            vector = pickle.loads(vector_blob)
            
            # Вычисляем similarity
            similarity = cosine_similarity(query_vector, vector.reshape(1, -1))[0][0]
            
            results.append({
                'id': track_id,
                'title': title,
                'artist': artist,
                'similarity': similarity,
                'emotion': emotion,
                'emotion_confidence': emotion_conf
            })
        
        conn.close()
        
        # Сортируем по similarity
        results.sort(key=lambda x: x['similarity'], reverse=True)
        
        print(f"📊 Найдено {len(results)} треков, показываем топ-{limit}:")
        print("-" * 80)
        
        for i, result in enumerate(results[:limit], 1):
            emotion_icon = {'joy': '😊', 'sadness': '😢', 'anger': '😡', 
                          'fear': '😨', 'disgust': '🤢', 'surprise': '😮'}.get(result['emotion'], '🎵')
            
            print(f"{i:2d}. {result['title']}")
            print(f"    👤 {result['artist']}")
            print(f"    🎯 Similarity: {result['similarity']:.3f}")
            print(f"    {emotion_icon} {result['emotion'].title()} ({result['emotion_confidence']:.2f})")
            print()
            
        return results[:limit]
        
    def emotion_filter(self, emotion, limit=15):
        """Фильтр по эмоции"""
        emotions_dict = {
            'радость': 'joy', 'грусть': 'sadness', 'гнев': 'anger',
            'страх': 'fear', 'отвращение': 'disgust', 'удивление': 'surprise',
            'joy': 'joy', 'sadness': 'sadness', 'anger': 'anger',
            'fear': 'fear', 'disgust': 'disgust', 'surprise': 'surprise'
        }
        
        emotion_en = emotions_dict.get(emotion.lower(), emotion.lower())
        
        conn = sqlite3.connect(self.db_path)
        
        cursor = conn.execute("""
        SELECT t.title, t.artist, ml.ml_emotion_confidence, t.quality_score
        FROM tracks t
        JOIN ml_analysis ml ON t.id = ml.track_id
        WHERE ml.ml_emotion_dominant = ?
        ORDER BY ml.ml_emotion_confidence DESC, t.quality_score DESC
        LIMIT ?
        """, (emotion_en, limit))
        
        results = cursor.fetchall()
        conn.close()
        
        emotion_icon = {'joy': '😊', 'sadness': '😢', 'anger': '😡', 
                       'fear': '😨', 'disgust': '🤢', 'surprise': '😮'}.get(emotion_en, '🎵')
        
        print(f"{emotion_icon} Треки с эмоцией '{emotion.title()}':")
        print("-" * 60)
        
        for i, (title, artist, conf, quality) in enumerate(results, 1):
            print(f"{i:2d}. {title}")
            print(f"    👤 {artist}")
            print(f"    🎯 Уверенность: {conf:.3f}, Качество: {quality:.3f}")
            print()
            
        return results
        
    def cluster_analysis(self):
        """Анализ кластеров"""
        conn = sqlite3.connect(self.db_path)
        
        cursor = conn.execute("""
        SELECT 
            ml.semantic_cluster,
            COUNT(*) as track_count,
            AVG(ml.cluster_confidence) as avg_confidence,
            ml.ml_emotion_dominant as dominant_emotion,
            COUNT(CASE WHEN ml.ml_emotion_dominant = 'joy' THEN 1 END) as joy_count,
            COUNT(CASE WHEN ml.ml_emotion_dominant = 'sadness' THEN 1 END) as sad_count
        FROM ml_analysis ml
        WHERE ml.semantic_cluster >= 0
        GROUP BY ml.semantic_cluster, ml.ml_emotion_dominant
        ORDER BY track_count DESC
        """)
        
        clusters_data = {}
        for row in cursor.fetchall():
            cluster_id, count, conf, emotion, joy, sad = row
            if cluster_id not in clusters_data:
                clusters_data[cluster_id] = {
                    'total_tracks': 0,
                    'avg_confidence': conf,
                    'emotions': {}
                }
            clusters_data[cluster_id]['total_tracks'] += count
            clusters_data[cluster_id]['emotions'][emotion] = count
            
        conn.close()
        
        print("🔍 АНАЛИЗ СЕМАНТИЧЕСКИХ КЛАСТЕРОВ:")
        print("=" * 50)
        
        for cluster_id, data in sorted(clusters_data.items(), 
                                     key=lambda x: x[1]['total_tracks'], reverse=True):
            dominant_emotion = max(data['emotions'].items(), key=lambda x: x[1])
            emotion_icon = {'joy': '😊', 'sadness': '😢', 'anger': '😡', 
                          'fear': '😨', 'disgust': '🤢', 'surprise': '😮'}.get(dominant_emotion[0], '🎵')
            
            print(f"🔸 Кластер {cluster_id}: {data['total_tracks']} треков")
            print(f"   {emotion_icon} Доминирующая эмоция: {dominant_emotion[0]} ({dominant_emotion[1]} треков)")
            print(f"   🎯 Уверенность: {data['avg_confidence']:.3f}")
            print()
            
    def statistics_overview(self):
        """Общая статистика"""
        conn = sqlite3.connect(self.db_path)
        
        # Основная статистика
        cursor = conn.execute("""
        SELECT 
            COUNT(*) as total_tracks,
            AVG(ml_emotion_confidence) as avg_emotion_conf,
            AVG(cluster_confidence) as avg_cluster_conf,
            COUNT(CASE WHEN ml_emotion_confidence > 0.8 THEN 1 END) as high_conf_tracks
        FROM ml_analysis
        """)
        
        stats = cursor.fetchone()
        total, avg_emotion, avg_cluster, high_conf = stats
        
        print("📈 ОБЩАЯ СТАТИСТИКА ML СИСТЕМЫ:")
        print("=" * 40)
        print(f"🎵 Всего треков: {total:,}")
        print(f"🎭 Средняя эмоциональная уверенность: {avg_emotion:.3f}")
        print(f"🔍 Средняя кластерная уверенность: {avg_cluster:.3f}")
        print(f"🏆 Треков с высокой уверенностью: {high_conf:,} ({high_conf/total*100:.1f}%)")
        print()
        
        # Топ исполнители по количеству треков
        cursor = conn.execute("""
        SELECT t.artist, COUNT(*) as track_count
        FROM tracks t
        JOIN ml_analysis ml ON t.id = ml.track_id
        GROUP BY t.artist
        ORDER BY track_count DESC
        LIMIT 10
        """)
        
        print("🎤 ТОП-10 ИСПОЛНИТЕЛЕЙ:")
        print("-" * 30)
        for i, (artist, count) in enumerate(cursor.fetchall(), 1):
            print(f"{i:2d}. {artist}: {count} треков")
        
        conn.close()

def main():
    demo = SunoMLDemo()
    
    print("""
Доступные команды:
1. demo.semantic_search("запрос") - семантический поиск
2. demo.emotion_filter("радость") - фильтр по эмоции  
3. demo.cluster_analysis() - анализ кластеров
4. demo.statistics_overview() - общая статистика

Примеры:
demo.semantic_search("love song about heartbreak")
demo.emotion_filter("грусть")
    """)
    
    return demo

if __name__ == "__main__":
    demo = main()
