﻿import { useEffect, useState, useRef, useMemo, useCallback } from "react";
import axios from "axios";
import { API_BASE } from "../utils/apiBase";
import {
  Box,
  Typography,
  Card,
  CardMedia,
  CardContent,
  IconButton,
  Button,
  CircularProgress,
  Skeleton
} from "@mui/material";
import { useNavigate, useLocation } from "react-router-dom";
import { ChevronLeft, ChevronRight, WhatsApp } from "@mui/icons-material";
import LazyImage from "../components/LazyImage";
import slugify, { slugifyNav } from "../utils/slugify";
import getArtistImage from "../utils/getArtistImage";
import agruparArtistas from "../utils/groupArtists";
import ScrollToTop from "../components/ScrollToTop";
import getMusicTitle from "../utils/getMusicTitle";
import getArtistNames from "../utils/getArtistNames";
import normalizeForSearch, { fuzzyMatch } from "../utils/normalizeForSearch";
import { getKV, setKV } from "../utils/db";
import { buildMusicIndex, searchMusic, getMusicIndex } from "../utils/flexIndex";
import { trackMusicViewOnServer, cacheServerRanking } from "../utils/serverMusicRanking";
import { getTopViewedMusic } from "../utils/trackMusicView";
import { useMusicCache } from "../contexts/CacheContext";
import Busca from "../components/Busca";
import ListaItemModern from "../components/ListaItemModern";
import openMusic from "../utils/openMusic";
import normalizeTrackNumber from "../utils/trackNumber";

// Extrair apenas o artista principal, removendo participações/colaborações
const extrairArtistaPrincipal = (nomeCompleto) => {
  if (!nomeCompleto) return nomeCompleto;
  const match = String(nomeCompleto).split(/\s*(?:\bpart\.?|\bft\.?|\bfeat\.?|\bfeaturing\b|\bcom\b|\bwith\b|&)\s*/i)[0];
  return match ? match.trim() : nomeCompleto;
};

export default function Home({ busca, setBusca, filtro, setFiltro }) {
  const [novas, setNovas] = useState([]);
  const [maisBuscadas, setMaisBuscadas] = useState([]);
  const [todasMusicas, setTodasMusicas] = useState([]);
  const [imagensArtistas, setImagensArtistas] = useState({});
  const [artistasAgrupados, setArtistasAgrupados] = useState([]);
  const [artistasFiltrados, setArtistasFiltrados] = useState([]);
  const [topArtistas, setTopArtistas] = useState([]);
  const [topArtistasImgs, setTopArtistasImgs] = useState({});
  const [carregando, setCarregando] = useState(true);
  const [itensMostrados, setItensMostrados] = useState(15);
  // Estados para controle de busca bloqueada
  const [buscaBloqueada, setBuscaBloqueada] = useState(true);
  const navigate = useNavigate();
  const location = useLocation();
  // location from react-router
  useEffect(() => {
    console.log('[Home] location.pathname ->', location.pathname);
    // When leaving Home, reset transient search UI to match Artistas logic
    if (location.pathname && location.pathname !== '/' && !location.pathname.startsWith('/musica')) {
      try { setBusca(''); } catch (e) { /* ignore if prop missing */ }
      try { setFiltro('todos'); } catch (e) { /* ignore if prop missing */ }
      setMusicasFiltradas([]);
      setArtistasFiltrados([]);
      setItensMostrados(15);
      // hide the home loading overlay if present
      if (typeof window !== 'undefined' && window.__hideHomeLoadingOverlay) window.__hideHomeLoadingOverlay();
      // Also force hide the overlay element directly
      try {
        const overlay = document.getElementById('home-loading-overlay');
        if (overlay) {
          overlay.style.display = 'none';
          console.log('[Home] Force hid home-loading-overlay on route change');
        }
      } catch (e) { /* ignore */ }
    }
    // eslint-disable-next-line
  }, [location.pathname]);

  // Force hide overlay when component unmounts or when not on home route
  useEffect(() => {
    if (location.pathname !== '/') {
      try {
        const overlay = document.getElementById('home-loading-overlay');
        if (overlay) {
          overlay.style.display = 'none';
          console.log('[Home] Force hid overlay - not on home route');
        }
        // Also ensure carregando is false when leaving home
        setCarregando(false);
        console.log('[Home] Set carregando to false when leaving home');
      } catch (e) { /* ignore */ }
    }
    return () => {
      // Cleanup on unmount
      try {
        const overlay = document.getElementById('home-loading-overlay');
        if (overlay) {
          overlay.style.display = 'none';
          console.log('[Home] Force hid overlay on Home unmount');
        }
        setCarregando(false);
      } catch (e) { /* ignore */ }
    };
  }, [location.pathname]);
  const carouselRef = useRef(null);
  const carouselMaisBuscadasRef = useRef(null);
  const observerTarget = useRef(null);
  const { getCachedData, setCachedMusicData } = useMusicCache();

  // Usar util comum para normalização (remove acentos, normaliza espaços, lowercase)
  const normalizar = normalizeForSearch;

  // Limpar nome de artista para remover participações/feat/etc e conteúdo entre parênteses
  const limparNomeArtista = (nome) => {
    if (!nome || typeof nome !== 'string') return '';
    // remover conteúdo entre parênteses/colchetes
    let s = nome.replace(/\([^)]*\)|\[[^\]]*\]/g, '');
    // normalizar espaços
    s = s.replace(/\s+/g, ' ').trim();
    // tokens que representam participações
    const tokens = [' feat ', ' ft ', ' featuring ', ' with ', ' part ', ' participa', ' participação ', ' feat.', ' ft.'];
    const low = s.toLowerCase();
    for (const t of tokens) {
      const idx = low.indexOf(t.trim());
      if (idx !== -1) {
        return s.slice(0, idx).trim();
      }
    }
    // também tratar ' - ' seguido de outro artista (ex.: "Artist A - Artist B") conservadoramente
    // somente cortar se houver muitos ' - ' ou se faixa parecer dupla/colaboração; evitar falsos positivos
    return s;
  };

  useEffect(() => {
    const CACHE_KEY = "home_carousel_cache_v6"; // v6 - corrigido fallback de novidades
    const CACHE_DURATION = 60 * 60 * 1000; // 1 hora em milissegundos

    const carregarDados = async () => {
      setBuscaBloqueada(true);
      // Se já tem dados carregados, não recarregar
      // Se já tem dados carregados, não recarregar
      if (novas.length > 0 && todasMusicas.length > 0) {
        console.log("⚡ Dados já carregados nesta sessão, pulando...");
        setCarregando(false);
        setBuscaBloqueada(false);
        return;
      }

      // Tentar buscar do cache em memória PRIMEIRO
      const cacheMemoria = getCachedData();
      if (cacheMemoria && cacheMemoria.todasMusicas) {
        console.log("⚡ Usando cache em memória");
        setNovas(cacheMemoria.novas);
        setTodasMusicas(cacheMemoria.todasMusicas);
        // Não restaurar artistasAgrupados - será carregado lazy quando necessário
        
        const topViewedIds = getTopViewedMusic(20);
        let maisBuscadasList;
        if (topViewedIds.length > 0) {
          maisBuscadasList = topViewedIds
            .map(id => cacheMemoria.todasMusicas.find(m => String(m.numero) === String(id)))
            .filter(Boolean);
        } else {
          maisBuscadasList = cacheMemoria.todasMusicas.filter((m) => m.novas !== true).slice(-20).reverse();
        }
        setMaisBuscadas(maisBuscadasList);
        setCarregando(false);
        setBuscaBloqueada(false);
        return;
      }

      // Tentar ler cache mínimo do IndexedDB (stale-while-revalidate)
      try {
        const idbKey = 'musicas_min_v1';
        const idbCached = await getKV(idbKey);
        if (idbCached && Array.isArray(idbCached) && idbCached.length > 0) {
          console.log('⚡ Usando cache IndexedDB (musicas_min_v1) para inicial render');
          setTodasMusicas(idbCached);
          // Construir índice a partir do cache rapidamente
          try { buildMusicIndex(idbCached); } catch (e) { /* ignore */ }

          // Carrossel baseado em campo 'novas'
          let idbMaisNovas = idbCached.filter(m => m.novas === true || m.nova === true);
          if (idbMaisNovas.length === 0) {
            const isMobile = window.innerWidth < 768;
            const limit = isMobile ? 30 : 60;
            idbMaisNovas = [...idbCached].sort((a,b) => (parseInt(b.numero)||0) - (parseInt(a.numero)||0)).slice(0, limit);
          }
          setNovas(idbMaisNovas);

          const topViewedIds = getTopViewedMusic(20);
          let maisBuscadasList;
          if (topViewedIds.length > 0) {
            maisBuscadasList = topViewedIds
              .map(id => idbCached.find(m => String(m.numero) === String(id)))
              .filter(Boolean);
          } else {
            maisBuscadasList = idbCached.filter((m) => m.novas !== true).slice(-20).reverse();
          }
          setMaisBuscadas(maisBuscadasList);
          setCarregando(false);
          setBuscaBloqueada(false);
          // continue to fetch in background to update cache
        }
      } catch (e) {
        console.warn('⚠️ Erro lendo IndexedDB cache:', e);
      }
      
      // Limpar caches antigos
      localStorage.removeItem('home_carousel_cache');
      localStorage.removeItem('home_carousel_cache_v2');
      localStorage.removeItem('home_carousel_cache_v3');
      localStorage.removeItem('home_carousel_cache_v4');
      localStorage.removeItem('home_carousel_cache_v5');
      
      // Sempre verificar views primeiro
      const viewsAtual = localStorage.getItem('music_views');
    
    // Tentar buscar do localStorage como fallback
    const cacheStr = localStorage.getItem(CACHE_KEY);
    let usarCache = false;
    
    if (cacheStr) {
      try {
        const cache = JSON.parse(cacheStr);
        const agora = Date.now();
        
        // Verificar se há novas visualizações desde o último cache
        const viewsCache = cache.views || null;
        const viewsMudaram = viewsAtual !== viewsCache;
        
        // Só usar cache se for válido E as views não mudaram
        const cacheValido = cache.timestamp && (agora - cache.timestamp) < CACHE_DURATION;
        usarCache = cacheValido && !viewsMudaram;
        
        if (usarCache) {
          console.log("✅ Carregando Novidades do cache");
          setNovas(cache.novas);
          setTodasMusicas(cache.todasMusicas);
          setArtistasAgrupados(cache.artistasAgrupados);
          
          // MAS sempre buscar Mais Buscadas atualizado
          const topViewedIds = getTopViewedMusic(20);

          let maisBuscadasList;
          if (topViewedIds.length > 0) {
            maisBuscadasList = topViewedIds
              .map(id => cache.todasMusicas.find(m => String(m.numero) === String(id)))
              .filter(Boolean);
          } else {
            maisBuscadasList = cache.todasMusicas.filter((m) => m.novas !== true).slice(-20).reverse();
          }

          // Definir lista imediata a partir do cache (rápido)
          setMaisBuscadas(maisBuscadasList);

          // Em background, tentar obter ranking atualizado do servidor
          (async () => {
            try {
              const serverRanking = await cacheServerRanking(20);
              if (serverRanking && serverRanking.length > 0) {
                const serverList = serverRanking
                  .map(item => (cache.todasMusicas || []).find(m => String(m.numero) === String(item.numero)))
                  .filter(Boolean);
                if (serverList.length > 0) {
                  console.log('[Home] Atualizando Mais Buscadas com ranking do servidor');
                  setMaisBuscadas(serverList);
                }
              }
            } catch (e) {
              console.warn('[Home] Falha ao atualizar ranking do servidor em background:', e);
            }
          })();
          setCarregando(false);
          setBuscaBloqueada(false);
          return;
        }
      } catch (e) {
        console.log("⚠️ Erro ao processar cache:", e);
      }
    }

    // Buscar do backend se não tem cache ou está expirado
    console.log("🔄 Carregando músicas do backend...");
    axios
      .get(`${API_BASE}/musicas`)
      .then(async (res) => {
        // Normalize response shape
        let data = res && res.data ? res.data : [];
        if (!Array.isArray(data)) {
          if (Array.isArray(data.musicas)) data = data.musicas;
          else if (Array.isArray(data.data)) data = data.data;
          else {
            console.warn('[Home] unexpected /musicas response shape, falling back to empty array', data);
            data = [];
          }
        }

        console.log("✅ Músicas carregadas:", data.length);

        // Pré-computar campos normalizados para pesquisa para evitar normalizações repetidas
        const normed = data.map(m => {
          const title = (m.musica) ? m.musica : (m.titulo || '');
          const artistStr = getArtistNames(m) || m.cantor || '';
          const ritmosArr = Array.isArray(m.ritmos) ? m.ritmos : (m.ritmo ? [m.ritmo] : []);
          return {
            ...m,
            _normTitle: normalizeForSearch(title),
            _normArtists: normalizeForSearch(artistStr),
            _normRitmos: ritmosArr.map(r => normalizeForSearch(r || '')),
            _normNumero: String(m.numero || '')
          };
        });
        // Salvar para uso nas buscas sem recalcular normalização
        setTodasMusicas(normed);
        // Construir índice FlexSearch para buscas rápidas
        try {
          buildMusicIndex(normed);
        } catch (e) {
          console.warn('Não foi possível construir índice FlexSearch', e);
        }

        // Filtrar músicas com tag "Novo" (campo novas ou nova = true)
        // Usar a versão 'normed' (pré-computada com campos _norm*) para que o
        // carrossel e os filtros possam usar essas propriedades sem erro.
        let filtradas = normed.filter((m) => m.novas === true || m.nova === true);

        console.log("🔍 Total de músicas no backend:", data.length);
        console.log("🔍 Músicas com novas/nova=true:", filtradas.length);
        
        // Se não encontrar músicas novas, mostra as últimas 30-60 por número (menos no mobile)
        if (filtradas.length === 0) {
          const isMobile = window.innerWidth < 768;
          const limit = isMobile ? 30 : 60;
          console.log(`⚠️  Nenhuma música com campo 'novas', usando últimas ${limit} por número`);
          filtradas = [...normed]
            .sort((a, b) => {
              const numA = parseInt(a.numero) || 0;
              const numB = parseInt(b.numero) || 0;
              return numB - numA;
            })
            .slice(0, limit);
          console.log(`📋 Últimas ${limit} músicas selecionadas`);
          console.log("📋 Primeira:", filtradas[0]?.numero, filtradas[0]?.musica);
          console.log("📋 Última:", filtradas[filtradas.length-1]?.numero, filtradas[filtradas.length-1]?.musica);
        }

        console.log("🎵 Total para carrossel:", filtradas.length);

        // Não carregar imagens agora - deixar para lazy loading
        console.log("⚡ Setando músicas sem imagens (lazy loading)...");
        setNovas(filtradas);

        // Salvar no cache em memória E localStorage (usar 'normed' para todasMusicas)
        setCachedMusicData(normed, filtradas, []);
        // Persistir versão mínima normed no IndexedDB para boot rápido (stale-while-revalidate)
        try {
          const minimal = normed.map(m => ({ numero: m.numero, musica: m.musica, cantor: m.cantor, ritmos: m.ritmos || m.ritmo || [], novas: m.novas || m.nova || false, _normTitle: m._normTitle, _normArtists: m._normArtists, _normRitmos: m._normRitmos }));
          setKV('musicas_min_v1', minimal).catch(() => {});
        } catch (e) {
          console.warn('⚠️ Erro ao persistir IndexedDB minimal cache:', e);
        }
        
        // Salvar no localStorage como fallback
        const cacheNovas = {
          timestamp: Date.now(),
          novas: filtradas,
          todasMusicas: normed,
          views: viewsAtual
        };
        try {
          localStorage.setItem(CACHE_KEY, JSON.stringify(cacheNovas));
          console.log("💾 Cache salvo em memória e localStorage");
        } catch (e) {
          if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {
            console.warn('⚠️ Quota do localStorage excedida. Limpando cache antigo e tentando novamente.');
            localStorage.removeItem(CACHE_KEY);
            try {
              localStorage.setItem(CACHE_KEY, JSON.stringify(cacheNovas));
              console.log("💾 Cache salvo após limpar localStorage.");
            } catch (err) {
              console.error('❌ Ainda não foi possível salvar no localStorage:', err);
            }
          } else {
            console.error('❌ Erro ao salvar no localStorage:', e);
          }
        }

        // Buscar "Mais Buscadas" do servidor (ranking centralizado)
        console.log("📊 Buscando ranking centralizado...");
        const serverRanking = await cacheServerRanking(20);
        
        let maisBuscadasList;
        if (serverRanking && serverRanking.length > 0) {
          // Usar ranking do servidor (dados agregados de todos os acessos)
          maisBuscadasList = serverRanking
            .map(item => data.find(m => String(m.numero) === String(item.numero)))
            .filter(Boolean);
          console.log("✅ Usando ranking do servidor (centralizado):", maisBuscadasList.length, "músicas");
          console.log("🎵 Top 5:", maisBuscadasList.slice(0, 5).map(m => `${m.numero} - ${m.musica}`));
        } else {
          // Fallback: usar local views
          const topViewedIds = getTopViewedMusic(20);
          if (topViewedIds.length > 0) {
            maisBuscadasList = topViewedIds
              .map(id => data.find(m => String(m.numero) === String(id)))
              .filter(Boolean);
            console.log("⚠️ Ranking do servidor indisponível, usando local views");
          } else {
            // Última opção: últimas 20 músicas
            maisBuscadasList = data.filter((m) => m.novas !== true).slice(-20).reverse();
            console.log("⚠️ Sem histórico, usando últimas 20 músicas");
          }
        }
        
        // Não carregar imagens agora - deixar para lazy loading
        setMaisBuscadas(maisBuscadasList);
        
        setCarregando(false);
        setBuscaBloqueada(false);
        console.log("💾 Carrossel salvo no cache");
      })
      .catch((err) => {
        console.error("❌ Erro ao carregar músicas:", err);
        setCarregando(false);
        setBuscaBloqueada(false);
      });
    };

    carregarDados();
  }, []);

  const scrollLeft = () => {
    carouselRef.current.scrollBy({ left: -300, behavior: "smooth" });
  };

  const scrollRight = () => {
    carouselRef.current.scrollBy({ left: 300, behavior: "smooth" });
  };

  const scrollLeftMaisBuscadas = () => {
    carouselMaisBuscadasRef.current.scrollBy({ left: -200, behavior: "smooth" });
  };

  const scrollRightMaisBuscadas = () => {
    carouselMaisBuscadasRef.current.scrollBy({ left: 200, behavior: "smooth" });
  };

  // Busca inteligente: prioriza exatos, depois parciais, normaliza tudo
  const filtradas = novas.filter((m) => {
    const termo = normalizar(busca);
    if (!termo) return true;
    // Prioriza exato, depois parcial
    return (
      (m._normTitle && m._normTitle === termo) ||
      (m._normArtists && m._normArtists === termo) ||
      (m._normNumero && m._normNumero === termo) ||
      (m._normTitle && m._normTitle.includes(termo)) ||
      (m._normArtists && m._normArtists.includes(termo)) ||
      (m._normNumero && m._normNumero.includes(termo))
    );
  });

  // Carrossel randomico de 8 cards
  const [carroselNovidades, setCarroselNovidades] = useState([]);
  const lastShuffleRef = useRef(0);
  useEffect(() => {
    const now = Date.now();
    if (filtradas.length > 0) {
      if (now - lastShuffleRef.current > 30000) { // 30 segundos
        const shuffled = [...filtradas].sort(() => Math.random() - 0.5);
        setCarroselNovidades(shuffled.slice(0, 8));
        lastShuffleRef.current = now;
      }
    } else {
      setCarroselNovidades([]);
    }
    // Buscar top 10 artistas com cache local (atualiza no máximo 1 vez por 30 dias)
    let cancelledTop = false;
    (async () => {
      try {
        const CACHE_KEY = 'top10_cache_v1';
        const CACHE_TTL = 7 * 24 * 60 * 60 * 1000; // 7 dias
        const now = Date.now();

        // tentar carregar do cache primeiro
        try {
          const raw = localStorage.getItem(CACHE_KEY);
          if (raw) {
            const parsed = JSON.parse(raw);
            if (parsed && parsed.timestamp && (now - parsed.timestamp) < CACHE_TTL && Array.isArray(parsed.data)) {
              if (!cancelledTop) {
                setTopArtistas(parsed.data);
                // não armazenamos imagens no cache, apenas nomes; pré-carregaremos imagens abaixo
              }
              // cache válido -> não buscar do backend
              return;
            }
          }
        } catch (e) {
          console.warn('[Home] top10 cache read error', e);
        }

        // cache ausente/expirado -> buscar do backend (proxy + fallback direto)
        let res;
        try {
          res = await axios.get(`${API_BASE}/top10-artistas`);
        } catch (e) {
          try { res = await axios.get('http://localhost:3001/api/top10-artistas'); } catch (err) { throw err; }
        }

        let list = res && res.data ? res.data : [];
        // suportar vários formatos: { top: [...] } | { artistas: [...] } | array direta [...]
        if (list && list.top && Array.isArray(list.top)) list = list.top;
        else if (list && list.artistas && Array.isArray(list.artistas)) list = list.artistas;
        else if (!Array.isArray(list)) list = [];

        // limpar nomes e limitar
        const cleaned = list.slice(0, 10).map((a) => {
          const isObj = a && typeof a === 'object';
          const rawName = isObj ? (a.nomePrincipal || a.nome || a.name || a.normalizado) : a || '';
          const displayName = String(rawName).replace(/^[\.\s]+/, '');
          return {
            raw: rawName,
            nome: displayName,
            totalMusicas: isObj ? (a.totalMusicas || a.count || a.total || a.cantidad) : (a.totalMusicas || a.count || '')
          };
        });

        if (!cancelledTop) setTopArtistas(cleaned);

        // guardar no cache com timestamp
        try {
          localStorage.setItem(CACHE_KEY, JSON.stringify({ timestamp: now, data: cleaned }));
        } catch (e) {
          // ignore write errors (quota etc.)
        }

        // Pré-carregar imagens por nome limpo
        cleaned.forEach(async (a) => {
          try {
            if (!a || !a.nome) return;
            const img = await getArtistImage(a.nome, { tryLocal: true });
            if (!cancelledTop) setTopArtistasImgs((prev) => ({ ...prev, [a.nome]: img }));
          } catch (e) {
            // ignore image errors
          }
        });
      } catch (e) {
        console.warn('[Home] failed to load top10 artistas', e);
      }
    })();
    return () => { cancelledTop = true; };
  }, [filtradas]);

  // Busca categorizada em todo conteúdo
  const termo = useMemo(() => normalizar(busca), [busca]);
  const temBusca = termo.length >= 3;

  // Músicas que correspondem à busca — armazenadas em state para suportar busca assíncrona
  const [musicasFiltradas, setMusicasFiltradas] = useState([]);

  useEffect(() => {
    if (!temBusca) {
      setMusicasFiltradas([]);
      return;
    }

    const idx = getMusicIndex();
    if (idx) {
      // FlexSearch via worker é assíncrono — usar API async e atualizar state quando pronto
      let cancelled = false;
      (async () => {
        try {
          const results = await searchMusic(busca, 200);
          if (!cancelled) setMusicasFiltradas(Array.isArray(results) ? results : []);
        } catch (e) {
          console.warn('Busca FlexSearch falhou (Home), fallback para filtro in-memory', e);
          if (!cancelled) {
            const fallback = todasMusicas.filter((m) => 
              (m._normTitle && m._normTitle.includes(termo)) ||
              (m._normArtists && m._normArtists.includes(termo)) ||
              (m._normNumero && m._normNumero.includes(termo))
            );
            setMusicasFiltradas(fallback);
          }
        }
      })();
      return () => { cancelled = true; };
    }

    // Fallback síncrono quando não há índice
    const fallback = todasMusicas.filter((m) => 
      (m._normTitle && m._normTitle.includes(termo)) ||
      (m._normArtists && m._normArtists.includes(termo)) ||
      (m._normNumero && m._normNumero.includes(termo))
    );
    setMusicasFiltradas(fallback);
  }, [temBusca, todasMusicas, termo, busca]);

  // Busca de artistas igual à página Nacional
  useEffect(() => {
    if (!temBusca) {
      setArtistasFiltrados([]);
      return;
    }

    // Preferir backend agrupado de artistas (retorna nomes únicos/canonizados).
    // Se o backend estiver indisponível, usamos o fallback antigo que extrai nomes das músicas.
    let cancelled = false;
    (async () => {
      try {
        const res = await axios.get(`/api/artistas/?busca=${encodeURIComponent(busca)}`);
        let list = res.data;
        // API may return { artistas: [...] } or an array
        if (list && list.artistas) list = list.artistas;
        if (Array.isArray(list) && list.length > 0) {
          // Extrair artista principal e agrupar para evitar duplicatas
          const artistasMap = new Map();
          list.forEach(a => {
            if (!a) return;
            // aceitar strings e objetos (API pode retornar objetos com campos de nome)
            const nomeCompleto = typeof a === 'string'
              ? a
              : (a.nomePrincipal || a.nome || a.name || a.normalizado || (a.displayName && a.displayName) || '');
            
            const nomePrincipal = extrairArtistaPrincipal(nomeCompleto);
            const key = normalizeForSearch(nomePrincipal).toLowerCase();
            
            if (nomePrincipal && fuzzyMatch(busca, nomePrincipal)) {
              if (!artistasMap.has(key)) {
                artistasMap.set(key, nomePrincipal);
              }
            }
          });
          
          if (!cancelled) {
            setArtistasFiltrados(Array.from(artistasMap.values()));
            return;
          }
        }
      } catch (e) {
        // backend/search may fail (CORS/offline) — fallback below
      }

      // Fallback: extract artist names from music entries (legacy behavior)
      const artistasDaBusca = todasMusicas
        .filter((m) => {
          return fuzzyMatch(busca, getMusicTitle(m)) || 
                 fuzzyMatch(busca, getArtistNames(m)) || 
                 fuzzyMatch(busca, String(m.numero || ''));
        })
        .flatMap(m => {
          const nomes = getArtistNames(m);
          return nomes ? nomes.split(',').map(s => extrairArtistaPrincipal(s.trim())).filter(Boolean) : [];
        })
        .filter(Boolean);

      // Agrupar artistas por nome principal normalizado para evitar duplicatas
      const artistasMap = new Map();
      artistasDaBusca.forEach(nome => {
        const key = normalizeForSearch(nome).toLowerCase();
        if (!artistasMap.has(key)) {
          artistasMap.set(key, nome);
        }
      });
      
      const artistasUnicos = Array.from(artistasMap.values());
      if (!cancelled) setArtistasFiltrados(artistasUnicos.filter((a) => a && fuzzyMatch(busca, a)));
    })();
    return () => { cancelled = true; };
  }, [temBusca, todasMusicas, termo]);

  // Ritmos únicos que correspondem à busca (memoizado para performance)
  const ritmosFiltrados = useMemo(() => {
    if (!temBusca) return [];
    
    return [...new Set(
      todasMusicas.flatMap((m) => {
        // Ritmos podem estar em 'm.ritmos' (array) ou 'm.ritmo' (string)
        const ritmos = Array.isArray(m.ritmos) ? m.ritmos : (m.ritmo ? [m.ritmo] : []);
        return ritmos.filter(r => r && normalizar(r).includes(termo));
      })
    )].sort();
  }, [temBusca, todasMusicas, termo]);

  // Resetar itens mostrados quando a busca mudar
  useEffect(() => {
    if (temBusca) {
      setItensMostrados(15);
    }
  }, [busca]);

  // Intersection Observer para scroll infinito
  useEffect(() => {
    if (!temBusca || !observerTarget.current) return;

    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting) {
          // Verificar se ainda há mais itens para carregar
          if (itensMostrados < musicasFiltradas.length) {
            console.log("📜 Carregando mais músicas...");
            setItensMostrados((prev) => prev + 15);
          }
        }
      },
      { threshold: 0.1 }
    );

    observer.observe(observerTarget.current);

    return () => {
      observer.disconnect();
    };
  }, [itensMostrados, musicasFiltradas.length, temBusca]);

  // Aplicar limite aos resultados exibidos (memoizado)
  const musicasExibidas = useMemo(() => 
    musicasFiltradas.slice(0, itensMostrados),
    [musicasFiltradas, itensMostrados]
  );

  // Debug
  useEffect(() => {
    if (temBusca) {
      console.log("🔍 Busca:", busca);
      console.log("📊 Filtro:", filtro);
      console.log("🎤 Artistas filtrados:", artistasFiltrados);
      console.log("🎸 Ritmos filtrados:", ritmosFiltrados);
      console.log("🎵 Músicas filtradas:", musicasFiltradas.length);
      console.log("👁️ Mostrar artistas:", mostrarArtistas);
      console.log("👁️ Mostrar ritmos:", mostrarRitmos);
    }
  }, [temBusca, filtro, artistasFiltrados, ritmosFiltrados, musicasFiltradas]);

  // Carregar imagens dos artistas da busca
  useEffect(() => {
    if (artistasFiltrados.length === 0) return;

    const displayNames = artistasFiltrados
      .map(a => (typeof a === 'string' ? a : (a.nomePrincipal || a.nome || a.name || a.normalizado || a.displayName || '')))
      .filter(Boolean);

    displayNames.forEach(async (name) => {
      if (!imagensArtistas[name]) {
        try {
          const img = await getArtistImage(name, { tryLocal: true });
          setImagensArtistas((prev) => ({ ...prev, [name]: img })); // Usa padrões otimizados
        } catch (e) {
          // ignore image load errors
        }
      }
    });
  }, [artistasFiltrados.map(a => (typeof a === 'string' ? a : (a.nomePrincipal || a.nome || a.name || a.normalizado || a.displayName || ''))).join(','), imagensArtistas]);

  // Aplicar filtro nos resultados
  // Ajuste: mostrar apenas botões de filtro relevantes
  const mostrarMusicas = (filtro === "todos" || filtro === "musicas") && musicasFiltradas.length > 0;
  const mostrarArtistas = (filtro === "todos" || filtro === "artistas") && artistasFiltrados.length > 0;
  const mostrarRitmos = (filtro === "todos" || filtro === "ritmos") && ritmosFiltrados.length > 0;

  return (
    <Box
      sx={{
        padding: 3,
        paddingBottom: 10,
        color: "#fff",
        position: "relative"
      }}
    >
      {/* Busca: passar buscaBloqueada e arrays filtrados como props */}
      <Busca
        valor={busca}
        onChange={setBusca}
        showFiltros={busca && busca.length >= 3}
        filtro={filtro}
        onFiltroChange={setFiltro}
        buscaBloqueada={buscaBloqueada}
        musicasFiltradas={musicasFiltradas}
        artistasFiltrados={artistasFiltrados}
        ritmosFiltrados={ritmosFiltrados}
      />
      {/* LOADING ANIMATION */}
      {carregando && location.pathname === '/' && (
        <Box id="home-loading-overlay" sx={{ position: "fixed", top: 0, left: 0, width: "100vw", height: "100vh", bgcolor: "rgba(0,0,0,0.7)", zIndex: 9999, display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column" }}>
          <CircularProgress size={60} sx={{ color: "#1D7EBF" }} />
          <Typography sx={{ color: "#fff", mt: 3, fontSize: "1.2rem" }}>Carregando músicas...</Typography>
        </Box>
      )}
      {/* RESULTADOS DA BUSCA CATEGORIZADA */}
      {/* Exemplo de uso: <Busca buscaBloqueada={buscaBloqueada} ... /> */}
      {busca && busca.length > 0 && busca.length < 3 ? (
        <Box sx={{ padding: 3, textAlign: "center" }}>
          <Typography sx={{ color: "#aaa", mt: 4 }}>
            Digite pelo menos 3 caracteres para buscar
          </Typography>
        </Box>
      ) : temBusca ? (
        <>
          <Typography variant="h4" sx={{ mb: 3, fontWeight: "bold" }}>
            Resultados para "{busca}"
          </Typography>

          {/* MÚSICAS */}
          {mostrarMusicas && musicasFiltradas.length > 0 && (
            <>
              <Typography variant="h5" sx={{ mb: 2, fontWeight: "bold", color: "#1D7EBF" }}>
                Músicas ({musicasFiltradas.length})
              </Typography>
              <Box sx={{ mb: 4 }}>
                {musicasExibidas.map((m, index) => (
                  <ListaItemModern key={index} item={m} />
                ))}
                
                {/* Target para Intersection Observer (scroll infinito) */}
                {musicasExibidas.length < musicasFiltradas.length && (
                  <Box ref={observerTarget} sx={{ textAlign: "center", mt: 4, mb: 4, display: "flex", alignItems: "center", justifyContent: "center", gap: 2 }}>
                    <CircularProgress size={24} sx={{ color: "#1D7EBF" }} />
                    <Typography sx={{ color: "#1D7EBF" }}>Carregando mais...</Typography>
                  </Box>
                )}
              </Box>
            </>
          )}

          {/* ARTISTAS */}
          {mostrarArtistas && artistasFiltrados.length > 0 && (
            <>
              <Typography variant="h5" sx={{ mb: 2, fontWeight: "bold", color: "#1D7EBF" }}>
                Artistas
              </Typography>
              <Box sx={{ display: "flex", flexWrap: "wrap", gap: 2, mb: 4 }}>
                {artistasFiltrados.map((artista, index) => {
                  const isObj = artista && typeof artista === 'object';
                  const artistId = isObj ? (artista.id || artista.normalizado) : null;
                  const displayName = isObj ? (artista.nomePrincipal || artista.nome || artista.name) : artista;
                  return (
                    <Card
                      key={artistId || index}
                      sx={{
                        width: 150,
                        background: "#181818",
                        borderRadius: "12px",
                        cursor: "pointer",
                        transition: "transform 0.2s",
                        textDecoration: 'none',
                        color: 'inherit',
                        "&:hover": { transform: "scale(1.05)" }
                      }}
                      onClick={() => {
                        // Usar slugify importado para garantir URL correta
                        const url = `/artista/${slugify(displayName)}`;
                        navigate(url);
                      }}
                    >
                      <CardMedia
                        component="img"
                        height="150"
                        image={imagensArtistas[artistId] || imagensArtistas[displayName] || ""}
                        alt={displayName}
                        sx={{ objectFit: "cover", aspectRatio: "1/1" }}
                      />
                      <CardContent sx={{ p: 1.5 }}>
                        <Typography sx={{ fontWeight: "bold", fontSize: "0.9rem" }}>
                          {displayName}
                        </Typography>
                      </CardContent>
                    </Card>
                  );
                })}
              </Box>
            </>
          )}

          {/* RITMOS */}
          {mostrarRitmos && ritmosFiltrados.length > 0 && (
            <>
              <Typography variant="h5" sx={{ mb: 2, fontWeight: "bold", color: "#1D7EBF" }}>
                Ritmos
              </Typography>
              <Box sx={{ display: "flex", flexWrap: "wrap", gap: 2, mb: 4 }}>
                {ritmosFiltrados.map((ritmo, index) => (
                  <Card
                    component="a"
                    href={`/ritmo/${ritmo}`}
                    key={index}
                    sx={{
                      background: "#181818",
                      borderRadius: "12px",
                      cursor: "pointer",
                      transition: "transform 0.2s",
                      textDecoration: 'none',
                      color: 'inherit',
                      "&:hover": { transform: "scale(1.05)" }
                    }}
                    onClick={(e) => {
                      e.preventDefault();
                      navigate(`/ritmo/${ritmo}`);
                    }}
                  >
                    <CardContent sx={{ p: 2 }}>
                      <Typography sx={{ fontWeight: "bold", fontSize: "1rem" }}>
                        {ritmo}
                      </Typography>
                    </CardContent>
                  </Card>
                ))}
              </Box>
            </>
          )}

          {/* Nenhum resultado */}
          {(!mostrarMusicas || musicasFiltradas.length === 0) && 
           (!mostrarArtistas || artistasFiltrados.length === 0) && 
           (!mostrarRitmos || ritmosFiltrados.length === 0) && (
            <Typography sx={{ color: "#aaa", mt: 4, textAlign: "center" }}>
              Nenhum resultado encontrado para "{busca}"
            </Typography>
          )}
        </>
      ) : (
        <>
          {/* CONTEÚDO PADRÃO (SEM BUSCA) */}
          {carregando ? (
            <Box>
              {/* Skeleton para Novidades */}
              <Typography variant="h5" sx={{ mb: 3, fontWeight: "bold" }}>
                Novidades
              </Typography>
              <Box
                sx={{
                  display: "grid",
                  gridTemplateColumns: {
                    xs: "repeat(2, 1fr)",
                    sm: "repeat(3, 1fr)",
                    md: "repeat(4, 1fr)",
                    lg: "repeat(5, 1fr)"
                  },
                  gap: { xs: 1, sm: 2 },
                  mb: 4
                }}
              >
                {[...Array(10)].map((_, i) => (
                  <Box key={i}>
                    <Skeleton 
                      variant="rectangular" 
                      sx={{ 
                        width: "100%", 
                        aspectRatio: "1/1",
                        bgcolor: "rgba(255,255,255,0.05)",
                        borderRadius: 1
                      }} 
                    />
                    <Skeleton sx={{ mt: 1, bgcolor: "rgba(255,255,255,0.05)" }} />
                    <Skeleton width="60%" sx={{ bgcolor: "rgba(255,255,255,0.05)" }} />
                  </Box>
                ))}
              </Box>

              {/* Skeleton para Mais Buscadas */}
              <Typography variant="h5" sx={{ mb: 3, fontWeight: "bold" }}>
                Mais Buscadas
              </Typography>
              <Box
                sx={{
                  display: "grid",
                  gridTemplateColumns: {
                    xs: "repeat(2, 1fr)",
                    sm: "repeat(3, 1fr)",
                    md: "repeat(4, 1fr)",
                    lg: "repeat(5, 1fr)"
                  },
                  gap: { xs: 1, sm: 2 }
                }}
              >
                {[...Array(10)].map((_, i) => (
                  <Box key={i}>
                    <Skeleton 
                      variant="rectangular" 
                      sx={{ 
                        width: "100%", 
                        aspectRatio: "1/1",
                        bgcolor: "rgba(255,255,255,0.05)",
                        borderRadius: 1
                      }} 
                    />
                    <Skeleton sx={{ mt: 1, bgcolor: "rgba(255,255,255,0.05)" }} />
                    <Skeleton width="60%" sx={{ bgcolor: "rgba(255,255,255,0.05)" }} />
                  </Box>
                ))}
              </Box>
            </Box>
          ) : (
            <>
                <Typography 
                variant="h5" 
                sx={{ 
                  mb: 3, 
                  fontWeight: "bold",
                  cursor: "pointer",
                  "&:hover": { color: "#1D7EBF" }
                }}
                onClick={() => navigate("/novidades")}
              >
                Novidades
              </Typography>

      {/* CONTAINER DO CARROSSEL COM SETAS */}
      <Box sx={{ position: "relative", mb: 4 }}>
        {/* SETA ESQUERDA */}
        <IconButton
          onClick={scrollLeft}
          sx={{
            position: "absolute",
            left: 0,
            // mover para sobrepor a base dos cards de Novidades
            bottom: { xs: 36, md: 48 },
            transform: "none",
            background: "rgba(29, 126, 191, 0.9)",
            backdropFilter: "blur(10px)",
            color: "#fff",
            width: { xs: 32, md: 40 },
            height: { xs: 32, md: 40 },
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 30,
            boxShadow: "0 6px 18px rgba(0,0,0,0.45)",
            "&:hover": { 
              background: "rgba(29, 126, 191, 0.95)",
              transform: "scale(1.08)"
            },
            transition: "all 0.18s ease"
          }}
        >
          <ChevronLeft sx={{ fontSize: { xs: 18, md: 24 } }} />
        </IconButton>

        {/* CARROSSEL */}
        <Box
          ref={carouselRef}
          sx={{
            display: "flex",
            overflowX: "auto",
            gap: 2,
            pb: 2,
            scrollBehavior: "smooth",
            "&::-webkit-scrollbar": { display: "none" }
          }}
        >
        {carroselNovidades.map((m, index) => (
          <Card
            key={index}
            sx={{
              minWidth: { xs: 140, sm: 200 },
              maxWidth: { xs: 140, sm: 200 },
              background: "#181818",
              borderRadius: "12px",
              cursor: "pointer",
              flexShrink: 0
            }}
            onClick={(e) => {
              if (!(m && m.numero)) return;
              const numero = normalizeTrackNumber(m.numero || m.numeroControle);
              const expected = `/musica/${numero}`;
              // Allow modifier clicks (open in new tab) or middle-button
              const isModified = e.ctrlKey || e.metaKey || e.shiftKey || e.altKey || (e.nativeEvent && e.nativeEvent.button === 1);
              if (isModified) {
                try { window.open(expected, '_blank'); } catch (err) { /* ignore */ }
                return;
              }
              console.log('[Home] carousel click ->', numero);
              try { navigate(`/musica/${numero}`, { state: { music: m } }); } catch (err) { console.warn('[Home] navigate error', err); }
            }}
          >
            <LazyImage
              cantor={m.cantor}
              alt={m.cantor}
              sx={{
                height: { xs: 140, sm: 200 },
                width: "100%",
                backgroundColor: "#1D7EBF",
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                position: "relative",
                overflow: "hidden"
              }}
            />
            <CardContent sx={{ p: { xs: 0.5, sm: 1, md: 1.2 } }}>
              <Typography sx={{ fontWeight: "normal", fontSize: { xs: "0.7rem", sm: "0.9rem", md: "1rem" } }}>
                {m.musica}
              </Typography>
              <Typography sx={{ opacity: 0.7, fontSize: { xs: "0.6rem", sm: "0.8rem", md: "0.9rem" } }}>
                {m.cantor}
              </Typography>
              <Typography
                sx={{ 
                  color: "#1D7EBF", 
                  fontSize: { xs: "0.8rem", sm: "1rem", md: "1.2rem" }, 
                  mt: { xs: 0.3, sm: 0.5, md: 1 },
                  fontWeight: "bold"
                }}
              >
                {String(parseInt(m.numero, 10))}
              </Typography>
            </CardContent>
          </Card>
        ))}
      </Box>

      {/* Botão 'Ver Mais Novidades' */}
      {filtradas.length > 8 && (
        <Box sx={{ textAlign: "center", mt: { xs: 0.5, sm: 1.5, md: 2 }, pb: 2 }}>
            <Button
            variant="outlined"
            onClick={() => navigate("/novidades")}
            sx={{
              color: "#1D7EBF",
              border: "1px solid #1D7EBF",
              fontSize: "0.9rem",
              padding: { xs: "4px 16px", sm: "6px 20px" },
              "&:hover": {
                backgroundColor: "rgba(29, 126, 191, 0.1)"
              }
            }}
          >
            Ver mais novidades
          </Button>
        </Box>
      )}

        {/* SETA DIREITA */}
        <IconButton
          onClick={scrollRight}
          sx={{
            position: "absolute",
            right: 0,
            // mover para sobrepor a base dos cards de Novidades
            bottom: { xs: 36, md: 48 },
            transform: "none",
            background: "rgba(29, 126, 191, 0.9)",
            backdropFilter: "blur(10px)",
            color: "#fff",
            width: { xs: 32, md: 40 },
            height: { xs: 32, md: 40 },
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 30,
            boxShadow: "0 6px 18px rgba(0,0,0,0.45)",
            "&:hover": { 
              background: "rgba(29, 126, 191, 0.95)",
              transform: "scale(1.08)"
            },
            transition: "all 0.18s ease"
          }}
        >
          <ChevronRight sx={{ fontSize: { xs: 18, md: 24 } }} />
        </IconButton>
      </Box>

      {/* MAIS BUSCADAS */}
      <Typography 
        variant="h5" 
        sx={{ 
          mt: 4, 
          mb: 2, 
          fontWeight: "bold",
          cursor: "pointer",
          "&:hover": { color: "#1D7EBF" }
        }}
        onClick={() => navigate("/mais-buscadas")}
      >
        Mais Buscadas
      </Typography>

      {/* CONTAINER DO CARROSSEL MAIS BUSCADAS COM SETAS */}
      <Box sx={{ position: "relative", mb: 4 }}>
        {/* SETA ESQUERDA - Mais Buscadas */}
        <IconButton
          onClick={scrollLeftMaisBuscadas}
          sx={{
              position: "absolute",
              left: 0,
              bottom: { xs: 8, md: 12 },
              transform: "none",
              background: "rgba(29, 126, 191, 0.9)",
              backdropFilter: "blur(10px)",
              color: "#fff",
              width: { xs: 32, md: 40 },
              height: { xs: 32, md: 40 },
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              zIndex: 20,
              boxShadow: "0 6px 18px rgba(0,0,0,0.45)",
              "&:hover": { 
                background: "rgba(29, 126, 191, 0.95)",
                transform: "scale(1.08)"
              },
              transition: "all 0.18s ease"
            }}
        >
          <ChevronLeft sx={{ fontSize: { xs: 18, md: 24 } }} />
        </IconButton>

        {/* CARROSSEL MAIS BUSCADAS - 35% menor */}
        <Box
          ref={carouselMaisBuscadasRef}
          sx={{
            display: "flex",
            overflowX: "auto",
            gap: 2,
            pb: 2,
            mb: 2,
            scrollBehavior: "smooth",
            "&::-webkit-scrollbar": { display: "none" }
          }}
        >
        {maisBuscadas.map((m, index) => (
          <Card
            key={index}
            sx={{
              minWidth: { xs: 91, sm: 130 },
              maxWidth: { xs: 91, sm: 130 },
              background: "#181818",
              borderRadius: "12px",
              cursor: "pointer",
              flexShrink: 0
            }}
            onClick={(e) => {
              if (!(m && m.numero)) return;
              const numero = normalizeTrackNumber(m.numero || m.numeroControle);
              const expected = `/musica/${numero}`;
              const isModified = e.ctrlKey || e.metaKey || e.shiftKey || e.altKey || (e.nativeEvent && e.nativeEvent.button === 1);
              if (isModified) {
                try { window.open(expected, '_blank'); } catch (err) { /* ignore */ }
                return;
              }
              console.log('[Home] maisBuscadas click ->', numero);
              try { navigate(`/musica/${numero}`, { state: { music: m } }); } catch (err) { console.warn('[Home] navigate error', err); }
            }}
          >
            <LazyImage
              cantor={m.cantor}
              alt={m.cantor}
              sx={{
                height: { xs: 91, sm: 130 },
                width: "100%",
                backgroundColor: "#1D7EBF",
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                position: "relative",
                overflow: "hidden"
              }}
            />
            <CardContent sx={{ p: { xs: 0.8, sm: 1.2 } }}>
              <Typography sx={{ fontWeight: "normal", fontSize: { xs: "0.65rem", sm: "0.78rem" } }}>
                {m.musica}
              </Typography>
              <Typography sx={{ opacity: 0.7, fontSize: { xs: "0.59rem", sm: "0.71rem" } }}>
                {m.cantor}
              </Typography>
              <Typography
                sx={{ 
                  color: "#1D7EBF", 
                  fontSize: { xs: "0.78rem", sm: "0.94rem" }, 
                  mt: 0.5,
                  fontWeight: "bold"
                }}
              >
                {String(parseInt(m.numero, 10))}
              </Typography>
            </CardContent>
          </Card>
        ))}
      </Box>

        {/* SETA DIREITA - Mais Buscadas */}
        <IconButton
          onClick={scrollRightMaisBuscadas}
          sx={{
              position: "absolute",
              right: 0,
              bottom: { xs: 8, md: 12 },
              transform: "none",
              background: "rgba(29, 126, 191, 0.9)",
              backdropFilter: "blur(10px)",
              color: "#fff",
              width: { xs: 32, md: 40 },
              height: { xs: 32, md: 40 },
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              zIndex: 20,
              boxShadow: "0 6px 18px rgba(0,0,0,0.45)",
              "&:hover": { 
                background: "rgba(29, 126, 191, 0.95)",
                transform: "scale(1.08)"
              },
              transition: "all 0.18s ease"
            }}
        >
          <ChevronRight sx={{ fontSize: { xs: 18, md: 24 } }} />
        </IconButton>
      </Box>

      {/* EXPLORAR */}
      {/* TOP 10 ARTISTAS (painel abaixo de Mais Buscadas) */}
      <>
        <Typography variant="h5" sx={{ mt: 4, mb: 2, fontWeight: "bold", cursor: "pointer", "&:hover": { color: "#1D7EBF" } }} onClick={() => navigate('/artistas')}>
          Top 10 artistas
        </Typography>

        <Box sx={{ display: 'grid', gridTemplateColumns: { xs: '1fr', sm: '1fr 1fr' }, gap: 2, mb: 2 }}>
          {topArtistas && topArtistas.length > 0 ? (
            topArtistas.map((a, index) => {
              const isObj = a && typeof a === 'object';
              const rawName = isObj ? (a.nomePrincipal || a.nome || a.name || a.normalizado) : a || '';
              const displayName = String(rawName).replace(/^[\.\s]+/, '');
              const count = isObj ? (a.totalMusicas || a.count || a.total || a.cantidad) : (a.count || a.totalMusicas || '');
              const img = topArtistasImgs[displayName] || "";
              return (
                <Card
                  key={displayName || index}
                  onClick={() => navigate(`/artista/${slugify(displayName)}`)}
                  sx={{
                    display: 'flex',
                    alignItems: 'center',
                    gap: 2,
                    p: 1,
                    background: '#181818',
                    borderRadius: '8px',
                    cursor: 'pointer',
                    '&:hover': { transform: 'translateY(-2px)' },
                    boxShadow: 'none'
                  }}
                >
                  <LazyImage cantor={displayName} alt={displayName} sx={{ width: 56, height: 56, borderRadius: 1, objectFit: 'cover', backgroundColor: 'rgba(255,255,255,0.04)' }} />
                  <Box sx={{ flex: 1, minWidth: 0 }}>
                    <Typography noWrap sx={{ fontWeight: 'bold', fontSize: '0.95rem' }}>{displayName}</Typography>
                    <Typography sx={{ color: '#a6a6a6', fontSize: '0.85rem' }}>{count ? `${String(count)} músicas` : '—'}</Typography>
                  </Box>
                </Card>
              );
            })
          ) : (
            // mostrar skeletons enquanto não há dados
            [...Array(10)].map((_, i) => (
              <Card key={i} sx={{ display: 'flex', alignItems: 'center', gap: 2, p: 1, background: '#181818', borderRadius: '8px' }}>
                <Skeleton variant="rectangular" sx={{ width: 56, height: 56, borderRadius: 1, bgcolor: 'rgba(255,255,255,0.04)' }} />
                <Box sx={{ flex: 1 }}>
                  <Skeleton sx={{ height: 18, width: '60%', mb: 0.5, bgcolor: 'rgba(255,255,255,0.04)' }} />
                  <Skeleton sx={{ height: 14, width: '40%', bgcolor: 'rgba(255,255,255,0.04)' }} />
                </Box>
              </Card>
            ))
          )}
        </Box>
      </>

      <Typography variant="h5" sx={{ mt: 4, mb: 3, fontWeight: "bold" }}>
        Explorar
      </Typography>

      <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" }, gap: 3 }}>
        <Button
          sx={{ 
            background: "#1D7EBF", 
            color: "#000", 
            fontWeight: "bold",
            height: "90px",
            fontSize: "1.1rem",
            borderRadius: "8px",
            transition: "all 0.3s",
            "&:hover": { 
              background: "#2E8FD0",
              transform: "translateY(-4px)",
              boxShadow: "0 8px 16px rgba(29, 126, 191, 0.4)"
            }
          }}
          onClick={() => navigate("/nacional")}
        >
          Nacional
        </Button>

        <Button
          sx={{ 
            background: "#1D7EBF", 
            color: "#000", 
            fontWeight: "bold",
            height: "90px",
            fontSize: "1.1rem",
            borderRadius: "8px",
            transition: "all 0.3s",
            "&:hover": { 
              background: "#2E8FD0",
              transform: "translateY(-4px)",
              boxShadow: "0 8px 16px rgba(29, 126, 191, 0.4)"
            }
          }}
          onClick={() => navigate("/internacional")}
        >
          Internacional
        </Button>

        <Button
          sx={{ 
            background: "#1D7EBF", 
            color: "#000", 
            fontWeight: "bold",
            height: "90px",
            fontSize: "1.1rem",
            borderRadius: "8px",
            transition: "all 0.3s",
            "&:hover": { 
              background: "#2E8FD0",
              transform: "translateY(-4px)",
              boxShadow: "0 8px 16px rgba(29, 126, 191, 0.4)"
            }
          }}
          onClick={() => navigate("/ritmos")}
        >
          Ritmos
        </Button>

        <Button
          sx={{ 
            background: "#1D7EBF", 
            color: "#000", 
            fontWeight: "bold",
            height: "90px",
            fontSize: "1.1rem",
            borderRadius: "8px",
            transition: "all 0.3s",
            "&:hover": { 
              background: "#2E8FD0",
              transform: "translateY(-4px)",
              boxShadow: "0 8px 16px rgba(29, 126, 191, 0.4)"
            }
          }}
          onClick={() => {
            navigate('/artistas');
          }}
        >
          Artistas
        </Button>
      </Box>
            </>
          )}
        </>
      )}
      <ScrollToTop />
    </Box>
  );
}
