package com.yeejoin.amos.api.openapi.controller;

import com.yeejoin.amos.api.common.restful.utils.ResponseHelper;
import com.yeejoin.amos.api.common.restful.utils.ResponseModel;
import com.yeejoin.amos.api.openapi.constant.Constant;
import com.yeejoin.amos.api.openapi.face.model.*;
import com.yeejoin.amos.api.openapi.face.service.*;
import com.yeejoin.amos.boot.module.cylinder.api.dto.CylinderFillingMessage;
import com.yeejoin.amos.boot.module.cylinder.api.dto.CylinderFillingMessageModel;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.typroject.tyboot.component.cache.Redis;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.component.event.RestEventTrigger;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping(value = "/cylinder")
@Api(tags = "cylinder-气瓶数据对接")
public class CylinderController {
	private static final Logger logger = LogManager.getLogger(CylinderController.class);
	@Autowired
	private TmCylinderUnitService cylinderUnitService;
	@Autowired
	private TmCylinderFillingCheckService cylinderFillingCheckService;
	@Autowired
	private TmCylinderFillingExamineService cylinderFillingExamineService;
	@Autowired
	private TmCylinderFillingRecordService cylinderFillingRecordService;
	@Autowired
	private TmCylinderFillingService cylinderFillingService;
	@Autowired
	private TmCylinderInfoService cylinderInfoService;
	@Autowired
	private TmCylinderInspectionService cylinderInspectionService;
	@Autowired
	private TmCylinderTagsService cylinderTagsService;
	@Autowired
	private CylinderFillingDataValidationService cylinderFillingDataValidationService;
	@Autowired
	TmCylinderFillingMessageService cylinderFillingMessageService;
	@Autowired
	private EmqKeeper emqKeeper;
	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private TmCylinderOffloadingService cylinderOffloadingService;

	private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(value = "气瓶企业信息")
	@PostMapping(value = "/unit")
	@RestEventTrigger(value = "openapiLogEventHandler")
	public ResponseModel<String> cylinderUnit(@RequestBody List<TmCylinderUnitModel> unitData) {
		cylinderFillingDataValidationService.validateCylinderUnit(unitData);
		return ResponseHelper.buildResponse(cylinderUnitService.createCylinderUnit(unitData));
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(value = "气瓶基础数据")
	@PostMapping(value = "/info")
	@RestEventTrigger(value = "openapiLogEventHandler")
	public ResponseModel<String> cylinderInfo(@RequestBody List<TmCylinderInfoModel> infoData) {
		cylinderFillingDataValidationService.validateCylinderInfo(infoData);
		return ResponseHelper.buildResponse(cylinderInfoService.createCylinderInfo(infoData));
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(value = "气瓶标签数据")
	@PostMapping(value = "/tag")
	@RestEventTrigger(value = "openapiLogEventHandler")
	public ResponseModel<String> cylinderTagInfo(@RequestBody List<TmCylinderTagsModel> tagData) {
		cylinderFillingDataValidationService.validateCylinderTag(tagData);
		return ResponseHelper.buildResponse(cylinderTagsService.createCylinderTag(tagData));
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(value = "气瓶检验数据")
	@PostMapping(value = "/inspection")
	@RestEventTrigger(value = "openapiLogEventHandler")
	public ResponseModel<String> cylinderInspectionInfo(@RequestBody List<TmCylinderInspectionModel> inspectionData) {
		cylinderFillingDataValidationService.validateCylinderInspection(inspectionData);
		return ResponseHelper.buildResponse(cylinderInspectionService.createCylinderInspection(inspectionData));

	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(value = "气瓶充装数据")
	@PostMapping(value = "/filling")
	@RestEventTrigger(value = "openapiLogEventHandler")
	public ResponseModel<String> cylinderFillingInfo(@RequestBody String fillingData) throws Exception {
		String token = RequestContext.getToken();
		AgencyUserModel me = Privilege.agencyUserClient.getme().getResult();
		String tokenKey = Redis.genKey(Constant.TOKEN_PREFIX, token);
		BizTokenModel bizTokenModel = (BizTokenModel)this.redisTemplate.opsForValue().get(tokenKey);

		JSONObject jsonobject = JSONObject.fromObject(fillingData);
		CylinderFillingDataValidationResultModel validateResult = null;
		CylinderFillingMessage cylinderFillingMessage = new CylinderFillingMessage();
		cylinderFillingMessage.setTime(simpleDateFormat.format(new Date()));
		cylinderFillingMessage.setFillingCompanyName(me.getCompanys().get(0).getCompanyName());
		cylinderFillingMessage.setAppId(bizTokenModel.getAppId());
		try {
			validateResult = cylinderFillingDataValidationService.validateFilling(jsonobject);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("液化气体气瓶充装信息上报，数据校验失败");
			cylinderFillingMessage.setMessage(e.getMessage());
		}

		if (!ObjectUtils.isEmpty(validateResult)) {
			cylinderFillingMessage.setCylinderNumber(validateResult.getCylinderNumber());
			List<String> message = new ArrayList<>();
            Integer errorNumber = 0;
			JSONObject error = new JSONObject();
			if (!ObjectUtils.isEmpty(validateResult.getBeforeErrorData())) {
				errorNumber += validateResult.getBeforeErrorData().size();
				error.put("充装前检查错误数据：", validateResult.getBeforeErrorData());
				message.add("充装前检查数据异常气瓶数：" + validateResult.getBeforeErrorCylinderNumber());
			}

			if (!ObjectUtils.isEmpty(validateResult.getRecordErrorData())) {
				errorNumber += validateResult.getRecordErrorData().size();
				error.put("填充错误数据：", validateResult.getRecordErrorData());
				message.add("充装记录数据异常气瓶数：" + validateResult.getRecordErrorCylinderNumber());
			}

			if (!ObjectUtils.isEmpty(validateResult.getAfterErrorData())) {
				errorNumber += validateResult.getAfterErrorData().size();
				error.put("充装后错误数据：", validateResult.getAfterErrorData());
				message.add("充装后复查数据异常气瓶数：" + validateResult.getAfterErrorCylinderNumber());
			}
			if (errorNumber <= 0) {
				message.add("液化气体气瓶充装信息成功数：" + validateResult.getSuccessCylinderNumber() + "条");
			} else {
				cylinderFillingMessage.setMessage(String.join("条; ", message));
				CylinderFillingMessageModel cylinderFillingMessageModel = new CylinderFillingMessageModel();
				BeanUtils.copyProperties(cylinderFillingMessage, cylinderFillingMessageModel);
				cylinderFillingMessageService.createWithModel(cylinderFillingMessageModel);
				emqKeeper.getMqttClient().publish("openapi/cylinder/filling", JSONObject.fromObject(cylinderFillingMessage).toString().getBytes(), 2, false);

				throw new BadRequest(error.toString());
			}
		} else {
			throw new BadRequest("数据校验失败！！！");
		}

		TmCylinderFillingModelList cylinderFillingModelList = com.alibaba.fastjson.JSONObject.parseObject(fillingData, TmCylinderFillingModelList.class);

		List<TmCylinderFillingModel> fillingBeforeList = cylinderFillingModelList.getFillingBefore();
		List<TmCylinderFillingRecordModel> fillingList = cylinderFillingModelList.getFilling();
		List<TmCylinderFillingCheckModel> fillingAfterList = cylinderFillingModelList.getFillingAfter();
		if (ValidationUtil.isEmpty(fillingBeforeList) && ValidationUtil.isEmpty(fillingList) && ValidationUtil.isEmpty(fillingAfterList)) {
			throw new BadRequest("液化气体气瓶充装信息-充装前检查信息、液化气体气瓶充装信息-充装记录信息、液化气体气瓶充装信息-充装后复查信息为空.");
		}
		cylinderFillingService.createCylinderFillingBefore(fillingBeforeList);
		cylinderFillingRecordService.createCylinderFilling(fillingList);
		cylinderFillingCheckService.createCylinderFillingAfter(fillingAfterList);

		CylinderFillingMessageModel cylinderFillingMessageModel = new CylinderFillingMessageModel();
		BeanUtils.copyProperties(cylinderFillingMessage, cylinderFillingMessageModel);
		cylinderFillingMessageModel.setAppId(bizTokenModel.getAppId());
		cylinderFillingMessageService.createWithModel(cylinderFillingMessageModel);
		emqKeeper.getMqttClient().publish("openapi/cylinder/filling", JSONObject.fromObject(cylinderFillingMessage).toString().getBytes(), 2, false);

		return ResponseHelper.buildResponse("OK");
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(value = "气瓶充装审核数据")
	@PostMapping(value = "/fillingAudit")
	@RestEventTrigger(value = "openapiLogEventHandler")
	public ResponseModel<String> cylinderFillingAudit(@RequestBody List<TmCylinderFillingExamineModel> fillingAuditData) {
		cylinderFillingDataValidationService.validateCylinderFillingExamineModel(fillingAuditData);
		return ResponseHelper.buildResponse(cylinderFillingExamineService.createCylinderFillingExamine(fillingAuditData));
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(value = "气站卸液量记录数据")
	@PostMapping(value = "/offloading")
	@RestEventTrigger(value = "openapiLogEventHandler")
	public ResponseModel<String> createCylinderOffloading(@RequestBody List<TmCylinderOffloadingModel> offloadingData) {
		cylinderFillingDataValidationService.validateCylinderOffloadingData(offloadingData);
		return ResponseHelper.buildResponse(cylinderOffloadingService.createCylinderOffloading(offloadingData));
	}
}
