import 'dart:io'; import 'package:spotiflac_android/services/platform_bridge.dart'; import 'package:spotiflac_android/utils/file_access.dart'; bool hasEmbeddedLyricsMetadata(Map metadata) { final lyrics = (metadata['LYRICS'] ?? '').trim(); if (lyrics.isNotEmpty) return true; final unsyncedLyrics = (metadata['UNSYNCEDLYRICS'] ?? '').trim(); if (unsyncedLyrics.isNotEmpty) return true; return false; } String _sidecarLrcPath(String path) { final slash = path.lastIndexOf(Platform.pathSeparator); final dot = path.lastIndexOf('.'); if (dot > slash) { return '${path.substring(0, dot)}.lrc'; } return '$path.lrc'; } Future ensureLyricsMetadataForConversion({ required Map metadata, required String sourcePath, required bool shouldEmbedLyrics, required String trackName, required String artistName, String spotifyId = '', int durationMs = 0, }) async { if (!shouldEmbedLyrics || hasEmbeddedLyricsMetadata(metadata)) { return; } String? lyrics; // Prefer sidecar .lrc when available to avoid network calls. if (!isContentUri(sourcePath)) { try { final lrcPath = _sidecarLrcPath(sourcePath); final lrcFile = File(lrcPath); if (await lrcFile.exists()) { final content = (await lrcFile.readAsString()).trim(); if (content.isNotEmpty) { lyrics = content; } } } catch (_) {} } if (lyrics == null || lyrics.isEmpty) { try { final fetched = await PlatformBridge.getLyricsLRC( spotifyId, trackName, artistName, durationMs: durationMs, ); final normalized = fetched.trim(); if (normalized.isNotEmpty && normalized.toLowerCase() != '[instrumental:true]') { lyrics = normalized; } } catch (_) {} } if (lyrics == null || lyrics.isEmpty) { return; } metadata['LYRICS'] = lyrics; metadata['UNSYNCEDLYRICS'] = lyrics; } void mergePlatformMetadataForTagEmbed({ required Map target, required Map source, }) { void put(String key, dynamic value) { final normalized = value?.toString().trim(); if (normalized == null || normalized.isEmpty) return; target[key] = normalized; } put('TITLE', source['title']); put('ARTIST', source['artist']); put('ALBUM', source['album']); put('ALBUMARTIST', source['album_artist']); put('DATE', source['date']); put('ISRC', source['isrc']); put('GENRE', source['genre']); put('ORGANIZATION', source['label']); put('COPYRIGHT', source['copyright']); put('COMPOSER', source['composer']); put('COMMENT', source['comment']); put('LYRICS', source['lyrics']); put('UNSYNCEDLYRICS', source['lyrics']); final trackNumber = source['track_number']; final totalTracks = source['total_tracks']; if (trackNumber != null && trackNumber.toString() != '0') { put( 'TRACKNUMBER', totalTracks != null && totalTracks.toString().isNotEmpty && totalTracks.toString() != '0' ? '${trackNumber.toString()}/${totalTracks.toString()}' : trackNumber, ); } final discNumber = source['disc_number']; final totalDiscs = source['total_discs']; if (discNumber != null && discNumber.toString() != '0') { put( 'DISCNUMBER', totalDiscs != null && totalDiscs.toString().isNotEmpty && totalDiscs.toString() != '0' ? '${discNumber.toString()}/${totalDiscs.toString()}' : discNumber, ); } }