package de.oaa.libredeck.web.service.applemusic;

import de.oaa.libredeck.web.model.Track;
import de.oaa.libredeck.web.service.streaming.StreamingProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
@RequiredArgsConstructor
public class AppleMusicProvider implements StreamingProvider {

    // https://music.apple.com/us/playlist/my-playlist/pl.xxxxxxxxxxxxxxxx
    private static final Pattern CATALOG_URL = Pattern.compile(
            "music\\.apple\\.com/([a-z]{2})/playlist/[^/]*/([A-Za-z0-9.]+)");

    // Synthetic URL generated by the playlist picker for library playlists
    private static final Pattern LIBRARY_URL = Pattern.compile(
            "music\\.apple\\.com/library/playlists/([A-Za-z0-9.]+)");

    private final AppleMusicApiClient     apiClient;
    private final AppleMusicTokenGenerator tokenGen;

    @Override public String getId()          { return "applemusic"; }
    @Override public String getDisplayName() { return "Apple Music"; }

    @Override
    public boolean supportsUrl(String url) {
        if (url == null || !tokenGen.isConfigured()) return false;
        return CATALOG_URL.matcher(url).find() || LIBRARY_URL.matcher(url).find();
    }

    /**
     * Returns "catalog:{storefront}:{id}" or "library:{id}".
     * This encoding lets the API client know which endpoint to use.
     */
    @Override
    public String extractPlaylistId(String url) {
        Matcher m = CATALOG_URL.matcher(url);
        if (m.find()) return "catalog:" + m.group(1) + ":" + m.group(2);
        m = LIBRARY_URL.matcher(url);
        if (m.find()) return "library:" + m.group(1);
        throw new IllegalArgumentException("Not a valid Apple Music playlist URL: " + url);
    }

    @Override
    public String fetchPlaylistTitle(String playlistId) throws IOException {
        String[] p = playlistId.split(":", 3);
        return switch (p[0]) {
            case "catalog" -> apiClient.fetchCatalogPlaylistTitle(p[1], p[2]);
            case "library" -> apiClient.fetchLibraryPlaylistTitle(p[1]);
            default        -> throw new IllegalArgumentException("Invalid id: " + playlistId);
        };
    }

    @Override
    public List<Track> fetchTracks(String playlistId) throws IOException {
        String[] p = playlistId.split(":", 3);
        return switch (p[0]) {
            case "catalog" -> apiClient.fetchCatalogTracks(p[1], p[2]);
            case "library" -> apiClient.fetchLibraryTracks(p[1]);
            default        -> throw new IllegalArgumentException("Invalid id: " + playlistId);
        };
    }
}
