package com.linkwechat.quartz.task;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.linkwechat.common.constant.WeConstans;
import com.linkwechat.common.core.domain.entity.WeCorpAccount;
import com.linkwechat.common.core.elasticsearch.ElasticSearch;
import com.linkwechat.common.core.redis.RedisCache;
import com.linkwechat.wecom.service.*;
import com.tencent.wework.FinanceUtils;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @description: 会话存档定时拉取
 * @author: HaoN
 * @create: 2021-05-31 10:39
 **/
@Slf4j
@Component("FinanceTask")
public class FinanceTask {
    @Autowired
    ElasticSearch elasticSearch;

    @Autowired
    RedisCache redisCache;


    @Autowired
    IWeChatContactMappingService weChatContactMappingService;

    @Autowired
    IWeSensitiveService weSensitiveService;

    @Autowired
    IWeSensitiveActHitService weSensitiveActHitService;


    @Autowired
    IWeCorpAccountService iWeCorpAccountService;



    /**
     *  会话数据拉取
     * @throws IOException
     */
    public void FinanceTask(){
        List<WeCorpAccount> weCorpAccounts = iWeCorpAccountService.list(
                new LambdaQueryWrapper<WeCorpAccount>()
                        .eq(WeCorpAccount::getDelFlag, 1)
                        .eq(WeCorpAccount::getStatus, 1)
        );

        if(CollectionUtil.isNotEmpty(weCorpAccounts)){
            weCorpAccounts.stream().forEach(k->{
                try {
                    if(StrUtil.isNotBlank(k.getCorpId()) && StrUtil.isNotBlank(k.getSecret())){
                        findFinance(k.getCorpId(),k.getSecret(),"ChartKey_"+k.getCorpId(),k.getFinancePrivateKey());
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });

        }

    }


    private void findFinance(String corpId, String secret,String chartKey,String financePrivateKey) throws IOException {

        log.info("执行有参方法: params:{},{}", corpId, secret);
        //创建索引
        elasticSearch.createIndex2(chartKey, elasticSearch.getFinanceMapping());
        //从缓存中获取消息标识
        Object seqObject = Optional.ofNullable(redisCache.getCacheObject(chartKey+"::"+WeConstans.CONTACT_SEQ_KEY)).orElse(0L);
        Long seqLong = Long.valueOf(String.valueOf(seqObject));
        AtomicLong index = new AtomicLong(seqLong);
        if (index.get() == 0) {
            setRedisCacheSeqValue(index,chartKey);
        }

        log.info(">>>>>>>seq:{}", index.get());
        FinanceUtils.initSDK(corpId, secret);
        List<JSONObject> chatDataList = FinanceUtils.getChatData(index.get(),
                "",
                "", redisCache,financePrivateKey);
        if (CollectionUtil.isNotEmpty(chatDataList)) {
            try {
                List<JSONObject> elasticSearchEntities = weChatContactMappingService.saveWeChatContactMapping(chatDataList);
                //获取敏感行为命中信息
                weSensitiveActHitService.hitWeSensitiveAct(chatDataList);
                elasticSearch.insertBatchAsync(chartKey, elasticSearchEntities, weSensitiveService::hitSensitive);
            } catch (Exception e) {
                log.error("消息处理异常：ex:{}", e);
                e.printStackTrace();
            }
        }



    }


    private void setRedisCacheSeqValue(AtomicLong index,String chartKey) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        SortBuilder<?> sortBuilderPrice = SortBuilders.fieldSort(WeConstans.CONTACT_SEQ_KEY).order(SortOrder.DESC);
        searchSourceBuilder.sort(sortBuilderPrice);
        searchSourceBuilder.size(1);
        List<JSONObject> searchResultList = elasticSearch.search(chartKey, searchSourceBuilder, JSONObject.class);
        searchResultList.stream().findFirst().ifPresent(result -> {
            index.set(result.getLong(WeConstans.CONTACT_SEQ_KEY) + 1);
        });
        redisCache.setCacheObject(WeConstans.CONTACT_SEQ_KEY, index);
    }
}
