package org.shop.crop;

import com.alibaba.fastjson.JSON;
import com.tencent.wework.Finance;
import lombok.extern.slf4j.Slf4j;
import org.shop.crop.dto.BaseMessageDto;
import org.shop.crop.dto.ChatData;
import org.shop.crop.dto.Message;
import org.shop.crop.dto.MessagePullResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
@RestController
public class CropController {

    @Autowired
    Long sdk;

    @Autowired
    private Environment environment; // nul

    @GetMapping("/")
    public String index() {
        return "Hello, World!";
    }

    @GetMapping("/crop/chatData")
    private List<Message> chatData(Long startSeq) throws IOException {
        long limit = 1000;
        long slice = Finance.NewSlice();
        int ret = Finance.GetChatData(sdk, startSeq, limit, "", "", 1000, slice);
        if (ret != 0) {
            System.out.println("调用sdk拉取消息接口失败,失败消息为 ret = " + ret);
            Finance.FreeSlice(slice);
            return null;
        }
        String contentResult = Finance.GetContentFromSlice(slice);
        log.info("内容字符串" + contentResult);
        return decodeChatData(contentResult);
    }

    /**
     * 解密chatData数据
     *
     * @param contentResult 拉取到的JSON原文
     */
    public List<Message> decodeChatData(String contentResult) throws IOException {
        // 1.基础信息解析
        List<Message> messageList = new ArrayList<>();
        MessagePullResponse messagePullResponse = JSON.parseObject(contentResult, MessagePullResponse.class);
        if (messagePullResponse == null || messagePullResponse.getChatdata() == null) {
            return Collections.emptyList();
        }
        List<ChatData> chatdataList = messagePullResponse.getChatdata();
        // 2.解密数据
        ClassPathResource resource = new ClassPathResource("private_key.pem");
        if (!resource.exists()) {
            return Collections.emptyList();
        }
        String privateKey = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
        for (ChatData chatData : chatdataList) {
            try {
                // 解密ChatData数据
                String plainTextJson = decrypt(chatData, privateKey);
                BaseMessageDto messageDto = JSON.parseObject(plainTextJson, BaseMessageDto.class);
                // 转换dto数据到entity
                Message message = messageDto.convertToMessage();
                message.setSeq(chatData.getSeq());
                message.setOriginContent(plainTextJson);
                messageList.add(message);
            } catch (Exception e) {
                log.error("解密失败{}", e.getMessage());
                // 收集失败情况数据
                e.printStackTrace();

            }
        }

        // 4.保存消息和失败任务
        return messageList;
    }

    /**
     * 解密数据
     *
     * @param chatData      待解密数据
     * @param privateKeyStr 私钥字符串
     * @return 解密后的原文
     */
    private String decrypt(ChatData chatData, String privateKeyStr) throws Exception {
        // 1.解密EncryptRandomKey
        String randomKey = EncodeUtils.decryptRandomKey(chatData.getEncryptRandomKey(), privateKeyStr);
        // 2.调用SDK方法解密密文数据
        long msg = Finance.NewSlice();
        Finance.DecryptData(sdk, randomKey, chatData.getEncryptChatMsg(), msg);
        String plaintext = Finance.GetContentFromSlice(msg);
        Finance.FreeSlice(msg);
        return plaintext;
    }


}
