package com.yanzhu.module.ai.framework.ai.core.model.wenduoduo.api;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.yanzhu.framework.common.exception.ServiceException;
import com.yanzhu.framework.common.util.json.JsonUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.List;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;

import static org.springframework.http.HttpStatus.Series.CLIENT_ERROR;
import static org.springframework.http.HttpStatus.Series.SERVER_ERROR;

/**
 * 文多多 PPT 生成 API
 *
 * @author 研筑科技
 */
@Slf4j
public class WenDuoDuoPptApi {

    private final RestTemplate restTemplate;
    private final String baseUrl;

    public WenDuoDuoPptApi(String baseUrl) {
        this.restTemplate = new RestTemplate();
        this.baseUrl = baseUrl;
    }



    /**
     * 创建 Token
     *
     * @param request 请求体
     * @return Token
     */
    public String createToken(CreateTokenRequest request) {
        Assert.notNull(request, "请求体不能为空");
        Assert.notNull(request.getApiKey(), "API Key 不能为空");

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        
        HttpEntity<CreateTokenRequest> entity = new HttpEntity<>(request, headers);
        
        try {
            ResponseEntity<ApiResponse> response = restTemplate.exchange(
                    baseUrl + "/api/ppt/v2/createToken",
                    HttpMethod.POST,
                    entity,
                    ApiResponse.class
            );
            
            if (response.getStatusCode().series() == CLIENT_ERROR || response.getStatusCode().series() == SERVER_ERROR) {
                log.error("调用文多多 PPT API 异常，参数：{}，状态码：{}，响应：{}", JsonUtils.toJsonString(request), response.getStatusCode(), response.getBody());
                throw new ServiceException(500, "调用文多多 PPT API 异常：" + (response.getBody() != null ? "未知错误" : "未知错误"));
            }
            
            ApiResponse apiResponse = response.getBody();
            if (apiResponse == null || apiResponse.getCode() != 0) {
                throw new IllegalStateException("创建 Token 异常，" + (apiResponse != null ? apiResponse.getMessage() : "响应为空"));
            }
            
            Object tokenObj = apiResponse.getData().get("token");
            if (tokenObj == null) {
                throw new IllegalStateException("创建 Token 异常，返回数据中缺少token");
            }
            
            return Objects.requireNonNull(tokenObj.toString());
        } catch (Exception e) {
            if (e instanceof ServiceException || e instanceof IllegalStateException) {
                throw e;
            }
            log.error("调用文多多 PPT API 异常，参数：{}", JsonUtils.toJsonString(request), e);
            throw new ServiceException(500, "调用文多多 PPT API 异常：" + e.getMessage());
        }
    }

    /**
     * 创建任务
     *
     * @param token   令牌
     * @param type    类型
     * @param content 内容
     * @param files   文件
     * @return 任务 ID
     */
    public String createTask(String token, Integer type, String content, List<MultipartFile> files) {
        Assert.notNull(token, "令牌不能为空");
        Assert.notNull(type, "类型不能为空");

        MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
        formData.add("token", token);
        formData.add("type", type);
        if (content != null) {
            formData.add("content", content);
        }
        if (files != null) {
            for (MultipartFile file : files) {
                formData.add("file", file.getResource());
            }
        }
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        
        HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(formData, headers);
        
        try {
            ResponseEntity<ApiResponse> response = restTemplate.exchange(
                    baseUrl + "/api/ppt/v2/createTask",
                    HttpMethod.POST,
                    entity,
                    ApiResponse.class
            );
            
            if (response.getStatusCode().series() == CLIENT_ERROR || response.getStatusCode().series() == SERVER_ERROR) {
                log.error("调用文多多 PPT API 异常，参数：{}，状态码：{}，响应：{}", JsonUtils.toJsonString(formData), response.getStatusCode(), response.getBody());
                throw new ServiceException(500, "调用文多多 PPT API 异常：" + (response.getBody() != null ? response.getBody().getMessage() : "未知错误"));
            }
            
            ApiResponse apiResponse = response.getBody();
            if (apiResponse == null || apiResponse.getCode() != 0) {
                throw new IllegalStateException("创建任务异常，" + (apiResponse != null ? apiResponse.getMessage() : "响应为空"));
            }
            
            Object taskIdObj = apiResponse.getData().get("taskId");
            if (taskIdObj == null) {
                throw new IllegalStateException("创建任务异常，返回数据中缺少taskId");
            }
            
            return Objects.requireNonNull(taskIdObj.toString());
        } catch (Exception e) {
            if (e instanceof ServiceException || e instanceof IllegalStateException) {
                throw e;
            }
            log.error("调用文多多 PPT API 异常，参数：{}", JsonUtils.toJsonString(formData), e);
            throw new ServiceException(500, "调用文多多 PPT API 异常：" + e.getMessage());
        }
    }

    /**
     * 获取生成选项
     *
     * @param lang 语种
     * @return 生成选项
     */
    public Map<String, Object> getOptions(String lang) {
        String uri = "/api/ppt/v2/options";
        if (lang != null) {
            uri += "?lang=" + lang;
        }
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        
        HttpEntity<String> entity = new HttpEntity<>(headers);
        
        try {
            ResponseEntity<ApiResponse> response = restTemplate.exchange(
                    baseUrl + uri,
                    HttpMethod.GET,
                    entity,
                    ApiResponse.class
            );
            
            if (response.getStatusCode().series() == CLIENT_ERROR || response.getStatusCode().series() == SERVER_ERROR) {
                log.error("调用文多多 PPT API 异常，参数：{}，状态码：{}，响应：{}", lang, response.getStatusCode(), response.getBody());
                throw new ServiceException(500, "调用文多多 PPT API 异常：" + (response.getBody() != null ? response.getBody().getMessage() : "未知错误"));
            }
            
            ApiResponse apiResponse = response.getBody();
            if (apiResponse == null || apiResponse.getCode() != 0) {
                throw new IllegalStateException("获取生成选项异常，" + (apiResponse != null ? apiResponse.getMessage() : "响应为空"));
            }
            
            return apiResponse.getData();
        } catch (Exception e) {
            if (e instanceof ServiceException || e instanceof IllegalStateException) {
                throw e;
            }
            log.error("调用文多多 PPT API 异常，参数：{}", lang, e);
            throw new ServiceException(500, "调用文多多 PPT API 异常：" + e.getMessage());
        }
    }

    /**
     * 分页查询 PPT 模板
     *
     * @param request 请求体
     * @return 模板列表
     */
    public PagePptTemplateInfo getTemplatePage(TemplateQueryRequest request) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        
        HttpEntity<TemplateQueryRequest> entity = new HttpEntity<>(request, headers);
        
        try {
            ResponseEntity<PagePptTemplateInfo> response = restTemplate.exchange(
                    baseUrl + "/api/ppt/templates",
                    HttpMethod.POST,
                    entity,
                    PagePptTemplateInfo.class
            );
            
            if (response.getStatusCode().series() == CLIENT_ERROR || response.getStatusCode().series() == SERVER_ERROR) {
                log.error("调用文多多 PPT API 异常，参数：{}，状态码：{}，响应：{}", JsonUtils.toJsonString(request), response.getStatusCode(), response.getBody());
                throw new ServiceException(500, "调用文多多 PPT API 异常：" + (response.getBody() != null ? "未知错误" : "未知错误"));
            }
            
            return response.getBody();
        } catch (Exception e) {
            if (e instanceof ServiceException || e instanceof IllegalStateException) {
                throw e;
            }
            log.error("调用文多多 PPT API 异常，参数：{}", JsonUtils.toJsonString(request), e);
            throw new ServiceException(500, "调用文多多 PPT API 异常：" + e.getMessage());
        }
    }

    /**
     * 生成大纲内容
     *
     * @return 大纲内容（暂时不支持流式响应）
     */
    public List<Map<String, Object>> createOutline(CreateOutlineRequest request) {
        // 注意：由于JDK 1.8不支持Reactor，无法实现流式响应，这里返回完整的响应
        throw new UnsupportedOperationException("当前版本不支持流式响应，请使用其他API");
    }

    /**
     * 修改大纲内容
     *
     * @param request 请求体
     * @return 大纲内容（暂时不支持流式响应）
     */
    public List<Map<String, Object>> updateOutline(UpdateOutlineRequest request) {
        // 注意：由于JDK 1.8不支持Reactor，无法实现流式响应，这里返回完整的响应
        throw new UnsupportedOperationException("当前版本不支持流式响应，请使用其他API");
    }

    /**
     * 生成 PPT
     *
     * @return PPT信息
     */
    public PptInfo create(PptCreateRequest request) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        
        HttpEntity<PptCreateRequest> entity = new HttpEntity<>(request, headers);
        
        try {
            ResponseEntity<ApiResponse> response = restTemplate.exchange(
                    baseUrl + "/api/ppt/v2/generatePptx",
                    HttpMethod.POST,
                    entity,
                    ApiResponse.class
            );
            
            if (response.getStatusCode().series() == CLIENT_ERROR || response.getStatusCode().series() == SERVER_ERROR) {
                log.error("调用文多多 PPT API 异常，参数：{}，状态码：{}，响应：{}", JsonUtils.toJsonString(request), response.getStatusCode(), response.getBody());
                throw new ServiceException(500, "调用文多多 PPT API 异常：" + (response.getBody() != null ? response.getBody().getMessage() : "未知错误"));
            }
            
            ApiResponse apiResponse = response.getBody();
            if (apiResponse == null || apiResponse.getCode() != 0) {
                throw new IllegalStateException("生成 PPT 异常，" + (apiResponse != null ? apiResponse.getMessage() : "响应为空"));
            }
            
            Object pptInfoObj = apiResponse.getData().get("pptInfo");
            if (pptInfoObj == null) {
                throw new IllegalStateException("生成 PPT 异常，返回数据中缺少pptInfo");
            }
            
            return Objects.requireNonNull(JsonUtils.parseObject(JsonUtils.toJsonString(pptInfoObj), PptInfo.class));
        } catch (Exception e) {
            if (e instanceof ServiceException || e instanceof IllegalStateException) {
                throw e;
            }
            log.error("调用文多多 PPT API 异常，参数：{}", JsonUtils.toJsonString(request), e);
            throw new ServiceException(500, "调用文多多 PPT API 异常：" + e.getMessage());
        }
    }

    /**
     * 创建 Token 请求参数
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class CreateTokenRequest {
        private String apiKey;
        private String uid;
        private Integer limit;

        public CreateTokenRequest(String apiKey) {
            this(apiKey, null, null);
        }
    }

    /**
     * API 通用响应
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class ApiResponse {
        private Integer code;
        private String message;
        private Map<String, Object> data;
    }

    /**
     * 创建任务
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class CreateTaskRequest {
        private Integer type;
        private String content;
        private List<MultipartFile> files;
    }

    /**
     * 生成大纲内容请求
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class CreateOutlineRequest {
        private String id;
        private String length;
        private String scene;
        private String audience;
        private String lang;
        private String prompt;
    }

    /**
     * 修改大纲内容请求
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class UpdateOutlineRequest {
        private String id;
        private String markdown;
        private String question;
    }

    /**
     * 生成 PPT 请求参数
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class PptCreateRequest {
        private String id;
        private String templateId;
        private String markdown;
    }

    /**
     * PPT 信息
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class PptInfo {
        private String id;
        private String name;
        private String subject;
        private String coverUrl;
        private String fileUrl;
        private String templateId;
        private String pptxProperty;
        private String userId;
        private String userName;
        private int companyId;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime updateTime;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTime;
        private String createUser;
        private String updateUser;
    }

    /**
     * 模板查询请求参数
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class TemplateQueryRequest {
        private Integer page;
        private Integer size;
        private Filter filter;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class Filter {
        private String type;
        private String industry;
        private String scene;
    }

    /**
     * 分页查询 PPT 模板响应
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class PagePptTemplateInfo {
        private Integer total;
        private List<PptTemplateInfo> list;
    }

    /**
     * PPT 模板信息
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class PptTemplateInfo {
        private String id;
        private String name;
        private String coverUrl;
        private String type;
        private String industry;
        private String scene;
        private String description;
        private Integer sort;
        private Boolean isHot;
        private Boolean isNew;
    }
}