package com.jpsoft.shinestar.modules.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.jpsoft.shinestar.config.YsConfig;
import com.jpsoft.shinestar.modules.common.service.impl.RedisServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class YsUtil {
    @Autowired
    private RedisServiceImpl redisService;

    @Autowired
    private YsConfig ysConfig;

    @Autowired
    private ValueOperations<String,Object> valueOperations;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    public final String TOKEN_PREFIX = "ys_token_";

    public void removeToken(String appKey){
        log.warn("删除token:" + appKey);
        redisTemplate.delete(TOKEN_PREFIX + appKey);
    }

    public String getAccessToken(String appKey,String appSecret){
        String accessToken = (String)valueOperations.get(TOKEN_PREFIX + appKey);

        if(accessToken==null) {
            log.warn("请求萤石云token,key=" + appKey);

            try {
                HttpClient httpClient = HttpClientBuilder.create().build();

                HttpPost httpPost = new HttpPost(ysConfig.getTokenUrl());

                RequestConfig requestConfig = RequestConfig.custom()
                        .setSocketTimeout(3000)
                        .setConnectTimeout(3000)
                        .build();

                httpPost.setConfig(requestConfig);

                MultipartEntityBuilder postBuilder = MultipartEntityBuilder.create();

                postBuilder.addTextBody("appKey",appKey, ContentType.MULTIPART_FORM_DATA);
                postBuilder.addTextBody("appSecret", appSecret, ContentType.MULTIPART_FORM_DATA);

                httpPost.setEntity(postBuilder.build());

                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();

                String responseText = EntityUtils.toString(httpEntity);

                log.warn("萤石云token返回:" + responseText);

                JSONObject json = JSONObject.parseObject(responseText);

                if (json.getString("code").equals("200")){
                    JSONObject data = json.getJSONObject("data");

                    long expireTime = data.getLong("expireTime");
                    accessToken = data.getString("accessToken");

                    valueOperations.set(TOKEN_PREFIX + appKey, accessToken, expireTime, TimeUnit.MICROSECONDS);
                }
            }
            catch (Exception ex){
                log.error(ex.getMessage(),ex);
            }
        }

        return accessToken;
    }

    public JSONObject getLiveAddressUrl(String appKey,String appSecret,String deviceSerial,int channelNo,Long expireTime){
        JSONObject data = null;

        try {
            HttpClient httpClient = HttpClientBuilder.create().build();

            String accessToken = getAccessToken(appKey,appSecret);

            HttpPost httpPost = new HttpPost(ysConfig.getLiveAddressUrl());

            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(3000)
                    .setConnectTimeout(3000)
                    .build();

            httpPost.setConfig(requestConfig);

            MultipartEntityBuilder postBuilder = MultipartEntityBuilder.create();

            postBuilder.addTextBody("accessToken", accessToken, ContentType.MULTIPART_FORM_DATA);
            postBuilder.addTextBody("deviceSerial",deviceSerial, ContentType.MULTIPART_FORM_DATA);
            postBuilder.addTextBody("channelNo",String.valueOf(channelNo), ContentType.MULTIPART_FORM_DATA);
            postBuilder.addTextBody("expireTime",String.valueOf(expireTime), ContentType.MULTIPART_FORM_DATA);

            httpPost.setEntity(postBuilder.build());

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();

            String responseText = EntityUtils.toString(httpEntity);

            log.warn(responseText);

            JSONObject json = JSONObject.parseObject(responseText);

            if (json.getString("code").equals("200")){
                data = json.getJSONObject("data");
            }
            else{
                removeToken(appKey);
            }
        }
        catch (Exception ex){
            log.error(ex.getMessage(),ex);
        }

        return data;
    }

    public JSONObject getDeviceInfo(String appKey,String appSecret,String deviceSerial){
        JSONObject data = null;

        try {
            HttpClient httpClient = HttpClientBuilder.create().build();

            HttpPost httpPost = new HttpPost(ysConfig.getDeviceInfoUrl());

            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(3000)
                    .setConnectTimeout(3000)
                    .build();

            httpPost.setConfig(requestConfig);

            MultipartEntityBuilder postBuilder = MultipartEntityBuilder.create();

            String accessToken = getAccessToken(appKey,appSecret);

            postBuilder.addTextBody("accessToken", accessToken, ContentType.MULTIPART_FORM_DATA);
            postBuilder.addTextBody("deviceSerial",deviceSerial, ContentType.MULTIPART_FORM_DATA);

            httpPost.setEntity(postBuilder.build());

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();

            String responseText = EntityUtils.toString(httpEntity);

            log.warn(responseText);

            JSONObject json = JSONObject.parseObject(responseText);

            if (json.getString("code").equals("200")){
                data = json.getJSONObject("data");
            }
            else{
                removeToken(appKey);
            }
        }
        catch (Exception ex){
            log.error(ex.getMessage(),ex);
        }

        return data;
    }

    public String capturePicture(String appKey,String appSecret,String deviceSerial,int channelNo) {
        String picUrl = "";

        try {
            HttpClient httpClient = HttpClientBuilder.create().build();

            HttpPost httpPost = new HttpPost(ysConfig.getDeviceCaptureUrl());

            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(3000)
                    .setConnectTimeout(3000)
                    .build();

            httpPost.setConfig(requestConfig);

            MultipartEntityBuilder postBuilder = MultipartEntityBuilder.create();

            String accessToken = getAccessToken(appKey,appSecret);

            postBuilder.addTextBody("accessToken", accessToken, ContentType.MULTIPART_FORM_DATA);
            postBuilder.addTextBody("deviceSerial",deviceSerial, ContentType.MULTIPART_FORM_DATA);
            postBuilder.addTextBody("channelNo",String.valueOf(channelNo), ContentType.MULTIPART_FORM_DATA);

            httpPost.setEntity(postBuilder.build());

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();

            String responseText = EntityUtils.toString(httpEntity);

            log.warn(responseText);

            JSONObject json = JSONObject.parseObject(responseText);

            if (json.getString("code").equals("200")){
                JSONObject data = json.getJSONObject("data");
                picUrl = data.getString("picUrl");
            }
            else{
                removeToken(appKey);
            }
        }
        catch (Exception ex){
            log.error(ex.getMessage(),ex);
        }

        return picUrl;
    }
}
