package com.qiuguo.iot.third.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qiuguo.iot.third.resp.SingerResponse;
import com.qiuguo.iot.third.resp.SingerSongsResponse;
import com.qiuguo.iot.third.resp.SongInfoResponse;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import com.qiuguo.iot.third.resp.SearchResponse;
import reactor.core.scheduler.Schedulers;

import static org.springframework.util.MimeTypeUtils.APPLICATION_JSON_VALUE;

/**
 * XXX
 *
 * @author weiyachao
 * @since 2023/9/28 10:40
 */
@Service
@Slf4j
public class MusicService {
    
    // 网易云音乐

    /**
     *
     * @param keyword 关键字
     * @param type 1：歌名 100 歌手
     * @return
     */
    public Mono<List<SongInfoResponse.ResultSong>> searchMusic(String keyword, Integer type) {
        if (ObjectUtils.isEmpty(type)) {
            type = 1;
        }
        if (ObjectUtils.isEmpty(keyword)) {
            keyword = "追梦赤子心";
        }
        keyword = keyword.replaceAll("^[^\\u4e00-\\u9fa5\\d]+|[^\\u4e00-\\u9fa5\\d]+$", "");
        WebClient webClient = WebClient.builder()
                .defaultHeader("Content-Type", "application/json; charset=utf-8")
                .defaultHeader("User-Agent","PostmanRuntime/7.29.0")
                .defaultHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS")
                .defaultHeader("Access-Control-Allow-Headers", "X-Requested-With,Content-Type")
                .defaultHeader("Accept-Encoding", "gzip, deflate, br")
                .defaultHeader("Connection", "keep-alive")
                .defaultHeader("Accept", "*")
                .build();
        String baseUrl = "http://121.40.172.241:8031";
        if (type == 1) {
            return webClient.get().uri(baseUrl+"/search?keywords="+keyword).retrieve()
                    .bodyToMono(SearchResponse.class)
                    .delaySubscription(Duration.ofMillis(300), Schedulers.boundedElastic())
                    .flatMap(res -> {
                        if (!Objects.equals(res.getCode(), 200)) {
                            return Mono.empty();
                        }
                        String ids = res.getResult().getSongs().stream().map(SearchResponse.Song::getId).limit(3)
                                .collect(Collectors.joining(","));
                        Map<String,SearchResponse.Song > songMap = res.getResult().getSongs().stream()
                                .collect(Collectors.toMap(SearchResponse.Song::getId, Function.identity()));
                        return webClient.get().uri(baseUrl+"/song/url?id="+ids).retrieve()
                                .bodyToMono(SongInfoResponse.class).flatMap(song -> {
                                    if (Objects.equals(200, song.getCode()) && song.getData().size() > 0) {
                                        List<SongInfoResponse.ResultSong> data = song.getData();
                                        for (SongInfoResponse.ResultSong datum : data) {
                                            SearchResponse.Song innerSong = songMap.get(datum.getId());
                                            datum.setName(innerSong.getName());
                                            datum.setArtistName(ObjectUtils.isEmpty(innerSong.getArtists()) ? null
                                                    : innerSong.getArtists().get(0).getName());
                                        }
                                        return Mono.just(data);
                                    }
                                    return Mono.empty();
                                });
                    });
        } else {
            return webClient.get().uri(baseUrl+"/search?keywords="+keyword+"&type=100").retrieve()
                    .bodyToMono(SingerResponse.class)
                    .delaySubscription(Duration.ofMillis(300), Schedulers.boundedElastic())
                    .flatMap(res -> {
                        if (!Objects.equals(res.getCode(), 200) && res.getResult().getArtists().size() == 0) {
                            return Mono.empty();
                        }
                        String id = res.getResult().getArtists().get(0).getId();
                        return webClient.get().uri(baseUrl+"/artist/top/song?id="+id).retrieve()
                                .bodyToMono(SingerSongsResponse.class)
                                .delaySubscription(Duration.ofMillis(300), Schedulers.boundedElastic())
                                .flatMap(song -> {
                                    if (Objects.equals(200, song.getCode()) && song.getSongs().size() > 0) {
                                        String ids = song.getSongs().stream().limit(3)
                                                .map(SingerSongsResponse.Song::getId).collect(Collectors.joining(","));
                                        Map<String, SingerSongsResponse.Song> songMap = song.getSongs().stream()
                                                .collect(Collectors.toMap(SingerSongsResponse.Song::getId,
                                                        Function.identity()));
                                        return webClient.get().uri(baseUrl+"/song/url/v1?id="+ids).retrieve()
                                                .bodyToMono(SongInfoResponse.class).flatMap(so -> {
                                                    if (Objects.equals(200, song.getCode())
                                                            && so.getData().size() > 0) {
                                                        List<SongInfoResponse.ResultSong> data = so.getData();
                                                        for (SongInfoResponse.ResultSong datum : data) {
                                                            
                                                            SingerSongsResponse.Song innerSong = songMap.get(datum.getId());
                                                            datum.setName(innerSong.getName());
                                                            datum.setArtistName(ObjectUtils.isEmpty(innerSong.getAr()) ? null
                                                                    : innerSong.getAr().get(0).getName());
                                                        }
                                                        return Mono.just(data);
                                                    }
                                                    return Mono.empty();
                                                });
                                    }
                                    return Mono.empty();
                                });
                    });
        }
        
    }
    
}

