package com.malk.zhuogao.service.impl;

import com.alibaba.fastjson.JSON;
import com.malk.service.dingtalk.DDClient;
import com.malk.service.dingtalk.DDClient_Dedicated;
import com.malk.utils.UtilMap;
import com.malk.zhuogao.repository.dao.ZSDFileRecordDao;
import com.malk.zhuogao.repository.entity.ZSDFileRecordPo;
import com.malk.zhuogao.service.ZSDClient_File;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class ZSDImplClient_File implements ZSDClient_File {

    @Resource
    private ZSDFileRecordDao recordDao;

    /**
     * 查询文件审计记录
     */
    @Override
    public Page<ZSDFileRecordPo> queryRecords(Map<String, String> data, int page, int size) {

        // 分页 & 排序
        Sort sort = Sort.by(Sort.Direction.DESC, "gmtCreateTime");
        Pageable pageable = PageRequest.of(page - 1, size, sort);

        // 卓高查询条件: 匹配员工姓名、操作终端、操作类型、操作来源; 模糊: 知识库名称、接收方名称、文件名称; 日期范围
        Specification<ZSDFileRecordPo> specification = (root, criteriaQuery, criteriaBuilder) -> {

            List<Predicate> predicateList = new ArrayList<>();
            List<String> conditionsEqual = Arrays.asList("realName", "platformView", "actionView", "operateModuleView", "isWorkSpace");
            List<String> conditionsLike = Arrays.asList("workSpaceName", "receiverName", "resource");
            for (String equal : conditionsEqual) {
                if (UtilMap.isNotBlankString(data, equal)) {
                    predicateList.add(criteriaBuilder.equal(root.get(equal), data.get(equal)));
                }
            }
            for (String like : conditionsLike) {
                if (UtilMap.isNotBlankString(data, like)) {
                    predicateList.add(criteriaBuilder.like(root.get(like), "%" + data.get(like) + "%"));
                }
            }
            // 查询日期范围，闭区间
            if (data.containsKey("startTime") && data.containsKey("endTime")) {
                predicateList.add(criteriaBuilder.between(root.get("gmtCreateTime").as(String.class), data.get("startTime"), data.get("endTime")));
            }
            return criteriaBuilder.and(predicateList.toArray(new javax.persistence.criteria.Predicate[predicateList.size()]));
        };
        // 无数据时返回空列表
        return recordDao.findAll(specification, pageable);
    }

    @Autowired
    private DDClient ddClient;

    @Autowired
    private DDClient_Dedicated ddClient_orgapp;

    @Autowired
    private ZSDFileRecordDao zsdFileRecordDao;

    /**
     * 同步记录, 落库
     */
    @Override
    public void syncFileRecords(long startTime, long endTime, int pageSize, Map preLastRecord) {

        // 单表储存: 格式化
        List<Map> records = ddClient_orgapp.obtainFileOperationRecords(ddClient.getAccessToken(), startTime, endTime, pageSize, preLastRecord).stream().map(item -> {
            if (item.containsKey("docReceiverList")) {
                item.put("docReceiverList", JSON.toJSONString(item.get("docReceiverList")));
            }
            if (item.containsKey("docMemberList")) {
                item.put("docMemberList", JSON.toJSONString(item.get("docMemberList")));
            }
            item.put("gmtCreateTime", new Date(UtilMap.getLong(item, "gmtCreate")));
            item.put("gmtModifiedTime", new Date(UtilMap.getLong(item, "gmtModified")));
            return item;
        }).collect(Collectors.toList());

        // 递归同步日期范围记录
        if (records.size() > 0) {
            List<ZSDFileRecordPo> poList = JSON.parseArray(JSON.toJSONString(records), ZSDFileRecordPo.class);
            log.info("文件审计同步, {}, preLastRecord = {}", records.size(), records.get(records.size() - 1));
            zsdFileRecordDao.saveAll(poList);
            syncFileRecords(startTime, endTime, pageSize, records.get(records.size() - 1));
        }
    }
}
