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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.biz.common.constants.BizConstant;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.biz.common.utils.Menu;
import com.yeejoin.amos.boot.biz.common.utils.TreeParser;
import com.yeejoin.amos.boot.module.common.api.dto.LinkageUnitDto;
import com.yeejoin.amos.boot.module.common.api.dto.LinkageUnitZhDto;
import com.yeejoin.amos.boot.module.common.api.dto.RequestData;
import com.yeejoin.amos.boot.module.common.api.entity.DynamicFormColumn;
import com.yeejoin.amos.boot.module.common.api.entity.DynamicFormInstance;
import com.yeejoin.amos.boot.module.common.api.entity.LinkageUnit;
import com.yeejoin.amos.boot.module.common.api.entity.SourceFile;
import com.yeejoin.amos.boot.module.common.api.mapper.LinkageUnitMapper;
import com.yeejoin.amos.boot.module.common.api.service.ILinkageUnitService;
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.annotation.Condition;
import org.typroject.tyboot.core.rdbms.annotation.Operator;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 联动单位服务实现类
 *
 * @author system_generator
 * @date 2021-07-16
 */
@Service
public class LinkageUnitServiceImpl extends BaseService<LinkageUnitDto, LinkageUnit, LinkageUnitMapper>
		implements ILinkageUnitService {

	@Autowired
	DynamicFormInstanceServiceImpl dynamicFormInstanceService;

	@Resource
	LinkageUnitMapper linkageUnitMapper;
	@Autowired
	DynamicFormColumnServiceImpl dynamicFormColumnService;
	@Autowired
	SourceFileServiceImpl sourceFileServiceImpl;

	@Autowired
	DataDictionaryServiceImpl iDataDictionaryService;

	public String getGroupCode() {
		return "linkageUnit";
	}

	/**
	 * 分页查询
	 * 
	 * @param inAgreement
	 */
	@Override
	public Page<LinkageUnitDto> queryForLinkageUnitPage(IPage<LinkageUnitDto> page,


			 Boolean isDelete, String unitName,
			String linkageUnitTypeCode,
			 String linkageUnitType,  String emergencyLinkageUnitCode,
			String inAgreement,
														String bizOrgCode) {
		Page<List<LinkageUnitDto>> linkageUnitList = linkageUnitMapper.getEmergencyLinkageUnitList(page,unitName, linkageUnitType,linkageUnitTypeCode, emergencyLinkageUnitCode,inAgreement, bizOrgCode);
		List<Map> linkageUnitListMap =JSONArray.parseArray(JSONArray.toJSONString(linkageUnitList.getRecords()), Map.class);
		
		List<Map<String, Object>> pageList = dynamicFormInstanceService.listAll(getGroupCode());
		linkageUnitListMap.forEach(i -> {
			String mainString = i.get("instanceId").toString();
			pageList.stream().forEach(detail -> {
				if (detail.get("instanceId").toString().equals(mainString)) {
					i.putAll(detail);
				}
			});
		});

		List<LinkageUnitDto> resultDtoList = JSONArray.parseArray(JSONArray.toJSONString(linkageUnitListMap),
				LinkageUnitDto.class);
		List<LinkageUnitDto> detaiList = resultDtoList.stream().map(item -> {
			Date now = new Date();
			boolean isInAgreement = DateUtils.belongCalendar(now, item.getAgreementStartDate(),
					item.getAgreementEndDate());
			item.setInAgreement(isInAgreement ? "是" : "否");
			List<SourceFile> sourceFiles = sourceFileServiceImpl.findBySourceId(item.getSequenceNbr());
			item.setImage(sourceFiles);
			return item;
		}).collect(Collectors.toList());
        //.filter(item -> StringUtils.isEmpty(inAgreement) || inAgreement.equals(item.getInAgreement()))
		Page<LinkageUnitDto> page1 = new Page<LinkageUnitDto>();
		page1.setCurrent(page.getCurrent());
		page1.setSize(page.getSize());
		page1.setTotal(linkageUnitList.getTotal()); // TOTAL 需要统计所有存在的数据BUG2590 by kongfm
		page1.setRecords(detaiList);
		return page1;
	}

	/**
	 * 列表查询 示例
	 */
	@Override
	public List<LinkageUnitDto> queryForLinkageUnitList(@Condition(Operator.eq) Boolean isDelete) {
		return this.queryForList("", false, isDelete);
	}

	/**
	 * 保存联动单位
	 *
	 * @param linkageUnitDto 对象
	 * @return List<LinkageUnitDto>
	 */
	@Transactional
	public LinkageUnitDto saveModel(LinkageUnitDto linkageUnitDto) {

		if (linkageUnitDto.getAddress() != null) {
			JSONObject address = WaterResourceServiceImpl.getLongLatFromAddress(linkageUnitDto.getAddress());
			linkageUnitDto.setAddress(address.getString(BizConstant.ADDRESS));
			linkageUnitDto.setLongitude(Double.valueOf(address.getString(BizConstant.LONGITUDE)));
			linkageUnitDto.setLatitude(Double.valueOf(address.getString(BizConstant.LATITUDE)));
		}
		// 1.保存行数据
		String groupCode = this.getGroupCode();
		Map<String, Object> map = Bean.BeantoMap(linkageUnitDto);
		Long instanceId = dynamicFormInstanceService.commonSave(groupCode, map);
		linkageUnitDto.setInstanceId(instanceId);
		// 2.保存基本信息
		linkageUnitDto.setUnitCode(getUnitCodeStr());
		LinkageUnitDto model = createWithModel(linkageUnitDto);
		// 3.保存照片信息
		sourceFileServiceImpl.saveSourceFile(model.getSequenceNbr(), model.getImage());
		// 3.返回保存后的数据
		return model;
	}



	public LinkageUnitDto saveLinkageModel(LinkageUnitDto linkageUnitDto) {


		// 1.保存行数据
		String groupCode = this.getGroupCode();
		Map<String, Object> map = Bean.BeantoMap(linkageUnitDto);
		Long instanceId = dynamicFormInstanceService.commonSave(groupCode, map);
		linkageUnitDto.setInstanceId(instanceId);
		// 2.保存基本信息
		linkageUnitDto.setUnitCode(getUnitCodeStr());
		LinkageUnitDto model = createWithModel(linkageUnitDto);
		// 3.保存照片信息
		sourceFileServiceImpl.saveSourceFile(model.getSequenceNbr(), model.getImage());
		// 3.返回保存后的数据
		return model;
	}



	@Override
	public LinkageUnitDto queryOne(Long sequenceNbr) {
		String groupCode = getGroupCode();
		List<DynamicFormColumn> columns = dynamicFormColumnService
				.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
		Map<String, Object> fieldCodes = Bean.listToMap(columns, "fieldCode", "queryStrategy", DynamicFormColumn.class);
		LinkageUnitDto linkageUnitDto = linkageUnitMapper.selectOne(false, fieldCodes, groupCode, sequenceNbr);
		if (!ValidationUtil.isEmpty(linkageUnitDto)) {
			List<SourceFile> sourceFiles = sourceFileServiceImpl.findBySourceId(linkageUnitDto.getSequenceNbr());
			linkageUnitDto.setImage(sourceFiles);
		}
		return linkageUnitDto;
	}

	@Transactional
	public Boolean deleteById(Long sequenceNbr) {
		// 删除基本信息
		LinkageUnit linkageUnit = getById(sequenceNbr);
		linkageUnit.setIsDelete(true);
		updateById(linkageUnit);
		// 删除行
		Long instanceId = linkageUnit.getInstanceId();
		List<DynamicFormInstance> dynamicFormInstanceList = dynamicFormInstanceService
				.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId, instanceId));
		dynamicFormInstanceList.forEach(item -> item.setIsDelete(true));
		boolean update = dynamicFormInstanceService.updateBatchById(dynamicFormInstanceList);
		// 删除照片
		sourceFileServiceImpl.saveSourceFile(sequenceNbr, new ArrayList<>());
		return update;
	}

	@Transactional
	public LinkageUnitDto updateById(LinkageUnitDto linkageUnitDto) {

		if (linkageUnitDto.getAddress() != null) {
			JSONObject address = WaterResourceServiceImpl.getLongLatFromAddress(linkageUnitDto.getAddress());
			linkageUnitDto.setAddress(address.getString(BizConstant.ADDRESS));
			linkageUnitDto.setLongitude(Double.valueOf(address.getString(BizConstant.LONGITUDE)));
			linkageUnitDto.setLatitude(Double.valueOf(address.getString(BizConstant.LATITUDE)));
		}
		// 修改基本信息
		updateWithModel(linkageUnitDto);
		// 修改行信息
		Long instanceId = linkageUnitDto.getInstanceId();
		if(instanceId != null) { // BUG 2748 联动单位无法保存 bykongfm
			List<DynamicFormInstance> dynamicFormInstanceList = dynamicFormInstanceService
					.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId, instanceId));
			Map<String, Object> objectMap = Bean.BeantoMap(linkageUnitDto);
			dynamicFormInstanceList.forEach(item -> item.setFieldValue(
					objectMap.get(item.getFieldCode()) != null ? objectMap.get(item.getFieldCode()).toString()
							: item.getFieldValue()));
			dynamicFormInstanceService.updateBatchById(dynamicFormInstanceList);
		}
		// 修改照片信息
		sourceFileServiceImpl.saveSourceFile(linkageUnitDto.getSequenceNbr(), linkageUnitDto.getImage());
		return linkageUnitDto;
	}

	public static String getUnitCodeStr() {
		return TreeParser.genTreeCode();
	}

	@Override
	public List<LinkageUnitZhDto> listLinkageUnitZhDto(Integer pageNum, Integer pageSize, RequestData par) {
		if (null == pageNum || null == pageSize) {
			pageNum = 1;
			pageSize = Integer.MAX_VALUE;
		} else {
			pageNum = (pageNum - 1) * pageSize;
		}
		return linkageUnitMapper.listLinkageUnitZhDto(pageNum, pageSize, par);
	}

	@Override
	public Integer listLinkageUnitZhDtoCount(RequestData par) {
		return linkageUnitMapper.listLinkageUnitZhDtoCount(par);
	}

	/**
	 * 批量删除
	 *
	 * @param sequenceNbrList
	 * @return
	 */
	public Boolean batchDelete(List<Long> sequenceNbrList) {
		// 删除基本信息
		List<LinkageUnit> linkageUnitList = list(
				new LambdaQueryWrapper<LinkageUnit>().in(LinkageUnit::getSequenceNbr, sequenceNbrList));
		List<Long> instanceIdList = Lists.newArrayList();
		linkageUnitList.forEach(item -> {
			instanceIdList.add(item.getInstanceId());
			item.setIsDelete(true);
		});
		updateBatchById(linkageUnitList);
		// 删除行信息
		List<DynamicFormInstance> dynamicFormInstanceList = dynamicFormInstanceService.list(
				new LambdaQueryWrapper<DynamicFormInstance>().in(DynamicFormInstance::getInstanceId, instanceIdList));
		dynamicFormInstanceList.forEach(item -> item.setIsDelete(true));
		boolean update = dynamicFormInstanceService.updateBatchById(dynamicFormInstanceList);
		// 删除照片
		sourceFileServiceImpl.getBaseMapper()
				.delete(new LambdaQueryWrapper<SourceFile>().in(SourceFile::getSourceId, sequenceNbrList));
		return update;
	}

	@Override
	public List<Menu> getEmergencyLinkageUnitCodeGroupBy(String type, String rootName, String bizOrgCode) {
		List<Map<String, Object>> map = linkageUnitMapper.getEmergencyLinkageUnitCodeGroupByAndCount(bizOrgCode);

		LambdaQueryWrapper<DataDictionary> queryWrapper = new LambdaQueryWrapper<DataDictionary>();
		queryWrapper.eq(DataDictionary::getType, type);
		queryWrapper.eq(DataDictionary::getIsDelete, false);
		queryWrapper.orderByAsc(DataDictionary::getSortNum);
		List<DataDictionary> list = iDataDictionaryService.list(queryWrapper);
		List<DataDictionary> resultList = new ArrayList<DataDictionary>();
		list.stream().forEach(i -> {
			map.stream().forEach(m -> {
				if (m.containsKey("emergencyLinkageUnitCode") && m.get("emergencyLinkageUnitCode").toString().equals(i.getCode())) {
					i.setName(i.getName() + " " + m.get("count"));
					resultList.add(i);
				}
			});
		});
		List<Menu> menuList = new ArrayList<Menu>();
		try {
			List<Menu>	menus = TreeParser.getTree(null, resultList, DataDictionary.class.getName(), "getCode", 0, "getName",
					"getParent", null,null);
			Menu menu = new Menu(-1L, rootName, -1L, menus, 0);
			// 挂在主节点
			menuList.add(menu);
		} catch (Exception e) {
		log.debug("拼装tree树失败");
		}
		return menuList;
	}

	@Override
	public List<LinkageUnitDto> exportToExcel(String unitName,String linkageUnitTypeCode,String emergencyLinkageUnitCode, String bizOrgCode) {
		if ("null".equals(unitName)) {
			unitName = null;
		}
		if ("null".equals(linkageUnitTypeCode)) {
			linkageUnitTypeCode = null;
		}
		if ("null".equals(emergencyLinkageUnitCode)) {
			emergencyLinkageUnitCode = null;
		}
		if ("null".equals(bizOrgCode)) {
			bizOrgCode = null;
		}
		return linkageUnitMapper.exportToExcel(unitName,linkageUnitTypeCode,emergencyLinkageUnitCode, bizOrgCode);
	}

}