package com.wteam.framework.modules.permission.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wteam.framework.common.vo.PageVO;
import com.wteam.framework.common.vo.SearchVO;
import com.wteam.framework.modules.permission.entity.vo.SystemLogVO;
import com.wteam.framework.modules.permission.repository.SystemLogRepository;
import com.wteam.framework.modules.permission.service.SystemLogService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统日志
 *
 * @author Chopper
 * @since 2020/11/17 3:45 下午
 */
@Service
public class SystemLogServiceImpl implements SystemLogService {

    @Autowired
    private SystemLogRepository systemLogRepository;

    /**
     * ES
     */
    @Autowired
    private ElasticsearchOperations restTemplate;

    @Override
    public void saveLog(SystemLogVO systemLogVO) {
        systemLogRepository.save(systemLogVO);
    }

    @Override
    public void deleteLog(List<String> id) {
        for (String s : id) {
            systemLogRepository.deleteById(s);
        }
    }

    @Override
    public void flushAll() {
        systemLogRepository.deleteAll();
    }

    @Override
    public IPage<SystemLogVO> queryLog(String storeId, String operatorName, String key, SearchVO searchVo, PageVO pageVO) {
        pageVO.setNotConvert(true);
        IPage<SystemLogVO> iPage = new Page<>();
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        if (pageVO.getPageNumber() != null && pageVO.getPageSize() != null) {
            int pageNumber = pageVO.getPageNumber() - 1;
            if (pageNumber < 0) {
                pageNumber = 0;
            }
            Pageable pageable = PageRequest.of(pageNumber, pageVO.getPageSize());
            //分页
            nativeSearchQueryBuilder.withPageable(pageable);
            iPage.setCurrent(pageVO.getPageNumber());
            iPage.setSize(pageVO.getPageSize());
        }

        if (CharSequenceUtil.isNotEmpty(storeId)) {
            nativeSearchQueryBuilder.withFilter(QueryBuilders.matchQuery("storeId", storeId));
        }

        if (CharSequenceUtil.isNotEmpty(operatorName)) {
            nativeSearchQueryBuilder.withFilter(QueryBuilders.wildcardQuery("username", "*" + operatorName + "*"));
        }

        if (CharSequenceUtil.isNotEmpty(key)) {
            BoolQueryBuilder filterBuilder = new BoolQueryBuilder();
            filterBuilder.should(QueryBuilders.wildcardQuery("requestUrl", "*" + key + "*"))
                    .should(QueryBuilders.wildcardQuery("requestParam", "*" + key + "*"))
                    .should(QueryBuilders.wildcardQuery("responseBody", "*" + key + "*"))
                    .should(QueryBuilders.wildcardQuery("name", "*" + key + "*"));
            nativeSearchQueryBuilder.withFilter(filterBuilder);
        }
        //时间有效性判定
        if (searchVo.getConvertStartDate() != null && searchVo.getConvertEndDate() != null) {
            BoolQueryBuilder filterBuilder = new BoolQueryBuilder();
            //大于方法
            filterBuilder.must(
                    QueryBuilders.rangeQuery("createTime")
                            .gte(DateUtil.format(searchVo.getConvertStartDate(), "dd/MM/yyyy"))
                            .lte(DateUtil.format(searchVo.getConvertEndDate(), "dd/MM/yyyy")).format("dd/MM/yyyy||yyyy"));

            nativeSearchQueryBuilder.withFilter(filterBuilder);
        }

        if (CharSequenceUtil.isNotEmpty(pageVO.getOrder()) && CharSequenceUtil.isNotEmpty(pageVO.getSort())) {
            nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(pageVO.getSort()).order(SortOrder.valueOf(pageVO.getOrder().toUpperCase())));
        } else {
            nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC));
        }

        SearchHits<SystemLogVO> searchResult = restTemplate.search(nativeSearchQueryBuilder.build(), SystemLogVO.class);

        iPage.setTotal(searchResult.getTotalHits());

        iPage.setRecords(searchResult.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList()));
        return iPage;
    }

}
