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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.module.common.api.dto.FormValue;
import com.yeejoin.amos.boot.module.common.api.feign.IotFeignClient;
import com.yeejoin.amos.boot.module.jcs.api.dto.AircraftDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AircraftListTreeDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCalledFormDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCalledObjsDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.KeyValueLabel;
import com.yeejoin.amos.boot.module.jcs.api.entity.Aircraft;
import com.yeejoin.amos.boot.module.jcs.api.entity.AlertFormValue;
import com.yeejoin.amos.boot.module.jcs.api.enums.AircraftFileTypeEnum;
import com.yeejoin.amos.boot.module.jcs.api.mapper.AircraftMapper;
import com.yeejoin.amos.boot.module.jcs.api.service.IAircraftService;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.FileInfoModel;
import org.apache.commons.collections.map.HashedMap;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.exception.BaseException;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.StringUtil;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.annotation.Condition;
import org.typroject.tyboot.core.rdbms.annotation.Operator;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.DataNotFound;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import static org.hamcrest.CoreMatchers.nullValue;

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


/**
 * 航空器信息服务实现类
 *
 * @author system_generator
 * @date 2021-06-29
 */
@Service
public class AircraftServiceImpl extends BaseService<AircraftDto, Aircraft, AircraftMapper> implements IAircraftService {

	
	@Autowired
    AircraftMapper aircraftMapper;

    @Autowired
    IotFeignClient iotFeignClient;


    @Autowired
    AlertCalledServiceImpl iAlertCalledService;

    @Autowired
    private AlertFormValueServiceImpl iAlertFormValueService;

    private static String aircraftModel="aircraftModel";

    /**
     * <pre>
     * 保存
     * </pre>
     *
     * @param agencyCode
     * @param aircraftDto
     * @return
     * @throws Exception
     */
    public AircraftDto createAircraft(String agencyCode, AircraftDto aircraftDto) throws Exception {

        aircraftDto.setIsDelete(false);
        //持久化航空器信息
        aircraftDto = this.createWithModel(aircraftDto);
        //持久化航空器附件信息
        saveAircraftFile(agencyCode, aircraftDto);
        return aircraftDto;
    }

    /**
     * <pre>
     * 编辑航空器信息
     * </pre>
     *
     * @param agencyCode
     * @param model
     * @return
     * @throws Exception
     */
    public AircraftDto updateAircraft(String agencyCode, AircraftDto model) throws Exception {
        AircraftDto oldModel = this.queryBySeq(model.getSequenceNbr());
        if (ValidationUtil.isEmpty(oldModel)) {
            throw new DataNotFound("找不到指定的航空器信息.");
        }
        //删除附件信息
        Systemctl.fileInfoClient.deleteByAlias(agencyCode, Aircraft.class.getSimpleName(),
                String.valueOf(model.getSequenceNbr()), null);
        //持久化航空器附件信息
        saveAircraftFile(agencyCode, model);

        return this.updateWithModel(Bean.copyExistPropertis(model, oldModel));
    }

    /**
     * <pre>
     * 根据航空器主键查询
     * </pre>
     *
     * @param seq
     * @return
     */
    @Override
    public AircraftDto queryByAircraftSeq(String agencyCode, Long seq) {
        AlertCalledObjsDto dto = (AlertCalledObjsDto)iAlertCalledService.selectAlertCalledByIdNoRedisNew(seq);
        List<AlertFormValue>  list =  dto.getAlertFormValue();
        String aircraft = "";
        List<AlertFormValue> list1 =  list.stream().filter(formValue -> formValue.getFieldCode().equals("aircraft") || formValue.getFieldCode().equals(aircraftModel)).collect(Collectors.toList());
        if(list1.size() > 0) {
            if(!ValidationUtil.isEmpty(list1.get(0).getFieldValue())) {
                aircraft = list1.get(0).getFieldValue();
            } else {
                aircraft = list1.get(0).getFieldValueCode();
            }
        }

        LambdaQueryWrapper<Aircraft> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Aircraft::getAircraftModel,aircraft);
        AircraftDto aircraftDto = new AircraftDto();
        Aircraft one = this.getOne(queryWrapper);
        Bean.toPo(one,aircraftDto);
        if(one!=null){
            //填充航空器附件信息
            FeignClientResult<List<FileInfoModel>> fileInfoModelResult = Systemctl.fileInfoClient.queryByEntity(
                    agencyCode, Aircraft.class.getSimpleName(), String.valueOf(one.getSequenceNbr()));
            List<FileInfoModel> fileInfoModels = fileInfoModelResult.getResult();

            if (!ValidationUtil.isEmpty(fileInfoModels)) {
                aircraftDto.setAppearanceImages(processToStr(fileInfoModels, AircraftFileTypeEnum.APPEARANCE.getCode()));
                aircraftDto.setPlaneImages(processToStr(fileInfoModels, AircraftFileTypeEnum.PLANE.getCode()));
                aircraftDto.setRescueImages(processToStr(fileInfoModels, AircraftFileTypeEnum.RESCUE.getCode()));
                aircraftDto.setPositionImages(processToStr(fileInfoModels, AircraftFileTypeEnum.POSITION.getCode()));
                aircraftDto.setModels(processToStr(fileInfoModels, AircraftFileTypeEnum.MODEL.getCode()));
            }
        }

        return aircraftDto;
    }

    @Override
    public  List<Aircraft> queryByAircraftSeqList(String agencyCode, Long seq) {
        AlertCalledObjsDto dto = (AlertCalledObjsDto)iAlertCalledService.selectAlertCalledByIdNoRedisNew(seq);
        List<AlertFormValue>  list =  dto.getAlertFormValue();
        String aircraft = "";
        List<AlertFormValue> list1 =  list.stream().filter(formValue -> formValue.getFieldCode().equals("aircraft") || formValue.getFieldCode().equals(aircraftModel)).collect(Collectors.toList());
        if(list1.size() > 0) {
            if(!ValidationUtil.isEmpty(list1.get(0).getFieldValue())) {
                aircraft = list1.get(0).getFieldValue();
            } else {
                aircraft = list1.get(0).getFieldValueCode();
            }
        }
        LambdaQueryWrapper<Aircraft> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Aircraft::getAircraftModel,aircraft);
        List<Aircraft> one = this.list(queryWrapper);
        LambdaQueryWrapper<Aircraft> queryWrapper2 = new LambdaQueryWrapper<>();
        if(aircraft!=null&&aircraft.length()>3){
            queryWrapper2.likeRight(Aircraft::getAircraftModel,aircraft.substring(0,3));
        }else{
            queryWrapper2.likeRight(Aircraft::getAircraftModel,aircraft);
        }

        if(one!=null){
            queryWrapper2.notIn(Aircraft::getAircraftModel,aircraft);
        }


        List<Aircraft> one1 = this.list(queryWrapper2);
        if(one!=null){
            if(one1!=null){
                one.addAll(one1);
            }
        }else{
            if(one1!=null){
                return one1;
            }
        }
        return one;
    }



    @Override
    public AircraftDto queryByAircraftSeqx(String agencyCode, Long seq) {


        LambdaQueryWrapper<Aircraft> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Aircraft::getSequenceNbr,seq);
        AircraftDto aircraftDto = new AircraftDto();
        Aircraft one = this.getOne(queryWrapper);
        Bean.toPo(one,aircraftDto);
        if(one!=null){
            //填充航空器附件信息
            FeignClientResult<List<FileInfoModel>> fileInfoModelResult = Systemctl.fileInfoClient.queryByEntity(
                    agencyCode, Aircraft.class.getSimpleName(), String.valueOf(one.getSequenceNbr()));
            List<FileInfoModel> fileInfoModels = fileInfoModelResult.getResult();

            if (!ValidationUtil.isEmpty(fileInfoModels)) {
                aircraftDto.setAppearanceImages(processToStr(fileInfoModels, AircraftFileTypeEnum.APPEARANCE.getCode()));
                aircraftDto.setPlaneImages(processToStr(fileInfoModels, AircraftFileTypeEnum.PLANE.getCode()));
                aircraftDto.setRescueImages(processToStr(fileInfoModels, AircraftFileTypeEnum.RESCUE.getCode()));
                aircraftDto.setPositionImages(processToStr(fileInfoModels, AircraftFileTypeEnum.POSITION.getCode()));
                aircraftDto.setModels(processToStr(fileInfoModels, AircraftFileTypeEnum.MODEL.getCode()));
            }
        }

        return aircraftDto;
    }





    public AircraftDto queryBySeq(String agencyCode, Long seq) {
    	 AircraftDto aircraftDto = this.queryBySeq(seq);
   
        FeignClientResult<List<FileInfoModel>> fileInfoModelResult = Systemctl.fileInfoClient.queryByEntity(
                agencyCode, Aircraft.class.getSimpleName(), String.valueOf(seq));
        List<FileInfoModel> fileInfoModels = fileInfoModelResult.getResult();

        if (!ValidationUtil.isEmpty(fileInfoModels)) {
            aircraftDto.setAppearanceImages(processToStr(fileInfoModels, AircraftFileTypeEnum.APPEARANCE.getCode()));
            aircraftDto.setPlaneImages(processToStr(fileInfoModels, AircraftFileTypeEnum.PLANE.getCode()));
            aircraftDto.setRescueImages(processToStr(fileInfoModels, AircraftFileTypeEnum.RESCUE.getCode()));
            aircraftDto.setPositionImages(processToStr(fileInfoModels, AircraftFileTypeEnum.POSITION.getCode()));
            aircraftDto.setModels(processToStr(fileInfoModels, AircraftFileTypeEnum.MODEL.getCode()));
        }
        return aircraftDto;
    }

    /**
     * <pre>
     * 批量删除
     * </pre>
     *
     * @param ids
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = {Exception.class, BaseException.class})
    public List<Long> multDeleteAircraft(String agencyCode, String ids) throws Exception {
        List<Long> seqs = StringUtil.String2LongList(ids);
        for (Long id : seqs) {
            AircraftDto aircraftDto = this.queryBySeq(id);
            aircraftDto.setIsDelete(true);
            this.updateWithModel(aircraftDto);
        }
        return seqs;
    }


    /**
     * <pre>
     * 分页查询
     * </pre>
     *
     * @param page
     * @return
     */
    public Page<AircraftDto> queryForAircraftPage(Page<AircraftDto> page,
                                                  Boolean isDelete,
                                                  @Condition(Operator.like) String aircraftModel,
                                                  String engineTypeCode, String fuelTypeCode) {
        // 航空器信息按时间倒叙排列add rec_date 2021-09-08 by kongfm
        return this.queryForPage(page, "rec_date", false, isDelete, aircraftModel, engineTypeCode, fuelTypeCode);
    }

    /**
     * 列表查询 示例
     */
    public List<AircraftDto> queryAircraftDtoForList(@Condition(Operator.eq) Boolean isDelete, @Condition(Operator.like) String aircraftModel,
                                                     String engineTypeCode, String fuelTypeCode) {
    	if("null".equals(aircraftModel)) {
    		aircraftModel=null;
    	}
    	if("null".equals(engineTypeCode)) {
    		engineTypeCode = null;
    	}
    	if("null".equals(fuelTypeCode)) {
    		fuelTypeCode = null;
    	}
        return this.queryForList("", false, isDelete,aircraftModel, engineTypeCode, fuelTypeCode);
    }

    /**
     * <pre>
     * 持久化航空器附件信息
     * </pre>
     *
     * @param agencyCode
     * @param aircraftDto
     * @return
     */
    private boolean saveAircraftFile(String agencyCode, AircraftDto aircraftDto) throws Exception {
        List<FileInfoModel> fileInfoModelList = new ArrayList<FileInfoModel>();
        //外观图
        if (!ValidationUtil.isEmpty(aircraftDto.getAppearanceImages())) {
            List<String> appearanceImages = StringUtil.String2List(aircraftDto.getAppearanceImages());
            fileInfoModelList.addAll(buildFileInfo(agencyCode, appearanceImages, aircraftDto,
                    AircraftFileTypeEnum.APPEARANCE.getCode()));
        }
        //平面图
        if (!ValidationUtil.isEmpty(aircraftDto.getPlaneImages())) {
            List<String> planeImages = StringUtil.String2List(aircraftDto.getPlaneImages());
            fileInfoModelList.addAll(buildFileInfo(agencyCode, planeImages, aircraftDto,
                    AircraftFileTypeEnum.PLANE.getCode()));
        }
        //救援图
        if (!ValidationUtil.isEmpty(aircraftDto.getRescueImages())) {
            List<String> rescueImages = StringUtil.String2List(aircraftDto.getRescueImages());
            fileInfoModelList.addAll(buildFileInfo(agencyCode, rescueImages, aircraftDto,
                    AircraftFileTypeEnum.RESCUE.getCode()));
        }
        //方位图
        if (!ValidationUtil.isEmpty(aircraftDto.getPositionImages())) {
            List<String> positionImages = StringUtil.String2List(aircraftDto.getPositionImages());
            fileInfoModelList.addAll(buildFileInfo(agencyCode, positionImages, aircraftDto,
                    AircraftFileTypeEnum.POSITION.getCode()));
        }
        //三维模型
        if (!ValidationUtil.isEmpty(aircraftDto.getModels())) {
            List<String> models = StringUtil.String2List(aircraftDto.getModels());
            fileInfoModelList.addAll(buildFileInfo(agencyCode, models, aircraftDto,
                    AircraftFileTypeEnum.MODEL.getCode()));
        }

        if (!ValidationUtil.isEmpty(fileInfoModelList)) {
            Systemctl.fileInfoClient.batchCreateByEntity(fileInfoModelList);
        }
        return true;
    }

    /**
     * <pre>
     * 构建文件信息
     * </pre>
     *
     * @param agencyCode
     * @param images
     * @param aircraftDto
     * @param fileCategory
     * @return
     */
    private List<FileInfoModel> buildFileInfo(String agencyCode, List<String> images,
                                              AircraftDto aircraftDto, String fileCategory) throws Exception {
        List<FileInfoModel> fileInfoModelList = new ArrayList<>();
        for (String image : images) {
            FileInfoModel fileInfoModel = new FileInfoModel();
            fileInfoModel.setEntityId(String.valueOf(aircraftDto.getSequenceNbr()));
            fileInfoModel.setEntityType(Aircraft.class.getSimpleName());
            fileInfoModel.setFileCategory(fileCategory);
            fileInfoModel.setFilename(image);
            fileInfoModel.setAgencyCode(agencyCode);

            fileInfoModelList.add(fileInfoModel);
        }

        return fileInfoModelList;
    }

    /**
     * 图片转成逗号分割String
     *
     * @param fileInfoModels
     * @param fileCategory
     * @return
     */
    private String processToStr(List<FileInfoModel> fileInfoModels, String fileCategory) {
        return fileInfoModels.stream().filter(x -> fileCategory.equals(x.getFileCategory())).map(FileInfoModel::getFilename).collect(Collectors.joining(","));
    }



	@Override
	public Aircraft queryByaircraftModel(String seq) {
		QueryWrapper<Aircraft> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq(aircraftModel, seq);
		// 警情动态表单数据
		Aircraft aircraft = this.getOne(queryWrapper);	
		return aircraft;
	}

	@Override
	public List<AircraftListTreeDto> getAircraft() {
		
		return aircraftMapper.getAircraft();
	}

	@Override
    public Map<String, Object> queryAircraftInfo(Long alertId) {
        QueryWrapper<AlertFormValue> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("alert_called_id", alertId);
        // 警情动态表单数据
        List<AlertFormValue> list = iAlertFormValueService.list(queryWrapper);

        String num = null;
        if (list != null && list.size() > 0) {
            for (AlertFormValue alertFormValue : list) {
                if ("flightNumber".equals(alertFormValue.getFieldCode())) {
                    num = alertFormValue.getFieldValue();
                    break;
                }
            }
        }
        Map<String, Object> map = new HashedMap();
        ResponseModel<Map<String, Object>> dataModel = iotFeignClient.findImgByDynamicFlightId(num);
        if (dataModel != null) {
            map = dataModel.getResult();
        }
        return map;
    }



    @Override
    public Aircraft queryAircraftInfoByModel(String aircraftModel) {
        return this.baseMapper.selectOne(new LambdaQueryWrapper<Aircraft>().eq(Aircraft::getAircraftModel, aircraftModel));
    }

    @Override
    public List<Map<String, Object>> queryAircraftList() {
        return aircraftMapper.queryAircraftList();
    }
}
