package cn.com.poc.thirdparty.resource.demand.ai.aggregate.impl;

import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.thirdparty.resource.demand.ai.aggregate.AIDialogueService;
import cn.com.poc.thirdparty.resource.demand.ai.entity.function.FunctionCallResponse;
import cn.com.poc.thirdparty.resource.demand.ai.entity.function.FunctionCallResult;
import cn.com.poc.thirdparty.resource.demand.ai.entity.largemodel.LargeModelDemandResponse;
import cn.com.poc.thirdparty.resource.demand.ai.entity.largemodel.LargeModelDemandResult;
import cn.com.poc.thirdparty.resource.demand.ai.entity.largemodel.LargeModelResponse;
import cn.com.poc.thirdparty.resource.demand.ai.route.DgtoolsApiRoute;
import cn.com.poc.thirdparty.resource.demand.dgTools.DgtoolsAbstractHttpClient;
import cn.com.poc.thirdparty.resource.demand.member.service.DemandAuthService;
import cn.com.yict.framemax.core.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @author alex.yao
 * @date 2023/5/24
 **/

@Component
public class AIDialogueServiceImpl implements AIDialogueService {
    private final String POST = "POST";

    @Value("${dgtools.domain.url}")
    private String DOMAIN_URL;

    @Value(value = "${large-model.apikey}")
    private String API_KEY;

    @Resource
    private DemandAuthService demandAuthService;

    @Resource
    private DgtoolsAbstractHttpClient dgToolsAbstractHttpClient;

    @Override
    public BufferedReader polyStream(LargeModelResponse largeResponse) throws Exception {
        //获取one-api key
        largeResponse.setStream(true);
        LargeModelDemandResponse response = new LargeModelDemandResponse();
        response.setApiKey(API_KEY);
        response.setLargeResponse(largeResponse);
        return largeModelStream(response);
    }

    @Override
    public LargeModelDemandResult poly(LargeModelResponse largeResponse) {
        largeResponse.setStream(false);
        LargeModelDemandResponse response = new LargeModelDemandResponse();
        response.setApiKey(API_KEY);
        response.setLargeResponse(largeResponse);
        return largeModelRequest(response);
    }

    @Override
    public FunctionCallResult functionCall(FunctionCallResponse response) {
        String url = DgtoolsApiRoute.DgtoolsAI.FUNCTION_CALL;
        response.setApiKey(API_KEY);
        List<Header> headers = new ArrayList<Header>() {{
            add(DgtoolsApiRoute.JSON_HEADER);
            add(DgtoolsApiRoute.AI_HEADER);
            add(new BasicHeader(DgtoolsApiRoute.HEADER_X_PLATFORM_AUTHORIZATION, demandAuthService.getToken()));
        }};
        return dgToolsAbstractHttpClient.doRequest(url, response, headers);
    }

    private BufferedReader largeModelStream(LargeModelDemandResponse request) throws IOException {
        String jsonBody = dgToolsAbstractHttpClient.buildJson(request);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = httpClient.execute(RequestBuilder.create(POST)
                .setUri(DOMAIN_URL + DgtoolsApiRoute.BASE_URL + DgtoolsApiRoute.DgtoolsAI.LARGE_MODEL)
                .addHeader(DgtoolsApiRoute.JSON_HEADER)
                .addHeader(DgtoolsApiRoute.AI_HEADER)
                .addHeader(new BasicHeader(DgtoolsApiRoute.HEADER_X_PLATFORM_AUTHORIZATION, demandAuthService.getToken()))
                .setEntity(new StringEntity(jsonBody, StandardCharsets.UTF_8))
                .build()
        );
        InputStream inputStream = httpResponse.getEntity().getContent();
        Header contentType = httpResponse.getFirstHeader("Content-type");
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
        if ("application/json".equals(contentType.getValue()) || "text/plain;charset=UTF-8".equals(contentType.getValue()) || "application/json; charset=utf-8".equals(contentType.getValue())) {
            String res;
            StringBuilder stringBuilder = new StringBuilder();
            while ((res = bufferedReader.readLine()) != null) {
                if (StringUtils.isBlank(res)) {
                    continue;
                }
                stringBuilder.append(res);
            }
            LargeModelDemandResult result = JsonUtils.deSerialize(stringBuilder.toString(), LargeModelDemandResult.class);
            throw new BusinessException(result.getMessage());
        }
        return bufferedReader;
    }

    private LargeModelDemandResult largeModelRequest(LargeModelDemandResponse request) {
        String url = DgtoolsApiRoute.DgtoolsAI.LARGE_MODEL;
        List<Header> headers = new ArrayList<Header>() {{
            add(DgtoolsApiRoute.JSON_HEADER);
            add(DgtoolsApiRoute.AI_HEADER);
            add(new BasicHeader(DgtoolsApiRoute.HEADER_X_PLATFORM_AUTHORIZATION, demandAuthService.getToken()));
        }};
        return dgToolsAbstractHttpClient.doRequest(url, request, headers);
    }


}
