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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Sequence;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.module.common.api.dto.AttachmentDto;
import com.yeejoin.amos.boot.module.common.api.dto.KeySiteDto;
import com.yeejoin.amos.boot.module.common.api.dto.KeySiteExcleDto;
import com.yeejoin.amos.boot.module.common.api.dto.OrgMenuDto;
import com.yeejoin.amos.boot.module.common.api.dto.OrgUsrTreeDto;
import com.yeejoin.amos.boot.module.common.api.entity.KeySite;
import com.yeejoin.amos.boot.module.common.api.entity.SourceFile;
import com.yeejoin.amos.boot.module.common.api.feign.EquipFeignClient;
import com.yeejoin.amos.boot.module.common.api.mapper.KeySiteMapper;
import com.yeejoin.amos.boot.module.common.api.mapper.OrgUsrMapper;
import com.yeejoin.amos.boot.module.common.api.service.IKeySiteService;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 重点部位服务实现类
 *
 * @author system_generator
 * @date 2021-07-26
 */
@Service
public class KeySiteServiceImpl extends BaseService<KeySiteDto, KeySite, KeySiteMapper> implements IKeySiteService {

	@Autowired
	KeySiteMapper keySiteMapper;

	@Autowired
	SourceFileServiceImpl sourceFileService;

	@Autowired
	OrgUsrMapper orgUsrMapper;

	@Autowired
	EquipFeignClient equipFeignClient;
	@Autowired
	private Sequence sequence;

	/**
	 * 分页查询
	 */
	public IPage<KeySiteDto> getPageList(Page<KeySiteDto> page, String name, Long buildingId, String fireEnduranceRate,
			String useNature, String fireFacilitiesInfo, Long belongId){
		return keySiteMapper.getPageList(page,name,buildingId,fireEnduranceRate,useNature,fireFacilitiesInfo,belongId);
	}

	@Override
	public List<Object> getBuildTree() {
		ResponseModel<Object> response = equipFeignClient.getBuildingTree();
		if (200 == response.getStatus() && ObjectUtils.isNotEmpty(response.getResult())) {
			return JSONArray.parseArray(JSON.toJSONString(response.getResult()));
		}
		return null;
	}

	/**
	 * 列表查询 示例
	 */
	@Override
	public List<KeySiteDto> queryForKeySiteList() {
		return keySiteMapper.getKeySiteList();
	}

	@Override
	public List<KeySiteExcleDto> exportToExcel() {
		List<KeySiteDto> list = this.queryForKeySiteList();
		List<KeySiteExcleDto> excleList = new ArrayList<>();
		list.stream().forEach(i -> {
			KeySiteExcleDto keySiteExcleDto = new KeySiteExcleDto();
			Bean.copyExistPropertis(i, keySiteExcleDto);
			if (i.getFirePreventionFlag()) {
				keySiteExcleDto.setFirePreventionFlagName("有");
			} else {
				keySiteExcleDto.setFirePreventionFlagName("无");
			}
			keySiteExcleDto.setUseNature(i.getUseNatureName());
			keySiteExcleDto.setBelongName(i.getBelongName());
			keySiteExcleDto.setFireEnduranceRate(i.getFireEnduranceRateName());
			excleList.add(keySiteExcleDto);
		});
		return excleList;
	}

	@Override
	public boolean deleteById(List<Long> sequenceNbrList) {
		if(ObjectUtils.isEmpty(sequenceNbrList)) {
			return false;
		}
		try {
			sequenceNbrList.stream().forEach(i->{
				KeySite keySite = keySiteMapper.selectById(i);
				if (keySite != null) {
					keySite.setIsDelete(true);
				    keySiteMapper.updateById(keySite);
				}
			});
		} catch (Exception e) {
			return false;
		}
		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public KeySiteDto save(KeySiteDto model) {
		long sequenceId = sequence.nextId();
		KeySite keySite = new KeySite();
		Bean.copyExistPropertis(model, keySite);
		keySite.setSequenceNbr(sequenceId);
		model.setSequenceNbr(sequenceId);
		this.save(keySite);
		saveAttachments(model);
		// TODO Auto-generated method stub
		return model;
	}

	public void saveAttachments(KeySiteDto keySiteDto) {
		if (!ValidationUtil.isEmpty(keySiteDto.getAttachments())) {
			List<SourceFile> sourceFiles = Lists.newArrayList();
			Map<String, List<AttachmentDto>> attachmentMap = keySiteDto.getAttachments();
			attachmentMap.entrySet().forEach(entry -> {
				List<AttachmentDto> atts = entry.getValue();
				sourceFiles.addAll(attachment2SourceFile(entry.getKey(), atts));
			});
			sourceFileService.saveSourceFile(keySiteDto.getSequenceNbr(), sourceFiles);
		}
	}

	private List<SourceFile> attachment2SourceFile(String type, List<AttachmentDto> attachmentDtoList) {
		List<SourceFile> sourceFiles = Lists.newArrayList();
		if (!ValidationUtil.isEmpty(attachmentDtoList)) {
			attachmentDtoList.forEach(a -> {
				SourceFile s = new SourceFile();
				s.setFilePath(a.getUrl());
				s.setFileName(a.getName());
				s.setFileCategory(type);
				sourceFiles.add(s);
			});
		}
		return sourceFiles;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean update(KeySiteDto keySite, AgencyUserModel userInfo) {
		KeySite entity = new KeySite();
		Bean.copyExistPropertis(keySite, entity);
		entity.setIsDelete(false);
		entity.setRecDate(new Date());
		entity.setRecUserId(userInfo.getUserId());
		entity.setRecUserName(userInfo.getUserName());
		int num = keySiteMapper.updateById(entity);
		Map<String, List<AttachmentDto>> map = keySite.getAttachments();
		if (ObjectUtils.isNotEmpty(map)) {
			this.saveAttachments(keySite);
		}
		if (num > 0) {
			return true;
		}
		return false;
	}

	@Override
	public List<OrgMenuDto> getOrguserTree() {
		List<OrgUsrTreeDto> list =	orgUsrMapper.getCompanyAndCountDepartment();
		List<OrgMenuDto> menuList = list.stream().map(o -> {
			OrgMenuDto menu = new OrgMenuDto(o.getSequenceNbr(), o.getBizOrgName()+" ("+o.getNum() + ")",
					ObjectUtils.isEmpty(o.getParentId()) ? 0L : Long.valueOf(o.getParentId()), o.getBizOrgType(), false,
					o.getBizOrgCode());
			return menu;
		}).collect(Collectors.toList());
		return buildTreeParallel(menuList);
	}

	public static List<OrgMenuDto> buildTreeParallel(List<OrgMenuDto> menuList) {

		List<OrgMenuDto> result = new ArrayList<>();
		Map<Long, OrgMenuDto> map = new HashMap<>(menuList.size());
		menuList.forEach(e -> map.put(e.getKey(), e));
		Set<? extends Map.Entry<Long, ? extends OrgMenuDto>> entries = map.entrySet();
		entries.parallelStream().forEach(entry -> {
			OrgMenuDto value = entry.getValue();
			if (value != null) {
				OrgMenuDto treeDto = map.get(value.getParentId());
				if (treeDto != null) {
					List<OrgMenuDto> children = treeDto.getChildren();
					if (children == null) {
						children = new ArrayList<>();
						treeDto.setChildren(children);
					}
					children.add(value);
				} else {
					result.add(value);
				}
			}
		});
		return result;
	}

	@Override
	public KeySiteDto getSequenceNbr(Long sequenceNbr) {
		return keySiteMapper.getSequenceNbr(sequenceNbr);
	}

	@Override
	public boolean saveExcel(List<KeySiteExcleDto> excelDtoList) {
		List<KeySite> excelList = new ArrayList<KeySite>();
		for (KeySiteExcleDto keySiteExcleDto : excelDtoList) {
			KeySite keySiteDto = new KeySite();
			Bean.copyExistPropertis(keySiteExcleDto, keySiteDto);
			keySiteDto.setIsDelete(false);
			if (StringUtils.isNotBlank(keySiteExcleDto.getBelongName())
					&& keySiteExcleDto.getBelongName().contains("@")) {
				keySiteDto.setBelongId(Long.parseLong(keySiteExcleDto.getBelongName().split("@")[1]));
			}
			if (StringUtils.isNotBlank(keySiteExcleDto.getBuildingName())
					&& keySiteExcleDto.getBuildingName().contains("@")) {
				String[] fireEnduranceRateArray = keySiteExcleDto.getBuildingName().split("@");
				keySiteDto.setBuildingId(Long.parseLong(fireEnduranceRateArray[1]));
				keySiteDto.setBuildingName(fireEnduranceRateArray[0]);
			}
			if (StringUtils.isNotBlank(keySiteExcleDto.getFireEnduranceRate())
					&& keySiteExcleDto.getFireEnduranceRate().contains("@")) {
				String[] fireEnduranceRateArray = keySiteExcleDto.getFireEnduranceRate().split("@");
				if (fireEnduranceRateArray.length > 1) {
					keySiteDto.setFireEnduranceRate(fireEnduranceRateArray[1]);
				}
				keySiteDto.setFireEnduranceRateName(fireEnduranceRateArray[0]);
			}
			if (StringUtils.isNotBlank(keySiteExcleDto.getUseNature())
					&& keySiteExcleDto.getUseNature().contains("@")) {
				String[] useNatureArray = keySiteExcleDto.getUseNature().split("@");
				if (useNatureArray.length > 1) {
					keySiteDto.setUseNature(useNatureArray[1]);
				}
				keySiteDto.setUseNatureName(useNatureArray[0]);
			}
			if ("有".equals(keySiteExcleDto.getFirePreventionFlagName())) {
				keySiteDto.setFirePreventionFlag(true);
			} else {
				keySiteDto.setFirePreventionFlag(false);
			}
			excelList.add(keySiteDto);
		}
		return this.saveBatch(excelList);
	}

	@Override
	public List<OrgMenuDto> getBuildAndKeyTree(Long sequenceNbr) {
		LambdaQueryWrapper<KeySite> mapper =new LambdaQueryWrapper<KeySite>();
		mapper.eq(KeySite::getBuildingId, sequenceNbr);
		mapper.eq(KeySite::getIsDelete, false);
		List<KeySite>	list=this.baseMapper.selectList(mapper);
		if(list==null || list.size()==0) {
			return null;
		}
		String buildNameString=list.get(0).getBuildingName();
		List<OrgMenuDto> menuList = list.stream().map(o -> {
			OrgMenuDto menu = new OrgMenuDto(o.getSequenceNbr(), o.getName(),
					ObjectUtils.isEmpty(o.getBelongId()) ? 0L : Long.valueOf(o.getBelongId()), null, false,
					null);
			return menu;
		}).collect(Collectors.toList());
		List<OrgMenuDto> list1 = new ArrayList<OrgMenuDto>();
		OrgMenuDto orgMenuDto =new OrgMenuDto();
		orgMenuDto.setKey(sequenceNbr);
		orgMenuDto.setValue(sequenceNbr);
		orgMenuDto.setChildren(buildTreeParallel(menuList));
		orgMenuDto.setName(buildNameString);
		orgMenuDto.setTitle(buildNameString);
		list1.add(orgMenuDto);
		return list1;
	}

	
}
