package com.backendsys.service.SDKService.SDKBaidu;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.backendsys.entity.Ai.AiGenerateVideoCustom.*;
import com.backendsys.entity.Ai.AiGenerateVideoDTO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service
public class SDKBaiduAiGenerateVideoServiceImpl implements SDKBaiduAiGenerateVideoService {

    @Value("${baidu.ai.client-id}")
    private String clientId;
    @Value("${baidu.ai.client-secret}")
    private String clientSecret;


    /**
     * 获得 access_token
     * https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhu
     * {
     * 	"refresh_token": "25.2cc7890efdaef3223729bfe870249403.315360000.2027401315.282335-55087572",
     * 	"expires_in": 2592000,
     * 	"session_key": "9mzdCrKiywHbed9UQ/MDo2KRhrNxg+L8Mvp9klZEYBeHId1O8BTKz/Ud981xDGaKWwtPsVtXv/6KHsCX4G8kcwrK4YK5OQ==",
     * 	"access_token": "24.16ce8eec8a41041a986e66b284ac649e.2592000.1714633315.282335-55087572",
     * 	"scope": "audio_voice_assistant_get audio_tts_post brain_speech_realtime public brain_all_scope brain_ernievilg_txt2img brain_rpc_ernievilg_v2 brain_ttv_material wise_adapt lebo_resource_base lightservice_public hetu_basic lightcms_map_poi kaidian_kaidian ApsMisTest_Test权限 vis-classify_flower lpq_开放 cop_helloScope ApsMis_fangdi_permission smartapp_snsapi_base smartapp_mapp_dev_manage iop_autocar oauth_tp_app smartapp_smart_game_openapi oauth_sessionkey smartapp_swanid_verify smartapp_opensource_openapi smartapp_opensource_recapi fake_face_detect_开放Scope vis-ocr_虚拟人物助理 idl-video_虚拟人物助理 smartapp_component smartapp_search_plugin avatar_video_test b2b_tp_openapi b2b_tp_openapi_online smartapp_gov_aladin_to_xcx",
     * 	"session_secret": "f89c1e73564a9f6c60ba14d9ad39d3c3"
     * }
     */
    private Map<String, Object> getAccessToken() {

        String url = "https://aip.baidubce.com/oauth/2.0/token";
        URI uriWithParams = UriComponentsBuilder.fromUriString(url)
                .queryParam("grant_type", "client_credentials")
                .queryParam("client_id", clientId)
                .queryParam("client_secret", clientSecret)
                .build().toUri();

        // Http 远程调用
        Map<String, Object> resp = WebClient.create()
                .method(HttpMethod.POST)
                .uri(uriWithParams)
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .retrieve().bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
                })
                .block();

        return resp;
    }
    /**
     * [方法] 拼接授权过的 AccessToken URL
     */
    public URI getUriWithParams(String url) {
        Map<String, Object> respToken = getAccessToken();
        String access_token = (String) respToken.get("access_token");
        URI uriWithParams = UriComponentsBuilder.fromUriString(url)
                .queryParam("access_token", access_token)
                .build().toUri();
        return uriWithParams;
    }



    /**
     * [方法] 将接口入参 (MediaTtv) 转换为 符合SDK接口的格式 (BaiduBceMediaJob)
     */
    private AiGenerateVideoCustomDTO formatCustom(AiGenerateVideoDTO aiGenerateVideoDTO) {

        System.out.println("----------------------------------");
        System.out.println(aiGenerateVideoDTO);

        AiGenerateVideoCustomDTO customDTO = new AiGenerateVideoCustomDTO();
        SourceDTO sourceDTO = new SourceDTO();
        ConfigDTO configDTO = new ConfigDTO();

        // -- source ------------------------------------------------------------
        String source = aiGenerateVideoDTO.getSource();
        // \"structs\":[{\"type\":\"text\",\"text\":\"夕阳如红色绸带轻轻拂过天际，悄然间，大地沐浴在金色的温柔中。\"},{\"type\":\"image\",\"mediaSource\":{\"type\":3,\"url\":\"http://dev.manage.daoguyujia.com/assets/p1.jpg\"}}]
        JSONObject sourceJSON = JSONUtil.parseObj(source);
        JSONArray structs = (JSONArray) sourceJSON.get("structs");

        List<SourceStructDTO> StructList = new ArrayList<>();
        for (int i=0; i < structs.size(); i++) {
            SourceStructDTO sourceStructDTO = new SourceStructDTO();
            //
            JSONObject obj = structs.getJSONObject(i);
            String type = (String) obj.get("type");
            sourceStructDTO.setType(type);
            if (type.equals("text")) {
                String text = (String) obj.get("text");
                sourceStructDTO.setText(text);
            }
            if (type.equals("image")) {
                MediaSourceVO mediaSourceVO = new MediaSourceVO();
                JSONObject mediaSourceObj = (JSONObject) obj.get("mediaSource");
                mediaSourceVO.setType(3);
                mediaSourceVO.setUrl((String) mediaSourceObj.get("url"));

                sourceStructDTO.setMediaSource(mediaSourceVO);
            }
            //
            StructList.add(sourceStructDTO);
        }
        // -------------------------------------------------------------------------
        sourceDTO.setStructs(StructList);
        // -------------------------------------------------------------------------
        customDTO.setSource(sourceDTO);
        // -------------------------------------------------------------------------

        // -- config ---------------------------------------------------------------
        configDTO.setResolution(aiGenerateVideoDTO.getResolution());
        configDTO.setProductType(aiGenerateVideoDTO.getProduct_type());
        configDTO.setTtsPer(aiGenerateVideoDTO.getTts_per());
        // -------------------------------------------------------------------------
        // -- config.bgMusic.mediaSource (背景图) -----------------------------------
        String bg_music_url = aiGenerateVideoDTO.getBg_music_url();
        if (StrUtil.isNotBlank(bg_music_url)) {
            ConfigBgMusicDTO bgMusicDTO = new ConfigBgMusicDTO();

            MediaSourceVO mediaSourceVO = new MediaSourceVO();
            mediaSourceVO.setType(3);
            mediaSourceVO.setUrl(bg_music_url);
            bgMusicDTO.setMediaSource(mediaSourceVO);

            configDTO.setBgMusic(bgMusicDTO);
        }
        // -------------------------------------------------------------------------
        // -- config.videoBegin.mediaSource (片头) ----------------------------------
        String video_begin_url = aiGenerateVideoDTO.getVideo_begin_url();
        if (StrUtil.isNotBlank(video_begin_url)) {
            ConfigVideoBeginDTO videoBeginDTO = new ConfigVideoBeginDTO();

            MediaSourceVO mediaSourceVO = new MediaSourceVO();
            mediaSourceVO.setType(3);
            mediaSourceVO.setUrl(video_begin_url);
            videoBeginDTO.setMediaSource(mediaSourceVO);

            configDTO.setVideoBegin(videoBeginDTO);
        }
        // -------------------------------------------------------------------------
        // -- config.videoEnd.mediaSource (片尾) ------------------------------------
        String video_end_url = aiGenerateVideoDTO.getVideo_end_url();
        if (StrUtil.isNotBlank(video_end_url)) {
            ConfigVideoEndDTO videoEndDTO = new ConfigVideoEndDTO();

            MediaSourceVO mediaSourceVO = new MediaSourceVO();
            mediaSourceVO.setType(3);
            mediaSourceVO.setUrl(video_end_url);
            videoEndDTO.setMediaSource(mediaSourceVO);

            configDTO.setVideoEnd(videoEndDTO);
        }
        // -------------------------------------------------------------------------
        // -- config.videoLogo (LOGO) ----------------------------------------------
        String video_logo_url = aiGenerateVideoDTO.getVideo_logo_url();
        if (StrUtil.isNotBlank(video_logo_url)) {
            ConfigVideoLogoDTO videoLogoDTO = new ConfigVideoLogoDTO();

            MediaSourceVO mediaSourceVO = new MediaSourceVO();
            mediaSourceVO.setType(3);
            mediaSourceVO.setUrl(video_logo_url);
            videoLogoDTO.setMediaSource(mediaSourceVO);

            String video_logo_location = aiGenerateVideoDTO.getVideo_logo_location();
            Integer video_logo_margin = aiGenerateVideoDTO.getVideo_logo_margin();
            if (StrUtil.isNotBlank(video_logo_location)) {
                videoLogoDTO.setLocation(video_logo_location);
            }
            if (video_logo_margin != null) {
                videoLogoDTO.setMargin(video_logo_margin);
            }
            configDTO.setVideoLogo(videoLogoDTO);
        }
        // -------------------------------------------------------------------------
        System.out.println("configDTO:");
        System.out.println(configDTO);

        customDTO.setConfig(configDTO);
        // -------------------------------------------------------------------------

        return customDTO;
    }

    /**
     * [百度-AI成片] 定制成片任务
     */
    public Map<String, Object> makeGenerateVideo(AiGenerateVideoDTO aiGenerateVideoDTO) {
        // 将 [本地入参格式] 转换为 [远程入参格式]
        AiGenerateVideoCustomDTO customDTO = formatCustom(aiGenerateVideoDTO);
            System.out.println("-- customDTO: ------------------");
            System.out.println(customDTO);

        // Http 远程调用
        URI uriWithParams = getUriWithParams("https://aip.baidubce.com/rpc/2.0/brain/creative/ttv/material");
        Map<String, Object> resp = WebClient.create()
            .method(HttpMethod.POST)
            .uri(uriWithParams)
            .bodyValue(customDTO)
            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .retrieve().bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
            })
            .block();
        return resp;
    }

    // [百度-AI成片] 查询成片任务进度
    public Map<String, Object> getGenerateVideoProgress(Long jobId) {
        // Body 参数
        Map<String, Object> resultMap = new LinkedHashMap<>();
            resultMap.put("jobId", jobId);
        String bodyData = JSONUtil.toJsonStr(resultMap);

        // Http 远程调用
        URI uriWithParams = getUriWithParams("https://aip.baidubce.com/rpc/2.0/brain/creative/ttv/query");
        Map<String, Object> resp = WebClient.create()
                .method(HttpMethod.POST)
                .uri(uriWithParams)
                .bodyValue(bodyData.toString())
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .retrieve().bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
                })
                .block();

        System.out.println("getGenerateVideoProgress resp:");
        System.out.println(resp);
        return resp;
    }
}
