import 'dart:convert'; import 'package:flutter/services.dart'; /// Bridge to communicate with Go backend via platform channels class PlatformBridge { static const _channel = MethodChannel('com.zarz.spotiflac/backend'); /// Parse and validate Spotify URL static Future> parseSpotifyUrl(String url) async { final result = await _channel.invokeMethod('parseSpotifyUrl', {'url': url}); return jsonDecode(result as String) as Map; } /// Get Spotify metadata from URL static Future> getSpotifyMetadata(String url) async { final result = await _channel.invokeMethod('getSpotifyMetadata', {'url': url}); return jsonDecode(result as String) as Map; } /// Search Spotify static Future> searchSpotify(String query, {int limit = 10}) async { final result = await _channel.invokeMethod('searchSpotify', { 'query': query, 'limit': limit, }); return jsonDecode(result as String) as Map; } /// Check track availability on streaming services static Future> checkAvailability(String spotifyId, String isrc) async { final result = await _channel.invokeMethod('checkAvailability', { 'spotify_id': spotifyId, 'isrc': isrc, }); return jsonDecode(result as String) as Map; } /// Download a track from specific service static Future> downloadTrack({ required String isrc, required String service, required String spotifyId, required String trackName, required String artistName, required String albumName, String? albumArtist, String? coverUrl, required String outputDir, required String filenameFormat, bool embedLyrics = true, bool embedMaxQualityCover = true, int trackNumber = 1, int discNumber = 1, int totalTracks = 1, String? releaseDate, }) async { final request = jsonEncode({ 'isrc': isrc, 'service': service, 'spotify_id': spotifyId, 'track_name': trackName, 'artist_name': artistName, 'album_name': albumName, 'album_artist': albumArtist ?? artistName, 'cover_url': coverUrl, 'output_dir': outputDir, 'filename_format': filenameFormat, 'embed_lyrics': embedLyrics, 'embed_max_quality_cover': embedMaxQualityCover, 'track_number': trackNumber, 'disc_number': discNumber, 'total_tracks': totalTracks, 'release_date': releaseDate ?? '', }); final result = await _channel.invokeMethod('downloadTrack', request); return jsonDecode(result as String) as Map; } /// Download with automatic fallback to other services static Future> downloadWithFallback({ required String isrc, required String spotifyId, required String trackName, required String artistName, required String albumName, String? albumArtist, String? coverUrl, required String outputDir, required String filenameFormat, bool embedLyrics = true, bool embedMaxQualityCover = true, int trackNumber = 1, int discNumber = 1, int totalTracks = 1, String? releaseDate, String preferredService = 'tidal', }) async { final request = jsonEncode({ 'isrc': isrc, 'service': preferredService, 'spotify_id': spotifyId, 'track_name': trackName, 'artist_name': artistName, 'album_name': albumName, 'album_artist': albumArtist ?? artistName, 'cover_url': coverUrl, 'output_dir': outputDir, 'filename_format': filenameFormat, 'embed_lyrics': embedLyrics, 'embed_max_quality_cover': embedMaxQualityCover, 'track_number': trackNumber, 'disc_number': discNumber, 'total_tracks': totalTracks, 'release_date': releaseDate ?? '', }); final result = await _channel.invokeMethod('downloadWithFallback', request); return jsonDecode(result as String) as Map; } /// Get download progress static Future> getDownloadProgress() async { final result = await _channel.invokeMethod('getDownloadProgress'); return jsonDecode(result as String) as Map; } /// Set download directory static Future setDownloadDirectory(String path) async { await _channel.invokeMethod('setDownloadDirectory', {'path': path}); } /// Check if file with ISRC already exists static Future> checkDuplicate(String outputDir, String isrc) async { final result = await _channel.invokeMethod('checkDuplicate', { 'output_dir': outputDir, 'isrc': isrc, }); return jsonDecode(result as String) as Map; } /// Build filename from template static Future buildFilename(String template, Map metadata) async { final result = await _channel.invokeMethod('buildFilename', { 'template': template, 'metadata': jsonEncode(metadata), }); return result as String; } /// Sanitize filename static Future sanitizeFilename(String filename) async { final result = await _channel.invokeMethod('sanitizeFilename', { 'filename': filename, }); return result as String; } /// Fetch lyrics for a track static Future> fetchLyrics( String spotifyId, String trackName, String artistName, ) async { final result = await _channel.invokeMethod('fetchLyrics', { 'spotify_id': spotifyId, 'track_name': trackName, 'artist_name': artistName, }); return jsonDecode(result as String) as Map; } /// Get lyrics in LRC format static Future getLyricsLRC( String spotifyId, String trackName, String artistName, ) async { final result = await _channel.invokeMethod('getLyricsLRC', { 'spotify_id': spotifyId, 'track_name': trackName, 'artist_name': artistName, }); return result as String; } /// Embed lyrics into an existing FLAC file static Future> embedLyricsToFile( String filePath, String lyrics, ) async { final result = await _channel.invokeMethod('embedLyricsToFile', { 'file_path': filePath, 'lyrics': lyrics, }); return jsonDecode(result as String) as Map; } }