package com.backendsys.modules.sdk.klingai.service.impl;

import cn.hutool.core.convert.Convert;
import com.backendsys.modules.common.Filter.WebClientFilter;
import com.backendsys.modules.sdk.klingai.config.KLingConfig;
import com.backendsys.modules.sdk.klingai.entity.KLGenerationImageParams;
import com.backendsys.modules.sdk.klingai.entity.KLImage2VideoParams;
import com.backendsys.modules.sdk.klingai.entity.KLResponse;
import com.backendsys.modules.sdk.klingai.entity.KLText2VideoParams;
import com.backendsys.modules.sdk.klingai.service.KLingService;

import com.backendsys.modules.sdk.klingai.utils.KLingUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

/**
 * 可灵 - 接口费用
 * https://app.klingai.com/cn/dev/document-api/productBilling/prePaidResourcePackage
 * 可灵 - 购买链接
 * - 图片：https://klingai.com/cn/dev/model/image
 * - 视频：https://klingai.com/cn/dev/model/video
 */
@Service
public class KLingServiceImpl implements KLingService {

    @Autowired
    private KLingConfig config;

    @Autowired
    private KLingUtil kLingUtil;

    private WebClient webClient;
    public WebClient getWebClient() {
        if (webClient == null) {
            webClient = WebClient.builder().baseUrl(config.URL).filter(WebClientFilter.logFilter).build();
        }
        return webClient;
    }


    /**
     * 6-1 查询账号下资源包列表及余量
     */
    @Override
    public Mono<KLResponse> queryAccountCosts() {

        // 获取当前时间的 Unix 时间戳（单位：毫秒）
//        long endTime = System.currentTimeMillis();
        long endTime = 1749198917406L;
        // 计算一小时前的时间戳（单位：毫秒）（1 小时 = 3600000 毫秒）
//        long startTime = endTime - 3600000;
        long startTime = 1749195317406L;

        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("start_time", Convert.toStr(startTime));          // Unix时间戳、单位ms
        params.add("end_time", Convert.toStr(endTime));

        System.out.println("params = " + params);
        // params = {start_time=[1749195317406], end_time=[1749198917406]}

        String url = "/account/costs";
        String uri = UriComponentsBuilder.fromUriString(url).queryParams(params).toUriString();
        WebClient webClient = getWebClient();
        return webClient.get()
                .uri(uri)
                .headers(kLingUtil.getHttpHeaders())
                .accept(MediaType.APPLICATION_JSON)
//                .retrieve()
//                .bodyToMono(KLResponse.class);
                .exchangeToMono(response -> {
                    if (response.statusCode().is2xxSuccessful()) {
                        return response.bodyToMono(KLResponse.class); // 成功响应
                    } else {
                        return response.bodyToMono(KLResponse.class).map(e -> KLingUtil.mapErrorResponse(e));
                    }
                });

        /*
            返回值：{
                "code": 0,
                "msg": "success",
                "resource_pack_subscribe_infos": [
                    {
                        "resource_pack_name": "试用-视频生成-100-3并发-1个月",
                        "resource_pack_id": "754492101828186181",
                        "resource_pack_type": "decreasing_total",
                        "total_quantity": 100.0,
                        "remaining_quantity": 100.0,
                        "purchase_time": 1749197892513,
                        "effective_time": 1749197892509,
                        "invalid_time": 1751789892509,
                        "status": "online"
                    }
                ]
            }
         */
    }

    /**
     * 2-1【图像生成】创建任务
     */
    @Override
    public Mono<KLResponse> generationImage(KLGenerationImageParams params) {
        String url = "/v1/images/generations";
        WebClient webClient = getWebClient();
        return webClient.post()
                .uri(url)
                .headers(kLingUtil.getHttpHeaders())
                .accept(MediaType.APPLICATION_JSON)
                .bodyValue(params)
//                .retrieve()
//                .bodyToMono(KLResponse.class);
                .exchangeToMono(response -> {
                    if (response.statusCode().is2xxSuccessful()) {
                        return response.bodyToMono(KLResponse.class); // 成功响应
                    } else {
                        return response.bodyToMono(KLResponse.class).map(e -> KLingUtil.mapErrorResponse(e));
                    }
                });
    }

    /**
     * 2-2【图像生成】查询任务（单个）
     * Mono<Object> responseMono = klingService.queryImageTask(task_id);
     * responseMono.block();                                                // 同步发起订阅
     * responseMono.subscribe(response -> System.out.println(response));    // 异步发起订阅
     * responseMono.subscribe().dispose();                                  // 异步中断/取消订阅
     */
    public Mono<KLResponse> queryImageTask(String task_id) {
        //
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("task_id", task_id);
        //
        String url = "/v1/images/generations";
        String uri = UriComponentsBuilder.fromUriString(url).queryParams(params).toUriString();
        WebClient webClient = getWebClient();
        return webClient.get()
                .uri(uri)
                .headers(kLingUtil.getHttpHeaders())
                .accept(MediaType.APPLICATION_JSON)
                .exchangeToMono(response -> {
                    if (response.statusCode().is2xxSuccessful()) {
                        return response.bodyToMono(KLResponse.class); // 成功响应
                    } else {
                        return response.bodyToMono(KLResponse.class).map(e -> KLingUtil.mapErrorResponse(e));
                    }
                });
    }


    /**
     * 3-1【文生视频】创建任务
     */
    @Override
    public Mono<KLResponse> text2Video(KLText2VideoParams params) {
        String url = "/v1/videos/text2video";
        WebClient webClient = getWebClient();
        return webClient.post()
                .uri(url)
                .headers(kLingUtil.getHttpHeaders())
                .accept(MediaType.APPLICATION_JSON)
                .bodyValue(params)
                .exchangeToMono(response -> {
                    if (response.statusCode().is2xxSuccessful()) {
                        return response.bodyToMono(KLResponse.class); // 成功响应
                    } else {
                        return response.bodyToMono(KLResponse.class).map(e -> KLingUtil.mapErrorResponse(e));
                    }
                });
        /*
            {
                "code": 0,
                "message": "SUCCEED",
                "request_id": "43baa609-8082-495a-b3a3-e5b45b03302b",
                "data": {
                    "task_id": "760138163112644666",
                    "task_status": "submitted",
                    "task_info": {},
                    "created_at": 1749259579553,
                    "updated_at": 1749259579553
                }
            }
         */
    }

    /**
     * 3-2【文生视频】查询任务（单个）
     */
    @Override
    public Mono<KLResponse> queryText2VideoTask(String task_id) {
        String url = "/v1/videos/text2video/" + task_id;
        String uri = UriComponentsBuilder.fromUriString(url).toUriString();
        WebClient webClient = getWebClient();
        return webClient.get()
                .uri(uri)
                .headers(kLingUtil.getHttpHeaders())
                .accept(MediaType.APPLICATION_JSON)
                .exchangeToMono(response -> {
                    if (response.statusCode().is2xxSuccessful()) {
                        return response.bodyToMono(KLResponse.class); // 成功响应
                    } else {
                        return response.bodyToMono(KLResponse.class).map(e -> KLingUtil.mapErrorResponse(e));
                    }
                });
        /*
            生成中：{
                "code": 0,
                "message": "SUCCEED",
                "request_id": "bfe78281-13cb-41f9-9a90-dda55dbeaeb6",
                "data": {
                    "task_id": "760138163112644666",
                    "task_status": "processing",
                    "task_info": {},
                    "task_result": {},
                    "task_status_msg": "",
                    "created_at": 1749259579553,
                    "updated_at": 1749259580965
                }
            }
            生成成功：
            {
                "code": 0,
                "message": "SUCCEED",
                "request_id": "b48d2799-63ac-435d-a546-01bf7c8f315d",
                "data": {
                    "task_id": "760138163112644666",
                    "task_status": "succeed",
                    "task_info": {},
                    "task_result": {
                        "videos": [
                            {
                                "id": "760138163221712948",
                                "url": "https://v2-kling.kechuangai.com/bs2/upload-ylab-stunt/special-effect/output/KLingMuse_77918a74-5665-4e50-9cbc-fd9f02f33d31/6566829430832074447/output.mp4?x-kcdn-pid=112452",
                                "duration": "5.1"
                            }
                        ]
                    },
                    "task_status_msg": "",
                    "created_at": 1749259579553,
                    "updated_at": 1749259891298
                }
            }
         */
    }


    /**
     * 3-4【图生视频】创建任务
     */
    @Override
    public Mono<KLResponse> image2Video(KLImage2VideoParams params) {
        String url = "/v1/videos/image2video";
        WebClient webClient = getWebClient();
        return webClient.post()
                .uri(url)
                .headers(kLingUtil.getHttpHeaders())
                .accept(MediaType.APPLICATION_JSON)
                .bodyValue(params)
                .exchangeToMono(response -> {
                    if (response.statusCode().is2xxSuccessful()) {
                        return response.bodyToMono(KLResponse.class); // 成功响应
                    } else {
                        return response.bodyToMono(KLResponse.class).map(e -> KLingUtil.mapErrorResponse(e));
                    }
                });
    }

    /**
     * 3-5【图生视频】查询任务（单个）
     */
    @Override
    public Mono<KLResponse> queryImage2VideoTask(String task_id) {
        String url = "/v1/videos/image2video/" + task_id;
        String uri = UriComponentsBuilder.fromUriString(url).toUriString();
        WebClient webClient = getWebClient();
        return webClient.get()
                .uri(uri)
                .headers(kLingUtil.getHttpHeaders())
                .accept(MediaType.APPLICATION_JSON)
                .exchangeToMono(response -> {
                    if (response.statusCode().is2xxSuccessful()) {
                        return response.bodyToMono(KLResponse.class); // 成功响应
                    } else {
                        return response.bodyToMono(KLResponse.class).map(e -> KLingUtil.mapErrorResponse(e));
                    }
                });
        /*
            {
            "code": 0,
            "message": "SUCCEED",
            "request_id": "a2fc31fe-169a-4da7-a2af-95a7016d4ff0",
            "data": {
                "task_id": "760160433335980080",
                "task_status": "succeed",
                "task_info": {},
                "task_result": {
                    "videos": [
                        {
                            "id": "760160433428238374",
                            "url": "https://v2-kling.kechuangai.com/bs2/upload-ylab-stunt/special-effect/output/KLingMuse_e6b349c2-40cc-40e5-a091-456ab6223e2e/8193360782519293624/output.mp4?x-kcdn-pid=112452",
                            "duration": "5.1"
                        }
                    ]
                },
                "task_status_msg": "",
                "created_at": 1749264889187,
                "updated_at": 1749265118666
            }
         */
    }

}
