package com.mortals.xhx.module.api.web;

import com.mortals.framework.common.IBaseEnum;
import com.mortals.framework.common.code.YesNo;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.DbOrderKind;
import com.mortals.framework.model.OrderCol;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.base.system.param.model.ParamEntity;
import com.mortals.xhx.base.system.param.model.ParamQuery;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.common.code.AssetFlowStatusEnum;
import com.mortals.xhx.common.code.EventFieldInputTypeEnum;
import com.mortals.xhx.common.key.Constant;
import com.mortals.xhx.module.api.RspCode;
import com.mortals.xhx.module.api.common.*;
import com.mortals.xhx.module.api.model.*;
import com.mortals.xhx.module.api.service.AssetFlowStatusService;
import com.mortals.xhx.module.asset.model.*;
import com.mortals.xhx.module.asset.service.AssetFlowEventFieldService;
import com.mortals.xhx.module.asset.service.AssetFlowEventLogService;
import com.mortals.xhx.module.asset.service.AssetFlowEventService;
import com.mortals.xhx.module.asset.service.AssetService;
import com.mortals.xhx.module.materia.service.MateriaService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 *
 *
 * @author luoshichao
 * @Description
 * @date 2021/1/8 10:43
 */
@Api(tags = "资产服务")
@RestController
@RequestMapping(value = "api/asset", method = RequestMethod.POST)
public class AssetApiController extends BaseApiController {

	@Autowired
	private AssetFlowStatusService assetFlowStatusService;
	@Autowired
	private AssetService assetService;

	@Autowired
	private ParamService paramService;

	@Autowired
	private AssetFlowEventFieldService  assetFlowEventFieldService;

	@Autowired
	private AssetFlowEventLogService assetFlowEventLogService;

	@Autowired
	private AssetFlowEventService assetFlowEventService;

	@Autowired
	private MateriaService materiaService;

	/**
	 * 获取资产信息
	 * 
	 * @param params
	 * @return
	 */
	@ApiOperation("获取资产信息")
	@RequestMapping("/get")
	public BaseRsp<ListQueryResultRsp<AssetGetRsp>> get(@RequestBody  QueryApiReq<AssetGetReq> params) {
		BaseRsp<ListQueryResultRsp<AssetGetRsp>> baseRsp = BaseRsp.buildSuccRsp();
		ListQueryResultRsp<AssetGetRsp> resultData = new ListQueryResultRsp<>();
		//字典信息
		Map<String, Object> dict = new HashMap<>();
		dict.put("flowStatus", paramService.getParamByFirstOrganize(Constant.Param_AssetFlowStatus,AssetFlowStatusEnum.Special_597.getValue(),Constant.Param_AssetFlowStatus,
				AssetFlowStatusEnum.Special_598.getValue(), AssetFlowStatusEnum.Special_599.getValue()));

		//数据结果集
		List<AssetGetRsp> resultList = new ArrayList<>();
		try {
			AssetGetReq assetGetReq = params.getQuery();
			if(assetGetReq.getAssetNumList() == null || assetGetReq.getAssetNumList().isEmpty()){
				throw new AppException("资产码不能为空");
			}
			if(assetGetReq.getAssetNumList().size() > 50){
				throw new AppException("资产码最多50个");
			}
			//如果是初始化录入设备，选择的bom版本字典
			List<BomInfoResp> bomDictList = new ArrayList<>();
			List<Map> bomList = materiaService.getBomInfoByAssetCode(assetGetReq.getAssetNumList().get(0));
			if(!bomList.isEmpty()){

				for (Map item: bomList  ) {
					BomInfoResp info = new BomInfoResp();
					PropertyUtils.copyProperties(info, item);
					bomDictList.add(info);
				}
			}
			dict.put("bomInfoList", bomDictList);
			AssetQuery assetQuery = new AssetQuery();
			assetQuery.setAssetNumList(assetGetReq.getAssetNumList());
			List<AssetEntity> assetEntities = assetService.find(assetQuery, null);
			assetEntities.stream().forEach(assetEntity -> {
				AssetGetRsp resp = new AssetGetRsp();
				BeanUtils.copyProperties(assetEntity, resp);
				if (assetGetReq.getReturnNextEvent() == YesNo.YES.getValue()) {
					List<AssetEventInfo> followEventResp = assetFlowStatusService
							.getNextEventList(assetEntity.getAssetNum());
					resp.setNextEventList(followEventResp);
				}



				resultList.add(resp);
			});
			resultData.setDict(dict);
			resultData.setList(resultList);
			baseRsp.setData(resultData);
		} catch (Exception e) {
			baseRsp = BaseRsp.buildFailRsp(RspCode.UNKNOWN_ERROR.getValue(), super.convertException(e));
		}
		return baseRsp;
	}

	/**
	 * 提交事件日志
	 * 
	 * @param params
	 * @return
	 */
	@ApiOperation("提交事件日志")
	@RequestMapping("/event/log/submit")
	public BaseRsp<List<AssetEventResp>> submitLog(@RequestBody  EntityApiReq<AssetEventLogSubmitReq> params) {
		BaseRsp<List<AssetEventResp>> baseRsp = BaseRsp.buildSuccRsp();
		List<AssetEventResp> resultList = new ArrayList<>();
		try {
			AssetEventLogSubmitReq assetEventLogSubmitReq = params.getEntity();
			assetFlowStatusService.execute(assetEventLogSubmitReq);
			if (assetEventLogSubmitReq.getReturnNextEvent() == YesNo.YES.getValue()) {
				assetEventLogSubmitReq.getAssetNumList().stream().forEach(assetNum ->{
					List<AssetEventInfo> eventList = assetFlowStatusService.getNextEventList(assetNum);
					AssetEventResp eventGetResp = new AssetEventResp();
					eventGetResp.setAssetNum(assetNum);
					eventGetResp.setNextEventList(eventList);
					resultList.add(eventGetResp);
				});

				baseRsp.setData(resultList);
			}
		} catch (Exception e) {
			log.error("", e);
			baseRsp = BaseRsp.buildFailRsp(RspCode.UNKNOWN_ERROR.getValue(), super.convertException(e));
		}
		return baseRsp;
	}

	/**
	 * 获取资产可操作后续事件
	 * 
	 * @param
	 * @return
	 */
	@ApiOperation("获取资产可操作后续事件")
	@RequestMapping("/event/get")
	public BaseRsp<ListQueryResultRsp<AssetEventResp>> getNextEventList(@RequestBody QueryApiReq<AssetEventGetReq> params) {
		BaseRsp<ListQueryResultRsp<AssetEventResp>> baseRsp = BaseRsp.buildSuccRsp();
		ListQueryResultRsp<AssetEventResp> resultData = new ListQueryResultRsp<>();
		List<AssetEventResp> resultList = new ArrayList<>();
		try {
			AssetEventGetReq req = params.getQuery();
			if(req.getAssetNumList() == null || req.getAssetNumList().isEmpty()){
				throw new AppException("资产码不能为空");
			}
			if(req.getAssetNumList().size() > 50){
				throw new AppException("资产码最多50个");
			}
			req.getAssetNumList().stream().forEach(assetNum ->{
				List<AssetEventInfo> eventList = assetFlowStatusService.getNextEventList(assetNum);
				AssetEventResp eventGetResp = new AssetEventResp();
				eventGetResp.setAssetNum(assetNum);
				eventGetResp.setNextEventList(eventList);
				resultList.add(eventGetResp);
			});
			resultData.setList(resultList);
			baseRsp.setData(resultData);
		} catch (Exception e) {
			log.error("", e);
			baseRsp = BaseRsp.buildFailRsp(RspCode.UNKNOWN_ERROR.getValue(), super.convertException(e));
		}
		return baseRsp;
	}


	/**
	 * 添加资产
	 * @param params
	 * @return
	 */
	@ApiOperation("初始化资产")
	@RequestMapping("/add")
	public BaseRsp<List<AssetEventInfo>> add(@RequestBody EntityApiReq<AssetAddReq> params) {
		BaseRsp<List<AssetEventInfo>> baseRsp = BaseRsp.buildSuccRsp();
		try {

			AssetAddReq assetAddReq = params.getEntity();

			AssetEntity assetEntity = new AssetEntity();
			assetEntity.initAttrValue();
			assetEntity.setAssetNum(assetAddReq.getAssetNum());
			//需要业务码的状态
			List<Integer> needDeviceNumStatus =  Arrays.asList(511, 512, 513);
			if(needDeviceNumStatus.contains(assetAddReq.getFlowStatus()) && StringUtils.isEmpty(assetAddReq.getDeviceNum())){
				throw new AppException("请输入设备业务码");
			}

			if(StringUtils.isNotEmpty(assetAddReq.getDeviceNum())){
				assetEntity.setDeviceNum(assetAddReq.getDeviceNum());
			}
			assetEntity.setBeforeFlowStatus(assetAddReq.getFlowStatus());
			assetEntity.setFlowStatus(assetAddReq.getFlowStatus());
			//TODO BOM相关信息
			assetEntity.setBomId(assetAddReq.getBomId());
			assetEntity.setCreateTime(new Date());
			assetEntity.setUpdateTime(new Date());
			assetEntity.setCreateUser(assetAddReq.getEventUser());
			assetEntity.setUpdateUser(assetAddReq.getEventUser());
			assetService.initEntity(assetEntity);

			List<AssetEventInfo> eventList = assetFlowStatusService.getNextEventList(assetAddReq.getAssetNum());
			baseRsp.setData(eventList);
		} catch (Exception e) {
			log.error("", e);
			baseRsp = BaseRsp.buildFailRsp(RspCode.UNKNOWN_ERROR.getValue(), super.convertException(e));
		}
		return baseRsp;
	}

	@ApiOperation("查询资产状态接口")
	@RequestMapping("/status/list")
	public BaseRsp<ListQueryResultRsp<AssetFlowStatusInfo>> getStatusList() {
		BaseRsp<ListQueryResultRsp<AssetFlowStatusInfo>> baseRsp = BaseRsp.buildSuccRsp();

		ListQueryResultRsp<AssetFlowStatusInfo> resultData = new ListQueryResultRsp<>();

		try {
			ParamQuery paramQuery = new ParamQuery();
			paramQuery.setFirstOrganize(Constant.Param_AssetFlowStatus);
			//暂时不考虑分页
			List<ParamEntity> list = paramService.find(paramQuery, null);

			//特殊状态去掉
			List<String> excludeParamKeys =  Arrays.asList(AssetFlowStatusEnum.Special_597.getValue(), AssetFlowStatusEnum.Special_598.getValue(), AssetFlowStatusEnum.Special_599.getValue());
			List<AssetFlowStatusInfo> resultList = list.stream().filter(item ->{
				return !excludeParamKeys.contains(item.getParamKey());
			}).map(item ->{
				AssetFlowStatusInfo statusInfo = new AssetFlowStatusInfo();
				statusInfo.setFlowStatus(item.getParamKey());
				statusInfo.setFlowStatusName(item.getParamValue());
				return statusInfo;
			}).collect(Collectors.toList());
			resultData.setList(resultList);
			baseRsp.setData(resultData);
		} catch (Exception e) {
			log.error("", e);
			baseRsp = BaseRsp.buildFailRsp(RspCode.UNKNOWN_ERROR.getValue(), super.convertException(e));
		}
		return baseRsp;
	}

	@ApiOperation("查询资产事件扩展参数字段接口")
	@RequestMapping("/event/field/list")
	public BaseRsp<ListQueryResultRsp<AssetEventFieldInfo>> getEventFieldList(@RequestBody QueryApiReq<AssetEventFieldReq> params) {
		BaseRsp<ListQueryResultRsp<AssetEventFieldInfo>> baseRsp = BaseRsp.buildSuccRsp();
		ListQueryResultRsp<AssetEventFieldInfo> resultData = new ListQueryResultRsp<>();

		//字典信息
		Map<String, Object> dict = new HashMap<>();
		Map<String, String> fieldType = new HashMap<>();
		fieldType.put(String.class.getSimpleName(), String.class.getSimpleName());
		fieldType.put(Integer.class.getSimpleName(), Integer.class.getSimpleName());
		fieldType.put(Long.class.getSimpleName(), Long.class.getSimpleName());
		fieldType.put(Float.class.getSimpleName(), Float.class.getSimpleName());
		fieldType.put(Double.class.getSimpleName(), Double.class.getSimpleName());
		dict.put("fieldType", fieldType);
		dict.put("fieldNull", IBaseEnum.getEnumMap(YesNo.class));
		dict.put( "inputType", IBaseEnum.getEnumMap(EventFieldInputTypeEnum.class));
		resultData.setDict(dict);

		try {
			//结果list
			List<AssetEventFieldInfo> resultList = new ArrayList<>();
			AssetEventFieldReq assetEventFieldReq = params.getQuery();
			if(StringUtils.isEmpty(assetEventFieldReq.getEventCode())){
				throw new AppException("参数错误，事件码不能为空");
			}

			AssetFlowEventFieldQuery assetFlowEventFieldQuery = new AssetFlowEventFieldQuery();
			assetFlowEventFieldQuery.setEventCode(assetEventFieldReq.getEventCode());
			//只查启用的
			assetFlowEventFieldQuery.setEnabled(YesNo.YES.getValue());
			//暂时不考虑分页
			List<AssetFlowEventFieldEntity> list =  assetFlowEventFieldService.find(assetFlowEventFieldQuery, null);
			if(!list.isEmpty()){
				resultList = list.stream().map(item->{
					AssetEventFieldInfo info = new AssetEventFieldInfo();
					BeanUtils.copyProperties(item, info);
					return info;
				}).collect(Collectors.toList());
			}
			resultData.setList(resultList);
			baseRsp.setData(resultData);
		} catch (Exception e) {
			log.error("", e);
			baseRsp = BaseRsp.buildFailRsp(RspCode.UNKNOWN_ERROR.getValue(), super.convertException(e));
		}
		return baseRsp;
	}


	@ApiOperation("查询资产事件日志列表接口")
	@RequestMapping("/event/log/list")
	public BaseRsp<ListQueryResultRsp<AssetEventLogInfo>> getEventLogList(@RequestBody QueryApiReq<AssetEventLogGetReq> params) {
		BaseRsp<ListQueryResultRsp<AssetEventLogInfo>> baseRsp = BaseRsp.buildSuccRsp();
		ListQueryResultRsp<AssetEventLogInfo> resultData = new ListQueryResultRsp<>();

		//字典信息
		Map<String, Object> dict = new HashMap<>();
		dict.put("fieldNull", IBaseEnum.getEnumMap(YesNo.class));
		dict.put( "inputType", IBaseEnum.getEnumMap(EventFieldInputTypeEnum.class));
		dict.put( "afteStatus", paramService.getParamByFirstOrganize(Constant.Param_AssetFlowStatus));
		dict.put( "beforeStatus", paramService.getParamByFirstOrganize(Constant.Param_AssetFlowStatus));
		AssetFlowEventQuery eventQuery = new AssetFlowEventQuery();
		eventQuery.setOrderColList(new ArrayList<OrderCol>() {
			{
				add(new OrderCol("orderNo", OrderCol.ASCENDING));
			}
		});
		List<AssetFlowEventEntity> eventEntityList = assetFlowEventService.find(eventQuery, null);
		dict.put( "eventCode", eventEntityList.stream().collect(Collectors.toMap(e->e.getCode() +"", e->e.getName() )));

		resultData.setDict(dict);

		try {
			List<AssetEventLogInfo> resultList = new ArrayList<>();
			AssetEventLogGetReq req = params.getQuery();

			AssetFlowEventLogQuery assetFlowEventLogQuery = new AssetFlowEventLogQuery();
			if(StringUtils.isEmpty(req.getEventUser())){
				throw new AppException("事件经手人为空");
			}
			assetFlowEventLogQuery.setEventUser(req.getEventUser());
			if(params.getOrderCols() != null && !params.getOrderCols().isEmpty()){
				assetFlowEventLogQuery.setOrderCols(params.getOrderCols());
			}else{
				//ID倒序排序
				Map<String, String> orderCols = new HashMap<>(1);
				orderCols.put("id", DbOrderKind.DESC.name());
				assetFlowEventLogQuery.setOrderCols(orderCols);
			}

			PageInfoReq pageInfoReq = params.getPageInfo();
			if (pageInfoReq != null && pageInfoReq.getPrePageResult() != 0) {//分页
				PageInfo pageInfo = new PageInfo();
				pageInfo.setCurrPage(pageInfoReq.getCurrPage());
				pageInfo.setPrePageResult(pageInfoReq.getPrePageResult());
				Result<AssetFlowEventLogEntity> eventLogEntityResult = assetFlowEventLogService.find(assetFlowEventLogQuery, pageInfo, null);

				//分页信息
				PageInfoRsp pageInfoRsp = new PageInfoRsp();
				PropertyUtils.copyProperties(pageInfoRsp, eventLogEntityResult.getPageInfo());
				resultData.setPageInfo(pageInfoRsp);

				List<AssetFlowEventLogEntity> list = eventLogEntityResult.getList();
				if(!list.isEmpty()){
					resultList = list.stream().map(item->{
						AssetEventLogInfo info = new AssetEventLogInfo();
						BeanUtils.copyProperties(item, info);
						return info;
					}).collect(Collectors.toList());
				}
				resultData.setList(resultList);

			}else { //不分页
				List<AssetFlowEventLogEntity> list = assetFlowEventLogService.find(assetFlowEventLogQuery, null);
				if(!list.isEmpty()){
					for(AssetFlowEventLogEntity item: list){
						AssetEventLogInfo info = new AssetEventLogInfo();
						BeanUtils.copyProperties(item, info);
						resultList.add(info);
					}
					/*list.stream().forEach(item->{

					});*/
				}
				resultData.setList(resultList);
			}
			baseRsp.setData(resultData);
		} catch (Exception e) {
			log.error("", e);
			baseRsp = BaseRsp.buildFailRsp(RspCode.UNKNOWN_ERROR.getValue(), super.convertException(e));
		}
		return baseRsp;
	}


	@ApiOperation("查询资产事件日志单个接口")
	@RequestMapping("/event/log/get")
	public BaseRsp<EntityQueryResultRsp<AssetEventLogInfo>> getEventLog(@RequestBody QueryApiReq<AssetEventLogGetReq> params) {
		BaseRsp<EntityQueryResultRsp<AssetEventLogInfo>> baseRsp = BaseRsp.buildSuccRsp();
		EntityQueryResultRsp<AssetEventLogInfo> resultData = new EntityQueryResultRsp<>();

		//字典信息
		Map<String, Object> dict = new HashMap<>();
		dict.put("fieldNull", IBaseEnum.getEnumMap(YesNo.class));
		dict.put( "inputType", IBaseEnum.getEnumMap(EventFieldInputTypeEnum.class));
		dict.put( "afteStatus", paramService.getParamByFirstOrganize(Constant.Param_AssetFlowStatus));
		dict.put( "beforeStatus", paramService.getParamByFirstOrganize(Constant.Param_AssetFlowStatus));
		AssetFlowEventQuery eventQuery = new AssetFlowEventQuery();
		eventQuery.setOrderColList(new ArrayList<OrderCol>() {
			{
				add(new OrderCol("orderNo", OrderCol.ASCENDING));
			}
		});
		List<AssetFlowEventEntity> eventEntityList = assetFlowEventService.find(eventQuery, null);
		dict.put( "eventCode", eventEntityList.stream().collect(Collectors.toMap(e->e.getCode() +"", e->e.getName() )));

		resultData.setDict(dict);
		/*resultData.setEntity();*/

		try {
			AssetEventLogGetReq req = params.getQuery();

			AssetFlowEventLogQuery assetFlowEventLogQuery = new AssetFlowEventLogQuery();
			if(req.getId() == null){
				throw new AppException("事件日志ID为空");
			}
			assetFlowEventLogQuery.setId(req.getId());
			if(StringUtils.isNotEmpty(req.getEventUser())){
				assetFlowEventLogQuery.setEventUser(req.getEventUser());
			}
			List<AssetFlowEventLogEntity> list = assetFlowEventLogService.find(assetFlowEventLogQuery, null);
			if(!list.isEmpty()){
				AssetFlowEventLogEntity entity = list.get(0);
				AssetEventLogInfo info = new AssetEventLogInfo();
				BeanUtils.copyProperties(entity, info);
				resultData.setEntity(info);
			}
			baseRsp.setData(resultData);
		} catch (Exception e) {
			log.error("", e);
			baseRsp = BaseRsp.buildFailRsp(RspCode.UNKNOWN_ERROR.getValue(), super.convertException(e));
		}
		return baseRsp;
	}

	@ApiOperation("bom信息列表接口")
	@RequestMapping("/bom/version/list")
	public BaseRsp<ListQueryResultRsp<BomInfoResp>> getBomVersionList(@RequestBody QueryApiReq<BomInfoReq> params) {
		BaseRsp<ListQueryResultRsp<BomInfoResp>> baseRsp = BaseRsp.buildSuccRsp();
		ListQueryResultRsp<BomInfoResp> resultData = new ListQueryResultRsp<>();

		//字典信息
		Map<String, Object> dict = new HashMap<>();
		dict.put("fieldNull", IBaseEnum.getEnumMap(YesNo.class));
		resultData.setDict(dict);

		try {
			List<BomInfoResp> resultList = new ArrayList<>();

			BomInfoReq req = params.getQuery();
			if(StringUtils.isEmpty(req.getAssetCode())){
				throw new AppException("资产编码有误");
			}
			List<Map> list = materiaService.getBomInfoByAssetCode(req.getAssetCode());
			if(!list.isEmpty()){
				for (Map item: list  ) {
					BomInfoResp info = new BomInfoResp();
					PropertyUtils.copyProperties(info, item);
					resultList.add(info);
				}
			}
			resultData.setList(resultList);
			baseRsp.setData(resultData);
		} catch (Exception e) {
			log.error("", e);
			baseRsp = BaseRsp.buildFailRsp(RspCode.UNKNOWN_ERROR.getValue(), super.convertException(e));
		}
		return baseRsp;
	}

}
