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

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.module.tzs.api.dto.EsSpecialEquipmentDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.SpecialEquipmentDto;
import com.yeejoin.amos.boot.module.tzs.api.entity.EsCylinder;
import com.yeejoin.amos.boot.module.tzs.api.enums.SpecialEquipmentCategoryEnum;
import com.yeejoin.amos.boot.module.tzs.biz.dao.ESCylinderRepository;
import com.yeejoin.amos.boot.module.tzs.flc.api.entity.CylinderInfo;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.common.geo.GeoPoint;
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.domain.PageRequest;
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.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import java.util.LinkedList;
import java.util.List;

/**
 * <pre>
 * 压力容器信息ES检索服务
 * </pre>
 *
 * @author tb
 * @version 2022年4月20日
 */
@Service
public class ESCylinderServiceImpl {

	@Autowired
	private ElasticsearchRestTemplate elasticsearchTemplate;

	@Autowired
	private ESCylinderRepository esCylinderRepository;

	/**
	 * <pre>
	 * 保存气瓶信息
	 * </pre>
	 *
	 * @param cylinderInfo 保存气瓶信息
	 */
	public EsCylinder saveEsCylinderToES(CylinderInfo cylinderInfo) {
		EsCylinder esCylinder = new EsCylinder();
		if (StringUtils.isNotEmpty(cylinderInfo.getLongitude())) {
			esCylinder.setLongitude(Double.parseDouble(cylinderInfo.getLongitude()));
		}
		if (StringUtils.isNotEmpty(cylinderInfo.getLatitude())) {
			esCylinder.setLatitude(Double.parseDouble(cylinderInfo.getLatitude()));
		}
		esCylinder.setSequenceNbr(cylinderInfo.getSequenceNbr());
//        esCylinder.setAddress(cylinder.getAddress());
		esCylinder.setFactoryNum(cylinderInfo.getFactoryNum());
		esCylinder.setUnitName(cylinderInfo.getUnitName());
		if (StringUtils.isNotBlank(cylinderInfo.getLatitude()) && StringUtils.isNotBlank(cylinderInfo.getLongitude())) {
			Double lat = Double.parseDouble(cylinderInfo.getLatitude());
			Double lon = Double.parseDouble(cylinderInfo.getLongitude());
			esCylinder.setLocation(new GeoPoint(lat, lon));
		}
		esCylinderRepository.save(esCylinder);
		return esCylinder;
	}

	public Page<SpecialEquipmentDto> queryPageByDto(EsSpecialEquipmentDto esSpecialEquipmentDto, int current, int size) {
		Page<SpecialEquipmentDto> result = new Page<>(current, size);
		Double startLongitude = esSpecialEquipmentDto.getStartLongitude();
		Double startLatitude = esSpecialEquipmentDto.getStartLatitude();
		Double endLongitude = esSpecialEquipmentDto.getEndLongitude();
		Double endLatitude = esSpecialEquipmentDto.getEndLatitude();
		String regionCode = esSpecialEquipmentDto.getRegionCode();
		String keyword = esSpecialEquipmentDto.getKeyword();
		/**
		 * 通用匹配规则，条件构建
		 */
		BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
		// 经度比start 大比end 小 纬度比start 小 比end 大
		if (!ValidationUtil.isEmpty(startLongitude) && !ValidationUtil.isEmpty(startLatitude) && !ValidationUtil.isEmpty(endLongitude) && !ValidationUtil.isEmpty(endLatitude)) {
			BoolQueryBuilder longLatMust = QueryBuilders.boolQuery();
			BoolQueryBuilder qb1 = QueryBuilders.boolQuery().must(QueryBuilders.rangeQuery("longitude").gte(startLongitude).lte(endLongitude));
			BoolQueryBuilder qb2 = QueryBuilders.boolQuery().must(QueryBuilders.rangeQuery("latitude").gte(endLatitude).lte(startLatitude));
			longLatMust.must(qb1);
			longLatMust.must(qb2);
			boolMust.must(longLatMust);
		}

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

		if (!ValidationUtil.isEmpty(keyword)) {
			BoolQueryBuilder qb0 = QueryBuilders.boolQuery().
					must(QueryBuilders.matchQuery("factoryNum", keyword));
			boolMust.should(qb0);
			BoolQueryBuilder qb1 = QueryBuilders.boolQuery().
					must(QueryBuilders.matchQuery("address", keyword));
			boolMust.should(qb1);
			BoolQueryBuilder qb2 = QueryBuilders.boolQuery().
					must(QueryBuilders.matchQuery("unitName", keyword));
			boolMust.should(qb2);
			boolMust.minimumShouldMatch(1);
		}

		// 创建查询构造器
		NativeSearchQuery query = new NativeSearchQueryBuilder()
				// 分页
				.withPageable(PageRequest.of(current - 1, size))
				// 排序
//                .withSort(SortBuilders.fieldSort("callTimeLong").order(SortOrder.DESC))
				//过滤条件
				.withQuery(boolMust).build();
		query.setTrackTotalHits(true);
		query.setMaxResults(size);
		List<SpecialEquipmentDto> list = new LinkedList<>();
		long total = 0;
		try {
			SearchHits<EsCylinder> searchHits = elasticsearchTemplate.search(query, EsCylinder.class);

			for (SearchHit searchHit : searchHits.getSearchHits()) {
				JSONObject jsonObject = (JSONObject) JSONObject.toJSON(searchHit.getContent());
				SpecialEquipmentDto esCylinderDto = JSONObject.toJavaObject(jsonObject, SpecialEquipmentDto.class);
				esCylinderDto.setCategoryCode(SpecialEquipmentCategoryEnum.PRESSURE_VESSEL.getCode());
				esCylinderDto.setUniqueCode(jsonObject.getString("factoryNum"));
				list.add(esCylinderDto);
			}
			total = searchHits.getTotalHits();
		} catch (Exception e) {
			// TODO: handle exception
		}
		result.setRecords(list);
		result.setTotal(total);
		return result;
	}

}
