package com.backendsys.modules.sdk.baidu.bce.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.backendsys.exception.CustException;
import com.backendsys.modules.ai.media.entity.MediaTtv;
import com.backendsys.modules.ai.media.entity.MediaTtvConfig;
import com.backendsys.modules.ai.media.entity.MediaTtvSource;
import com.backendsys.modules.sdk.baidu.bce.entity.BaiduBceMediaJob;
import com.backendsys.modules.sdk.baidu.bce.entity.BaiduBceMediaJobResult;
import com.backendsys.modules.sdk.baidu.bce.service.BaiduBceMediaService;
import com.backendsys.modules.sdk.baidu.bce.utils.BaiduBceUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;


/**
 * 百度AI成片
 * https://ai.baidu.com/ai-doc/NLP/Zk7ylspjv
 */
@Service
public class BaiduBceMediaServiceImpl implements BaiduBceMediaService {

    @Autowired
    private BaiduBceUtil baiduBceUtil;

    /*
        数据格式转化:
        {\"type\":\"image\",\"mediaSource\":{\"type\":3,\"url\":\"" + imageUrl + "\"}},
        {"\"type\":\"text\",\"text\":\"" + text + "\"}
    */
    private String sourceToParams(List<MediaTtvSource> sourceList) {
        AtomicReference<String> sourceStr = new AtomicReference<>("[");
        for (int i = 0; i < sourceList.size(); i++) {
            String item = "";
            if ("text".equals(sourceList.get(i).getType())) {
                item = "{\"type\":\"text\",\"text\":\"" + sourceList.get(i).getContent() + "\"}";
            }
            if ("image".equals(sourceList.get(i).getType())) {
                item = "{\"type\":\"image\",\"mediaSource\":{\"type\":3,\"url\":\"" + sourceList.get(i).getContent() + "\"}}";
            }
            if (i < sourceList.size() - 1) item += ",";
            sourceStr.set(sourceStr.get() + item);
        }
        sourceStr.set(sourceStr.get() + "]");
        return sourceStr.get();
    }

    /**
     * [百度AI] AI成片-图文转视频
     * https://ai.baidu.com/ai-doc/NLP/Zk7ylspjv
     */
    @Override
    public BaiduBceMediaJob generateMediaTtv(MediaTtv mediaTtv) {

        /*
            入参模板：
            mediaTtv: {
                "title": "测试百度AI成片 (图片+文生语音配音)",
                "source": [
                    { "type": "text", "content": "云渺修仙历经千年，实力超凡，却因身世之谜未解，毅然成为摆渡人。" },
                    { "type": "image", "content": "http://43.138.151.228:3001/2cut_compress.png" }
                ],
                "config": {
                    "tts_voice_type": 4144,
                    "resolution": [1024, 576]
                }
            }
        */


//        // structs: 文本、图片素材内容，文字内容必填，structs中文本总长度在20-800字符之间
//        // mediaSource: 若内容类型type=image，该字段描述图片内容，支持jpg/jpeg/png格式的图片
//        // type: 内容类型，支持image（图片）、text（文字）、video（视频）
//        String imageUrl = "http://43.138.151.228:3001/2.jpg";
//        // 传入图片、视频的url地址，图片、视频总数量不得超过20个，视频总大小不超过1G
//        String text = "夕阳如红色绸带轻轻拂过天际，悄然间，大地沐浴在金色的温柔中。";      // 若内容类型type=text，该字段描述文本内容

//        String source = mediaTtv.getSource();

//        // config: 视频生产配置
//        Integer ttsPer = 4144;                // 支持基础音库、甄选音库，默认4144:度姗姗-女；【基础音库】0:度小美-女、1:度小宇-男、3:度小云-男、4:度小丫-女童、5:度小娇-女、103:度小朵-女童、106:度小博-男、110:度小童-男童、111:度小萌-女、5003:度小遥-男、5118:度小婷-女、4003:度小耀-男、4100:度小雯-女、4103:度小米-男童、4105:度小灵-女、4106:度小文-男、4115:度小贤-男、4117:度小乔-女、4119:度小鹿-女；【甄选音库】4144:度姗姗-女、4140:度小新-女、4143:度清风-男、4129:度小彦-男、4278:度小贝-女、4254:度小清-女、4149:度星河-男
//        String resolution = "[1024,576]";     // 分辨率，横屏支持[1920,1080]、[1280,720]、[1024,576]、竖屏支持[1080,1920]、[720,1280]、[576,1024]



//        String templateId = "";         // 视频模板id，不传则智能匹配，横屏模板支持："30","41","42","43","44","45","46","47","48","49"，竖屏模板支持："40","28","29","31","32","33","34","35","36","37","38","39","50","51","52","53","54","55","56","57","58","59","60","61","62","63","64","65","66","67","68","69","70","71"
//
//        // bgMusic: 背景音乐，支持使用mp3格式，文件大小不超过10M
//        String bgMusicUrl = "";
//        String videoBeginUrl = "";  // videoBegin: 视频片头，大小限制50M，格式为mp4或mov
//        String videoEndUrl = "";
//
//        // caption: 字幕显示设置
//        String marginBottom = "170px";  // 字幕距离视频底部的位置，单位px，支持选择0-500。横屏默认值为70px；竖屏[1080,1920]默认为270px、[720,1280]默认为180px、[576,1024]默认为170px
//        String fontColor = "ffffff";    // 字体颜色，支持传入颜色的十六进制，默认：ffffff
//        Integer fontAlpha = 100;        // 字体透明度，范围：0-100，从透明到不透明，默认：100
//        String bgColor = "927070";      // 字幕背景颜色，支持传入颜色的十六进制，默认：927070
//        Integer bgAlpha = 32;           // 字幕背景透明度，范围：0-100，从透明到不透明，默认32
//
//        String location = "";           // 角标位置，支持：top-left（左上）、top-right（右上），默认为 top-left
//        Integer margin = 20;            // 角标边缘距离，单位px，支持0-100，默认为 20



        String structs = sourceToParams(mediaTtv.getSource());
        MediaTtvConfig config = mediaTtv.getConfig();

        Integer ttsPer = config.getTts_voice_type();
        if (ttsPer == null) throw new CustException("音色参数不能为空");



        Integer[] resolution = config.getResolution();
        if (resolution == null) throw new CustException("分辨率参数不能为空");
        if (resolution.length != 2) throw new CustException("分辨率参数格式不正确，必须是：[数值,数值]");
        // 定义支持的分辨率列表
        List<Integer[]> supportedResolutions = Arrays.asList(
            new Integer[]{1920, 1080}, new Integer[]{1280, 720}, new Integer[]{1024, 576},
            new Integer[]{1080, 1920}, new Integer[]{720, 1280}, new Integer[]{576, 1024}
        );
        Boolean resolutionValid = false;
        for (Integer[] supportedResolution : supportedResolutions) {
            if (Arrays.equals(resolution, supportedResolution)) {
                resolutionValid = true;
            }
        }
        if (!resolutionValid) throw new CustException("分辨率参数格式不支持，必须是：横屏[1920,1080]、[1280,720]、[1024,576]，竖屏[1080,1920]、[720,1280]、[576,1024]");



        String params = "{" +
            "\"source\":{\"structs\":" + structs + "}," +
            "\"config\":{" +
                "\"productType\":\"video\"," +
                "\"ttsPer\":" + ttsPer + "," +
                "\"resolution\":[" + resolution[0] + "," + resolution[1] + "]" +
//                "\"templateId\":\"" + templateId + "\"" +
//                "\"bgMusic\":{" +
//                    "\"mediaSource\":{" +
//                        "\"type\":3," +
//                        "\"url\":\"" + bgMusicUrl + "\"" +
//                    "}"+
//                "}," +
//                "\"videoBegin\":{" +
//                    "\"mediaSource\":{" +
//                        "\"type\":3," +
//                        "\"url\":\"" + videoBeginUrl + "\"" +
//                    "}"+
//                "},"+
//                "\"videoEnd\":{" +
//                    "\"mediaSource\":{" +
//                        "\"type\":3," +
//                        "\"url\":\"" + videoEndUrl + "\"" +
//                    "}"+
//                "},"+
//                "\"caption\":{" +
//                    "\"marginBottom\":\"" + marginBottom + "\"," +
//                    "\"fontColor\":\"" + fontColor + "\"," +
//                    "\"fontAlpha\":" + fontAlpha + "," +
//                    "\"bgColor\":\"" + bgColor + "\"," +
//                    "\"bgAlpha\":" + bgAlpha + "" +
//                "},"+
//                "\"videoLogo\":{" +
//                    "\"mediaSource\":{" +
//                        "\"type\":3," +
//                        "\"url\":\"" + videoEndUrl + "\"" +
//                    "},"+
//                    "\"location\":\"" + location + "\"," +
//                    "\"margin\":" + margin + "" +
//                "}"+
            "}" +
        "}";

        System.out.println("-- [百度AI] AI成片-图文转视频 (Params) -----");
        System.out.println(params);
        System.out.println("-----------------------------------------");

        String access_token = baiduBceUtil.getAccessToken();
        String response = HttpUtil.post("https://aip.baidubce.com/rpc/2.0/brain/creative/ttv/material?access_token=" + access_token, params);
        JSONObject responseJSON = JSONUtil.parseObj(response);
        if (responseJSON.get("error_code") != null) throw new CustException(Convert.toStr(responseJSON.get("error_msg")));

        JSONObject data = JSONUtil.parseObj(responseJSON.get("data"));
        /*
            {
                "data": {
                    "jobId": 1914625923861756991,
                    "id": "1914625923861756991"
                },
                "log_id": 1914625923861756991
            }
         */
        BaiduBceMediaJob job = new BaiduBceMediaJob();
        job.setJob_id(Convert.toStr(data.get("jobId")));
        job.setLog_id(Convert.toStr(responseJSON.get("log_id")));
        job.setRequest_params(params);
        job.setResponse_params(response);
        return job;
    }


    /**
     * [百度AI] AI成片-查询结果
     */
    @Override
    public BaiduBceMediaJobResult queryMediaTtv(String job_id) {

        String params = "{\"jobId\":\"" +  job_id + "\"}";

        // [Post] 查询结果
        String access_token = baiduBceUtil.getAccessToken();
        String response = HttpUtil.post("https://aip.baidubce.com/rpc/2.0/brain/creative/ttv/query?access_token=" + access_token, params);
        JSONObject responseJSON = JSONUtil.parseObj(response);

        // 检查返回值状态
        Integer error_code = Convert.toInt(responseJSON.get("error_code"));
        if (error_code != 0) throw new CustException(Convert.toStr(responseJSON.get("error_msg")));

        // 出参
        JSONObject data = JSONUtil.parseObj(responseJSON.get("data"));
        BaiduBceMediaJobResult result = new BaiduBceMediaJobResult();
        result.setJob_id(job_id);
        Float progress = (data.get("progress") != null) ? Convert.toFloat(data.get("progress")) : 1;
        result.setProgress(progress);
        result.setVideo_origin_url(Convert.toStr(data.get("videoAddr")));
        result.setVideo_url("");
        result.setResponse_params(response);
        return result;
    }

}
