package com.yeejoin.amos.boot.module.tzs.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.module.tzs.api.dto.EsElevatorDto;
import com.yeejoin.amos.boot.module.tzs.api.entity.AlertCalled;
import com.yeejoin.amos.boot.module.tzs.api.entity.Elevator;
import com.yeejoin.amos.boot.module.tzs.api.entity.EsElevator;
import com.yeejoin.amos.boot.module.tzs.biz.dao.ESElavtorRepository;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
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 org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 * <pre>
 * 电梯信息ES检索服务
 * </pre>
 *
 * @authorlitw
 * @version  2021年9月26日
 */
@Service
public class ESElevatorServiceImpl {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchTemplate;

    @Autowired
    private ESElavtorRepository esElavtorRepository;

    @Autowired
    AlertCalledServiceImpl iAlertCalledService;

    @Autowired
    ElevatorServiceImpl elevatorService;

    @Autowired
    ElevatorAlarmServiceImpl elevatorAlarmServiceImpl;

    @Value("${alertcall.es.synchrony.time}")
	private Long time;
    


    /**
     *
     * <pre>
     * 电梯信息
     * </pre>
     *
     * @param elevator 电梯信息
     */
    public EsElevator saveEsElevatorToES(Elevator elevator)
    {
		EsElevator esElevator = new EsElevator();
        Bean.toPo(elevator,esElevator);
		esElavtorRepository.save(esElevator);
    	return esElevator;
    }


    /**
     * 根据关键字查询文档，关键字不为空时按相关性从大到小排序
     *
     * @param elevatorDto 关键字
     * @return
     */
    @SuppressWarnings({ "rawtypes" })
    public List<EsElevatorDto> queryByKeys(EsElevatorDto elevatorDto) {

        String alarmTypeCode = elevatorDto.getAlarmTypeCode();
        String address = elevatorDto.getAddress();
        String regionCode = elevatorDto.getRegionCode();
        String alertId = elevatorDto.getAlertId();
        Long equipmentId = elevatorDto.getSequenceNbr();

        /**
         * 通用匹配规则，条件构建
         */
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();

        BoolQueryBuilder qb0 = QueryBuilders.boolQuery();
        LambdaQueryWrapper<AlertCalled> queryWrapper = new LambdaQueryWrapper();

        if(!ValidationUtil.isEmpty(alarmTypeCode) && !"all".equals(alarmTypeCode)) {
            queryWrapper.eq(AlertCalled::getAlarmTypeCode,alarmTypeCode);
        }
        AlertCalled alertCalled = null;
        List<AlertCalled> alertCalleds = null;
        if(!ValidationUtil.isEmpty(alertId)) {
            alertCalled = iAlertCalledService.getById(elevatorDto.getAlertId());
            BoolQueryBuilder qb4 = QueryBuilders.boolQuery();
            qb4.must(QueryBuilders.termQuery("sequenceNbr",  alertCalled.getEquipmentId()));
            boolMust.must(qb4);
        } else {
            if(!ValidationUtil.isEmpty(alarmTypeCode)) {
                if(elevatorDto.getIsToday() != null && elevatorDto.getIsToday()) {
                    queryWrapper.ge(AlertCalled::getCallTime, DateUtils.stampToDate(System.currentTimeMillis(),DateUtils.DATE_PATTERN));
                    queryWrapper.le(AlertCalled::getCallTime, DateUtils.stampToDate(DateUtils.dateAddDays(new Date(),1).getTime(),DateUtils.DATE_PATTERN));
                }
                alertCalleds  = iAlertCalledService.list(queryWrapper);
                List<Long> stringList = new ArrayList<>();
                for (AlertCalled al: alertCalleds
                ) {
                    stringList.add(al.getEquipmentId());
                }
                List<Long> listL = stringList.stream().distinct().collect(Collectors.toList());
                qb0.should(QueryBuilders.termsQuery("sequenceNbr",  listL.toArray()));
                boolMust.must(qb0);
            }
        }


        if(!ValidationUtil.isEmpty(address)) {
            BoolQueryBuilder boolMustAddress = QueryBuilders.boolQuery();
            BoolQueryBuilder qb1 = QueryBuilders.boolQuery()
                    .should(QueryBuilders.matchPhraseQuery("address", address));
            boolMustAddress.should(qb1);
            boolMust.must(boolMustAddress);
        }

        if(!ValidationUtil.isEmpty(regionCode)) {
            BoolQueryBuilder qb2= QueryBuilders.boolQuery().
                    filter(QueryBuilders. matchPhraseQuery("regionCode", regionCode));
            boolMust.must(qb2);
        }

        if(!ValidationUtil.isEmpty(equipmentId)) {
            BoolQueryBuilder qb3= QueryBuilders.boolQuery().
                    filter(QueryBuilders. termQuery("sequenceNbr", equipmentId));
            boolMust.must(qb3);
        }

        // 创建查询构造器
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder()
                // 分页
//                .withPageable(PageRequest.of(current, size))
                // 排序
//                .withSort(SortBuilders.fieldSort("callTimeLong").order(SortOrder.DESC))
                //过滤条件
                .withQuery(boolMust);

        List<EsElevatorDto> list = new LinkedList<>();
        try
        {
            SearchHits<EsElevator> searchHits =elasticsearchTemplate.search(queryBuilder.build(), EsElevator.class);

            for (SearchHit searchHit : searchHits.getSearchHits())
            {
                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(searchHit.getContent());
                EsElevatorDto esElevatorDto =JSONObject.toJavaObject(jsonObject, EsElevatorDto.class);
                if(null != alertCalleds) {
                    for (AlertCalled al: alertCalleds
                    ) {
                        if(al.getEquipmentId().equals(esElevatorDto.getSequenceNbr())) {
                            esElevatorDto.setHappenTime(al.getCallTime());
                            esElevatorDto.setAlertId(String.valueOf(al.getSequenceNbr()));
                            esElevatorDto.setAlarmTypeCode(al.getAlarmTypeCode());
                            esElevatorDto.setType(al.getAlertStage());
                            list.add(esElevatorDto);
                            break;
                        }
                    }
                } else {
                    list.add(esElevatorDto);
                }
            }
        }
        catch (Exception e)
        {
            // TODO: handle exception
        }
        return list;
    }

}
