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.ElevatorAlarm;
import com.yeejoin.amos.boot.module.tzs.api.entity.EsElevator;
import com.yeejoin.amos.boot.module.tzs.api.enums.LiftAlarmDealStatusEnum;
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.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();
		esElevator.setSequenceNbr(elevator.getSequenceNbr());
        esElevator.setProvince(elevator.getProvince());
        esElevator.setAddress(elevator.getAddress());
        esElevator.setCity(elevator.getCity());
        esElevator.setDistrict(elevator.getDistrict());
        esElevator.setLatitude(elevator.getLatitude());
        esElevator.setLongitude(elevator.getLongitude());
        esElevator.setRegisterCode(elevator.getRegisterCode());
        esElevator.setRegionCode(elevator.getRegionCode());
        esElevator.setRescueCode(elevator.getRescueCode());

		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();

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

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

        if(!ValidationUtil.isEmpty(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(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);
        }

        // 创建查询构造器
        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 != alertCalled) {
                   // Elevator elevator = elevatorService.getById(esElevatorDto.getSequenceNbr());
                    LambdaQueryWrapper<ElevatorAlarm> queryWrapper1 = new LambdaQueryWrapper<>();
                    queryWrapper1.eq(ElevatorAlarm::getRegisterCode,esElevatorDto.getRegisterCode());
                    queryWrapper1.orderByDesc(ElevatorAlarm::getStartDate);
                    List<ElevatorAlarm>  elevatorAlarms = elevatorAlarmServiceImpl.list(queryWrapper1);
                    if(null != elevatorAlarms && elevatorAlarms.size() > 0) {
                        esElevatorDto.setType(elevatorAlarms.get(0).getType());
                        esElevatorDto.setStatus(LiftAlarmDealStatusEnum.getEnum(elevatorAlarms.get(0).getDealStatus()).getName());

                    }
                    esElevatorDto.setHappenTime(alertCalled.getCallTime());
                    esElevatorDto.setAlertId(String.valueOf(alertCalled.getSequenceNbr()));
                    esElevatorDto.setAlarmTypeCode(alertCalled.getAlarmTypeCode());

                } else {
                    for (AlertCalled al: alertCalleds
                    ) {
                        if(al.getEquipmentId().equals(esElevatorDto.getSequenceNbr())) {
                            esElevatorDto.setHappenTime(al.getCallTime());
                            esElevatorDto.setAlertId(String.valueOf(al.getSequenceNbr()));
                            esElevatorDto.setAlarmTypeCode(al.getAlarmTypeCode());
                            break;
                        }
                    }
                }
                list.add(esElevatorDto);
            }
        }
        catch (Exception e)
        {
            // TODO: handle exception
        }
        return list;
    }

}
