package com.yifu.cloud.plus.v1.yifu.ekp.util;

import com.yifu.cloud.plus.v1.yifu.ekp.config.EkpOrderProperties;
import com.yifu.cloud.plus.v1.yifu.ekp.constant.EkpConstants;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.AttachmentForm;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpOrderParam;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpOrderReplyParam;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ArrayUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @author licancan
 * @description 对接ekp订单
 * @date 2022-08-31 15:35:20
 */
@Log4j2
@EnableConfigurationProperties(EkpOrderProperties.class)
public class EkpOrderUtil {
	@Autowired
	private EkpOrderProperties ekpProperties;

	/**
	 * 更新订单状态
	 *
	 * @author licancan
	 * @param param
	 * @return {@link String}
	 */
	public String sendOrderToEKP(EkpOrderParam param){
		log.info("推送EKP开始--订单状态");
		RestTemplate yourRestTemplate = new RestTemplate();
		try{
			String formValues = new ObjectMapper().writeValueAsString(param);
			//指向EKP的接口url
			//把ModelingAppModelParameterAddForm转换成MultiValueMap
			MultiValueMap<String,Object> wholeForm = new LinkedMultiValueMap<>();
			wholeForm.add("docSubject",ekpProperties.getOrderDocSubject());
			wholeForm.add("docCreator", "{\"LoginName\":\"admin\"}");
			wholeForm.add("docStatus", ekpProperties.getDocStatus());
			wholeForm.add("fdModelId", ekpProperties.getOrderFdModelId());
			wholeForm.add("fdFlowId", ekpProperties.getOrderFdFlowId());
			wholeForm.add("formValues", formValues);
			log.info("wholeForm:" + wholeForm);
			HttpHeaders headers = new HttpHeaders();
			//如果EKP对该接口启用了Basic认证，那么客户端需要加入
			//addAuth(headers,"yourAccount"+":"+"yourPassword");是VO，则使用APPLICATION_JSON
			headers.setContentType(MediaType.MULTIPART_FORM_DATA);
			//必须设置上传类型，如果入参是字符串，使用MediaType.TEXT_PLAIN；如果
			HttpEntity<MultiValueMap<String,Object>> entity = new HttpEntity<MultiValueMap<String,Object>>(wholeForm,headers);
			//有返回值的情况 VO可以替换成具体的JavaBean
			ResponseEntity<String> obj = yourRestTemplate.exchange(ekpProperties.getUrl(), HttpMethod.POST, entity, String.class);
			String body = obj.getBody();
			if (StringUtils.isBlank(body)){
				log.error(EkpConstants.SEND_FAILED);
				return null;
			}else{
				log.info(EkpConstants.SEND_SUCCESS + body);
				return body;
			}
		}catch (Exception e){
			log.error(e);
			return null;
		}
	}

	/**
	 * 推送订单回复
	 *
	 * @author licancan
	 * @param param
	 * @return {@link String}
	 */
	public String sendReplyToEKP(EkpOrderReplyParam param, MultipartFile[] multipartFiles){
		log.info("推送EKP开始--订单回复信息");
		RestTemplate yourRestTemplate = new RestTemplate();
		List<AttachmentForm> fileList = createAllAttach(multipartFiles);
		try{
			String formValues = new ObjectMapper().writeValueAsString(param);
			//指向EKP的接口url
			//把ModelingAppModelParameterAddForm转换成MultiValueMap
			MultiValueMap<String,Object> wholeForm = new LinkedMultiValueMap<>();
			wholeForm.add("docSubject",ekpProperties.getReplyDocSubject());
			wholeForm.add("docCreator", "{\"LoginName\":\"admin\"}");
			wholeForm.add("docStatus", ekpProperties.getDocStatus());
			wholeForm.add("fdModelId", ekpProperties.getReplyFdModelId());
			wholeForm.add("fdFlowId", ekpProperties.getReplyFdFlowId());
			wholeForm.add("formValues", formValues);
			wholeForm.add("attachmentForms", fileList);

			log.info("wholeForm:" + wholeForm);
			HttpHeaders headers = new HttpHeaders();
			//如果EKP对该接口启用了Basic认证，那么客户端需要加入
			//addAuth(headers,"yourAccount"+":"+"yourPassword");是VO，则使用APPLICATION_JSON
			headers.setContentType(MediaType.MULTIPART_FORM_DATA);
			//必须设置上传类型，如果入参是字符串，使用MediaType.TEXT_PLAIN；如果
			HttpEntity<MultiValueMap<String,Object>> entity = new HttpEntity<MultiValueMap<String,Object>>(wholeForm,headers);
			//有返回值的情况 VO可以替换成具体的JavaBean
			ResponseEntity<String> obj = yourRestTemplate.exchange(ekpProperties.getUrl(), HttpMethod.POST, entity, String.class);
			String body = obj.getBody();
			if (StringUtils.isBlank(body)){
				log.error(EkpConstants.SEND_FAILED);
				return null;
			}else{
				log.info(EkpConstants.SEND_SUCCESS + body);
				return body;
			}
		}catch (Exception e){
			log.error(e);
			return null;
		}finally {
			//将产生的临时附件删除，这里的fileList没值得话是[]，不会是null，如果是null需要做判空处理
			fileList.stream().forEach(e -> {
				FileDataSource dataSource = (FileDataSource)e.getFdAttachment().getDataSource();
				boolean delete = dataSource.getFile().delete();
				log.info("临时附件删除结果：",delete);
			});
		}
	}

	/**
	 * 处理成ekp要的附件格式
	 *
	 * @author licancan
	 * @param multipartFiles
	 * @return {@link List<AttachmentForm>}
	 */
	public List<AttachmentForm> createAllAttach(MultipartFile[] multipartFiles){
		List<AttachmentForm> attForms = new ArrayList<>();
		if (ArrayUtils.isNotEmpty(multipartFiles)){
			try {
				for (MultipartFile multipartFile : multipartFiles) {
					AttachmentForm attForm = new AttachmentForm();
					//设置附件关键字，注意附件列表的key是一样的
					attForm.setFdKey(ekpProperties.getReplyAttachKey());
					attForm.setFdFileName(multipartFile.getOriginalFilename());
					File file = new File(multipartFile.getOriginalFilename());
					FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);
					DataSource dataSource = new FileDataSource(file);
					DataHandler dataHandler = new DataHandler(dataSource);
					attForm.setFdAttachment(dataHandler);
					attForms.add(attForm);
				}
			}catch (Exception e){
				log.error("createAllAttach--->error:",e);
			}
		}
		return attForms;
	}


}
