package com.seer.teach.ai.client.model.dashscope;

import com.alibaba.cloud.ai.dashscope.api.DashScopeApi;
import com.alibaba.cloud.ai.dashscope.api.DashScopeAudioSpeechApi;
import com.alibaba.cloud.ai.dashscope.api.DashScopeImageApi;
import com.alibaba.cloud.ai.dashscope.audio.DashScopeAudioSpeechModel;
import com.alibaba.cloud.ai.dashscope.audio.DashScopeAudioSpeechOptions;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import com.alibaba.cloud.ai.dashscope.embedding.DashScopeEmbeddingModel;
import com.alibaba.cloud.ai.dashscope.image.DashScopeImageModel;
import com.alibaba.cloud.ai.dashscope.image.DashScopeImageOptions;
import com.seer.teach.ai.client.model.AbstractAiModelClient;
import com.seer.teach.ai.client.model.config.ModelConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.audio.tts.TextToSpeechModel;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.image.ImageModel;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Optional;

/**
 * DashScope平台模型管理器
 * 专门负责DashScope平台的AI模型管理
 * 使用配置属性进行更灵活的模型初始化
 *
 * @author Captain
 * @since 2025-12-25
 */
@Slf4j
@Component
public class DashScopeModelClient extends AbstractAiModelClient {
    
    @Override
    public String getPlatformName() {
        return "aliyun_bailian";
    }
    
    @Override
    public Optional<ChatModel> createChatModel(ModelConfig modelConfig) {
        DashScopeChatOptions chatOptions = DashScopeChatOptions.builder()
                .withModel(modelConfig.getModel())
                .build();
        
        DashScopeApi dashScopeApi = createDashScopeApi(modelConfig.getApiKey(), modelConfig.getUrl());
        return Optional.of(DashScopeChatModel.builder()
                .dashScopeApi(dashScopeApi)
                .retryTemplate(retryTemplate)
                .toolCallingManager(toolCallingManager)
                .defaultOptions(chatOptions)
                .observationRegistry(observationRegistry)
                .toolExecutionEligibilityPredicate(toolExecutionEligibilityPredicate)
                .build());
    }
    
    @Override
    public Optional<ChatOptions> createChatOptions(Map<String, Object> options) {
        DashScopeChatOptions.DashScopeChatOptionsBuilder builder = DashScopeChatOptions.builder();
        for (Map.Entry<String, Object> entry : options.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            if (value == null) {
                continue;
            }
            switch (key) {
                case "temperature":
                    builder.withTemperature(((Number) value).doubleValue());
                    break;
                case "maxTokens":
                    builder.withMaxToken(((Number) value).intValue());
                    break;
                case "enableSearch":
                    builder.withEnableSearch((Boolean) value);
                    break;
                case "seed":
                    builder.withSeed(((Number) value).intValue());
                    break;
                case "topP":
                    builder.withTopP(((Number) value).doubleValue());
                    break;
                case "topK":
                    builder.withTopK(((Number) value).intValue());
                    break;
                case "enableThinking":
                    builder.withEnableThinking((Boolean) value);
                    break;
                case "repetitionPenalty":
                    builder.withRepetitionPenalty(((Number) value).doubleValue());
                default:
                    break;
            }
        }
        DashScopeChatOptions chatOptions = builder.build();
        return Optional.of(chatOptions);
    }
    
    @Override
    public Optional<ImageModel> createImageModel(ModelConfig modelConfig) {
        DashScopeImageOptions imageOptions = DashScopeImageOptions.builder()
                .withModel(modelConfig.getModel())
                .build();
        
        DashScopeImageApi imageApi = DashScopeImageApi.builder()
                .apiKey(modelConfig.getApiKey())
                .baseUrl(modelConfig.getUrl())
                .restClientBuilder(restClientBuilder)
                .responseErrorHandler(responseErrorHandler)
                .build();
        return Optional.of(new DashScopeImageModel(imageApi, imageOptions, retryTemplate));
    }
    
    @Override
    public Optional<TextToSpeechModel> createTextToSpeechModel(ModelConfig modelConfig) {
        try {
            DashScopeAudioSpeechApi audioSpeechApi = new DashScopeAudioSpeechApi(modelConfig.getApiKey(), modelConfig.getUrl());

            DashScopeAudioSpeechOptions options = DashScopeAudioSpeechOptions.builder()
                    .model(modelConfig.getModel())
                    .voice("longyingxiao")
                    .build();
            DashScopeAudioSpeechModel speechSynthesisModel = new DashScopeAudioSpeechModel(audioSpeechApi, options, retryTemplate);
            return Optional.of(speechSynthesisModel);
        } catch (Exception e) {
            log.error("创建DashScope语音合成模型失败", e);
            return Optional.empty();
        }
    }

    
    @Override
    public Optional<EmbeddingModel> createEmbeddingModel(ModelConfig modelConfig) {
        try {
            DashScopeApi dashScopeApi = createDashScopeApi(modelConfig.getApiKey(), modelConfig.getUrl());

            DashScopeEmbeddingModel embeddingModel = new DashScopeEmbeddingModel(dashScopeApi);

            return Optional.of(embeddingModel);
        } catch (Exception e) {
            log.error("创建DashScope嵌入模型失败", e);
            return Optional.empty();
        }
    }
    
    /**
     * 创建DashScope API实例
     */
    private DashScopeApi createDashScopeApi(String apiKey, String completionsPath) {
        DashScopeApi.Builder builder = DashScopeApi.builder()
                .apiKey(apiKey)
                .baseUrl("https://dashscope.aliyuncs.com");
        // 如果有可用的客户端构建器，添加它们
        if (webClientBuilder != null) {
            builder.webClientBuilder(webClientBuilder);
        }
        if (restClientBuilder != null) {
            builder.restClientBuilder(restClientBuilder);
        }
        if (responseErrorHandler != null) {
            builder.responseErrorHandler(responseErrorHandler);
        }
        return builder.build();
    }
    
    private DashScopeImageApi createDashScopeImageApi(String apiKey, String baseUrl) {
        return DashScopeImageApi.builder()
                .apiKey(apiKey)
                .baseUrl(baseUrl)
                .restClientBuilder(restClientBuilder)
                .responseErrorHandler(responseErrorHandler)
                .build();
    }
}