package com.yifu.cloud.plus.v1.yifu.order.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.OSSUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.ekp.util.EkpOrderUtil;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpOrderParam;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpOrderReplyParam;
import com.yifu.cloud.plus.v1.yifu.order.constants.OrderConstants;
import com.yifu.cloud.plus.v1.yifu.order.entity.TOrder;
import com.yifu.cloud.plus.v1.yifu.order.entity.TOrderEnclosure;
import com.yifu.cloud.plus.v1.yifu.order.entity.TOrderHandler;
import com.yifu.cloud.plus.v1.yifu.order.entity.TOrderReply;
import com.yifu.cloud.plus.v1.yifu.order.mapper.TOrderMapper;
import com.yifu.cloud.plus.v1.yifu.order.service.TOrderEnclosureService;
import com.yifu.cloud.plus.v1.yifu.order.service.TOrderHandlerService;
import com.yifu.cloud.plus.v1.yifu.order.service.TOrderReplyService;
import com.yifu.cloud.plus.v1.yifu.order.service.TOrderService;
import com.yifu.cloud.plus.v1.yifu.order.util.ValidityUtil;
import com.yifu.cloud.plus.v1.yifu.order.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author licancan
 * @description 针对表【t_order(订单表)】的数据库操作Service实现
 * @date 2022-08-26 17:22:18
 */
@Slf4j
@Service
public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> implements TOrderService {
	@Resource
	private TOrderEnclosureService tOrderEnclosureService;
	@Resource
	private TOrderReplyService tOrderReplyService;
	@Resource
	private TOrderHandlerService tOrderHandlerService;
	@Resource
	private OSSUtil ossUtil;
	@Resource
	private EkpOrderUtil ekpOrderUtil;

	/**
	 * 订单列表分页查询
	 *
	 * @param page
	 * @param param
	 * @return {@link IPage <OrderListVO>}
	 * @author licancan
	 */
	@Override
	public IPage<OrderListVO> getOrderPageList(Page<OrderListParam> page, OrderListParam param) {
		YifuUser user = SecurityUtils.getUser();
		IPage<OrderListVO> orderList = baseMapper.getOrderPageList(page,param,user.getUsername());
		return orderList;
	}

	/**
	 * 订单列表不分页查询
	 *
	 * @param param
	 * @return {@link List<OrderListVO>}
	 * @author licancan
	 */
	@Override
	public R<List<OrderListVO>> getOrderList(OrderListParam param) {
		YifuUser user = SecurityUtils.getUser();
		List<OrderListVO> list;
		if (CollectionUtils.isNotEmpty(param.getIdList())){
			list = baseMapper.getOrderListBySelect(param.getIdList());
		}else {
			list = baseMapper.getOrderList(param,user.getUsername());
		}
		if (CollectionUtils.isNotEmpty(list) && list.size() > CommonConstants.EXPORT_TWENTY_THOUSAND){
			return R.failed(OrderConstants.EXPORT_TOO_LONG);
		}
		return R.ok(list);
	}

	/**
	 * 变更订单状态
	 *
	 * @param id
	 * @param status
	 * @return {@link R <String>}
	 * @author licancan
	 */
	@Override
	public R<String> handleOrder(String id, Integer status) {
		if (StringUtils.isEmpty(id)){
			return R.failed(OrderConstants.ORDER_ID_IS_EMPTY);
		}
		if (CommonConstants.ONE_INT != status && CommonConstants.TWO_INT != status){
			return R.failed(OrderConstants.STATUS_ERROR);
		}
		YifuUser user = SecurityUtils.getUser();
		TOrder byId = this.getById(id);
		if (!Optional.ofNullable(byId).isPresent()){
			return R.failed(OrderConstants.DATA_IS_EMPTY);
		}
		if (CommonConstants.TWO_INT == byId.getOrderStatus()){
			return R.failed(OrderConstants.ORDER_IS_HANDLED);
		}
		byId.setOrderStatus(status);
		byId.setUpdateBy(user.getId());
		byId.setUpdateName(user.getNickname());
		byId.setUpdateTime(LocalDateTime.now());
		this.updateById(byId);
		// 状态同步给ekp
		EkpOrderParam param = new EkpOrderParam();
		param.setFd_3b0b02a93e9cda(byId.getOrderNo());
		param.setFd_3b0b02a34a0134(getOrderStatus(status));
		ekpOrderUtil.sendOrderToEKP(param);
		return R.ok(OrderConstants.OPERATE_SUCCESS);
	}

	/**
	 * 获取订单状态
	 *
	 * @author licancan
	 * @param orderStatus
	 * @return {@link String}
	 */
	private String getOrderStatus(Integer orderStatus){
		String result;
		switch (orderStatus){
			case 0:
				result = "待处理";
				break;
			case 1:
				result = "处理中";
				break;
			case 2:
				result = "已办结";
				break;
			default:
				result = "";
		}
		return result;
	}

	/**
	 * 通过id查询详情
	 *
	 * @param id
	 * @return {@link R<OrderDetailVO>}
	 * @author licancan
	 */
	@Override
	public R<OrderDetailVO> getOrderDetailById(String id) {
		if (StringUtils.isEmpty(id)){
			return R.failed(OrderConstants.ORDER_ID_IS_EMPTY);
		}
		OrderDetailVO orderDetailVO = this.baseMapper.getOrderDetailById(id);
		//处理订单附件
		if (Optional.ofNullable(orderDetailVO).isPresent()){
			List<TOrderEnclosure> list = tOrderEnclosureService.list(Wrappers.<TOrderEnclosure>query().lambda()
					.eq(TOrderEnclosure::getOrderNo, orderDetailVO.getOrderNo())
					.eq(TOrderEnclosure::getEnclosureFlag,CommonConstants.ZERO_INT)
					.eq(TOrderEnclosure::getDeleteFlag,CommonConstants.ZERO_INT)
			);
			if (CollectionUtils.isNotEmpty(list)){
				orderDetailVO.setOrderEnclosure(list);
			}else {
				orderDetailVO.setOrderEnclosure(Lists.newArrayList());
			}
		}
		return R.ok(orderDetailVO);
	}

	/**
	 * 附件预览下载地址
	 *
	 * @param id 附件表id
	 * @return {@link R}
	 * @author licancan
	 */
	@Override
	public R getEnclosureUrl(String id) {
		if(StringUtils.isEmpty(id)){
			return R.failed(OrderConstants.ENCLOSURE_ID_IS_EMPTY);
		}
		TOrderEnclosure orderEnclosure = tOrderEnclosureService.getById(id);
		if (!Optional.ofNullable(orderEnclosure).isPresent()) {
			return R.failed(OrderConstants.DATA_IS_EMPTY);
		}
		String enclosureAddress = orderEnclosure.getEnclosureAddress();
		log.info("key:"+enclosureAddress);
		URL url = ossUtil.getObjectUrl(null, orderEnclosure.getEnclosureAddress());
		return new R<>(url.toString());
	}

	/**
	 * 添加回复
	 *
	 * @author licancan
	 * @param file         附件
	 * @param filePath     附件路径
	 * @param replyContent 回复内容
	 * @param orderNo      订单编号
	 * @return {@link R}
	 * @throws IOException
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public R uploadReplyEnclosure(MultipartFile[] file, String filePath, String replyContent, String orderNo) throws IOException {
		YifuUser user = SecurityUtils.getUser();
		if (Common.isEmpty(orderNo)){
			return R.failed(OrderConstants.ORDER_NO_IS_EMPTY);
		}
		TOrder one = this.getOne(Wrappers.<TOrder>query().lambda()
				.eq(TOrder::getOrderNo, orderNo)
				.eq(TOrder::getDeleteFlag,CommonConstants.ZERO_INT)
				.last(CommonConstants.LAST_ONE_SQL)
		);
		if (!Optional.ofNullable(one).isPresent()){
			return R.failed(OrderConstants.ORDER_NO_NOT_EXIST);
		}else {
			if (CommonConstants.TWO_INT == one.getOrderStatus()){
				return R.failed(OrderConstants.ORDER_STATUS_IS_TWO);
			}
		}
		if (Common.isEmpty(replyContent) && ArrayUtils.isEmpty(file)){
			return R.failed(OrderConstants.REPLY_CONTENT_AND_ENCLOSURE_IS_EMPTY);
		}
		// 校验回复内容200字以内
		if (!Common.isEmpty(replyContent) && !ValidityUtil.validate200(replyContent)){
			return R.failed(OrderConstants.REPLY_CONTENT_MORE_THAN_200);
		}

		if (ArrayUtils.isNotEmpty(file)){
			if (file.length > CommonConstants.TWENTY_INT){
				return R.failed(OrderConstants.ENCLOSURE_SIZE_ERROR);
			}
			for (MultipartFile multipartFile : file) {
				if(!Common.checkInsuranceFile(multipartFile.getOriginalFilename())){
					return R.failed(OrderConstants.ENCLOSURE_TYPE_IS_ERROR);
				}
				if (multipartFile.getSize() > (CommonConstants.FIFTY_INT*CommonConstants.BYTE*CommonConstants.BYTE)){
					return R.failed(OrderConstants.ENCLOSURE_SIZE_ERROR);
				}
			}

		}

		TOrderReply reply = new TOrderReply();
		reply.setOrderNo(orderNo);
		reply.setReplyContent(Common.isEmpty(replyContent)?null:replyContent);
		reply.setCreateName(user.getNickname());
		reply.setCreateTime(LocalDateTime.now());
		reply.setDeleteFlag(CommonConstants.ZERO_INT);
		boolean save = tOrderReplyService.save(reply);
		//同步推送ekp
		EkpOrderReplyParam param = new EkpOrderReplyParam();
		param.setFd_3ac904bbaf972a(orderNo);
		Map<String,Object> map = new HashMap<>();
		map.put("LoginName",user.getUsername());
		param.setFd_3ac904badcaa06(map);
		param.setFd_3ac904b8590598(reply.getCreateTime().toString());
		param.setFd_3ac904c7798e5c(replyContent);
		ekpOrderUtil.sendReplyToEKP(param,file);
		if (save && ArrayUtils.isNotEmpty(file)){
			for (MultipartFile multipartFile : file) {
				String fileName = System.currentTimeMillis() + "_" + multipartFile.getOriginalFilename();
				//filePath不传默认存储空间的根目录
				//支持的附件格式
				String key = "";
				if (!Common.isNotNull(filePath)) {
					key = fileName;
				} else {
					key = filePath + "/" + fileName;
				}
				boolean flag = ossUtil.uploadFileByStream(multipartFile.getInputStream(), key, null);
				if (flag) {
					log.info("文件：" + fileName + "上传至存储空间" + ossUtil.getBucketName() + "成功！");
					TOrderEnclosure orderEnclosure = new TOrderEnclosure();
					orderEnclosure.setOrderNo(reply.getId());
					orderEnclosure.setEnclosureName(multipartFile.getOriginalFilename());
					orderEnclosure.setEnclosureFlag(CommonConstants.ONE_INT);
					orderEnclosure.setEnclosureAddress(key);
					orderEnclosure.setDeleteFlag(CommonConstants.ZERO_INT);
					try {
						tOrderEnclosureService.save(orderEnclosure);
					} catch (Exception e) {
						log.error("回复附件OSS文件上传接口异常：" + e.getMessage());
						ossUtil.deleteObject(null, key);
						return R.failed("failed:" + e.getMessage());
					}
				} else {
					return R.failed(OrderConstants.OPERATE_FAILED);
				}
			}
		}
		return R.ok(OrderConstants.OPERATE_SUCCESS);
	}

	/**
	 * 订单回复列表分页查询
	 *
	 * @param page
	 * @param orderNo
	 * @return {@link IPage<OrderReplyListVO>}
	 * @author licancan
	 */
	@Override
	public IPage<OrderReplyListVO> getOrderReplyPageList(Page<OrderReplyListVO> page, String orderNo) {
		IPage<OrderReplyListVO> orderReplyList = baseMapper.getOrderReplyPageList(page,orderNo);
		if (CollectionUtils.isNotEmpty(orderReplyList.getRecords())){
			orderReplyList.getRecords().stream().forEach(e ->{
				List<TOrderEnclosure> list = tOrderEnclosureService.list(Wrappers.<TOrderEnclosure>query().lambda()
						.eq(TOrderEnclosure::getOrderNo, e.getId())
						.eq(TOrderEnclosure::getEnclosureFlag,CommonConstants.ONE_INT)
						.eq(TOrderEnclosure::getDeleteFlag,CommonConstants.ZERO_INT)
				);
				if (CollectionUtils.isNotEmpty(list)){
					e.setOrderReplyEnclosure(list);
				}else {
					e.setOrderReplyEnclosure(Lists.newArrayList());
				}
			});
		}
		return orderReplyList;
	}

	/**
	 * 接收处理ekp订单
	 *
	 * @author licancan
	 * @param vo
	 * @return {@link R}
	 * @throws IOException
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public R receiveOrder(OrderAddVO vo) throws IOException{
		if (Common.isEmpty(vo.getOrderNo())){
			return R.failed(OrderConstants.ORDER_NO_IS_EMPTY);
		}
		TOrder one = this.getOne(Wrappers.<TOrder>query().lambda()
				.eq(TOrder::getOrderNo, vo.getOrderNo())
				.eq(TOrder::getDeleteFlag,CommonConstants.ZERO_INT)
				.last(CommonConstants.LAST_ONE_SQL)
		);
		if (Optional.ofNullable(one).isPresent()){
			return R.failed(OrderConstants.ORDER_NO_IS_EXIST);
		}
		if (Common.isEmpty(vo.getCreateName())){
			return R.failed(OrderConstants.ORDER_NAME_IS_EMPTY);
		}
		if (Common.isEmpty(vo.getCreateTime())){
			return R.failed(OrderConstants.ORDER_TIME_IS_EMPTY);
		}
		if (Common.isEmpty(vo.getDeptNo())){
			return R.failed(OrderConstants.DEPT_NO_IS_EMPTY);
		}
		if (Common.isEmpty(vo.getDeptName())){
			return R.failed(OrderConstants.DEPT_NAME_IS_EMPTY);
		}
		if (Common.isEmpty(vo.getCustomerName())){
			return R.failed(OrderConstants.CUSTOMER_NAME_IS_EMPTY);
		}
		if (Common.isEmpty(vo.getOrderStatus())){
			return R.failed(OrderConstants.ORDER_STATUS_IS_EMPTY);
		}
		if (Common.isEmpty(vo.getOrderContent())){
			return R.failed(OrderConstants.ORDER_CONTENT_IS_EMPTY);
		}
		if (!Common.isEmpty(vo.getOrderContent()) && !ValidityUtil.validate200(vo.getOrderContent())){
			return R.failed(OrderConstants.ORDER_CONTENT_MORE_THAN_200);
		}
		if (CollectionUtils.isEmpty(vo.getHandleUserList())){
			return R.failed(OrderConstants.HANDLE_USER_IS_EMPTY);
		}
		TOrder order = new TOrder();
		BeanUtils.copyProperties(vo,order);
		boolean save = this.save(order);
		//处理指派人
		if (save && CollectionUtils.isNotEmpty(vo.getHandleUserList())){
			List<TOrderHandler> list = new ArrayList<>();
			vo.getHandleUserList().stream().forEach(e ->{
				TOrderHandler handler = new TOrderHandler();
				handler.setOrderNo(vo.getOrderNo());
				handler.setHandleUser(e);
				list.add(handler);
			});
			tOrderHandlerService.saveBatch(list);
		}
		if (save && ArrayUtils.isNotEmpty(vo.getFile())){
			for (MultipartFile multipartFile : vo.getFile()) {
				String fileName = System.currentTimeMillis() + "_" + multipartFile.getOriginalFilename();
				//filePath不传默认存储空间的根目录
				//支持的附件格式
				String key = fileName;
				boolean flag = ossUtil.uploadFileByStream(multipartFile.getInputStream(), key, null);
				if (flag) {
					log.info("文件：" + fileName + "上传至存储空间" + ossUtil.getBucketName() + "成功！");
					TOrderEnclosure orderEnclosure = new TOrderEnclosure();
					orderEnclosure.setOrderNo(order.getOrderNo());
					orderEnclosure.setEnclosureName(multipartFile.getOriginalFilename());
					orderEnclosure.setEnclosureFlag(CommonConstants.ZERO_INT);
					orderEnclosure.setEnclosureAddress(key);
					orderEnclosure.setDeleteFlag(CommonConstants.ZERO_INT);
					try {
						tOrderEnclosureService.save(orderEnclosure);
					} catch (Exception e) {
						log.error("订单接收OSS文件上传接口异常：" + e.getMessage());
						ossUtil.deleteObject(null, key);
						return R.failed("failed:" + e.getMessage());
					}
				} else {
					return R.failed(OrderConstants.OPERATE_FAILED);
				}
			}
		}
		return R.ok(OrderConstants.OPERATE_SUCCESS);
	}

	/**
	 * 接收处理ekp订单回复
	 *
	 * @author licancan
	 * @param vo
	 * @return {@link R}
	 * @throws IOException
	 */
	@Override
	public R receiveOrderReply(OrderReplyAddVO vo) throws IOException{
		if (Common.isEmpty(vo.getOrderNo())){
			return R.failed(OrderConstants.ORDER_NO_IS_EMPTY);
		}
		TOrder one = this.getOne(Wrappers.<TOrder>query().lambda()
				.eq(TOrder::getOrderNo, vo.getOrderNo())
				.eq(TOrder::getDeleteFlag,CommonConstants.ZERO_INT)
				.last(CommonConstants.LAST_ONE_SQL)
		);
		if (!Optional.ofNullable(one).isPresent()){
			return R.failed(OrderConstants.ORDER_NO_NOT_EXIST);
		}else {
			if (CommonConstants.TWO_INT == one.getOrderStatus()){
				return R.failed(OrderConstants.ORDER_STATUS_IS_TWO);
			}
		}
		if (Common.isEmpty(vo.getCreateName())){
			return R.failed(OrderConstants.REPLY_NAME_IS_EMPTY);
		}
		if (Common.isEmpty(vo.getCreateTime())){
			return R.failed(OrderConstants.REPLY_TIME_IS_EMPTY);
		}
		if (Common.isEmpty(vo.getReplyContent()) && ArrayUtils.isEmpty(vo.getFile())){
			return R.failed(OrderConstants.REPLY_CONTENT_AND_ENCLOSURE_IS_EMPTY);
		}
		// 校验回复内容200字以内
		if (!Common.isEmpty(vo.getReplyContent()) && !ValidityUtil.validate200(vo.getReplyContent())){
			return R.failed(OrderConstants.REPLY_CONTENT_MORE_THAN_200);
		}

		if (ArrayUtils.isNotEmpty(vo.getFile())){
			if (vo.getFile().length > CommonConstants.TWENTY_INT){
				return R.failed(OrderConstants.ENCLOSURE_SIZE_ERROR);
			}
			for (MultipartFile multipartFile : vo.getFile()) {
				if(!Common.checkInsuranceFile(multipartFile.getOriginalFilename())){
					return R.failed(OrderConstants.ENCLOSURE_TYPE_IS_ERROR);
				}
				if (multipartFile.getSize() > (CommonConstants.FIFTY_INT*CommonConstants.BYTE*CommonConstants.BYTE)){
					return R.failed(OrderConstants.ENCLOSURE_SIZE_ERROR);
				}
			}

		}
		TOrderReply reply = new TOrderReply();
		BeanUtils.copyProperties(vo,reply);
		reply.setReplyContent(Common.isEmpty(vo.getReplyContent())?null:vo.getReplyContent());
		reply.setDeleteFlag(CommonConstants.ZERO_INT);
		boolean save = tOrderReplyService.save(reply);
		if (save && ArrayUtils.isNotEmpty(vo.getFile())){
			for (MultipartFile multipartFile : vo.getFile()) {
				String fileName = System.currentTimeMillis() + "_" + multipartFile.getOriginalFilename();
				//filePath不传默认存储空间的根目录
				//支持的附件格式
				String key = fileName;
				boolean flag = ossUtil.uploadFileByStream(multipartFile.getInputStream(), key, null);
				if (flag) {
					log.info("文件：" + fileName + "上传至存储空间" + ossUtil.getBucketName() + "成功！");
					TOrderEnclosure orderEnclosure = new TOrderEnclosure();
					orderEnclosure.setOrderNo(reply.getId());
					orderEnclosure.setEnclosureName(multipartFile.getOriginalFilename());
					orderEnclosure.setEnclosureFlag(CommonConstants.ONE_INT);
					orderEnclosure.setEnclosureAddress(key);
					orderEnclosure.setDeleteFlag(CommonConstants.ZERO_INT);
					try {
						tOrderEnclosureService.save(orderEnclosure);
					} catch (Exception e) {
						log.error("订单回复接收OSS文件上传接口异常：" + e.getMessage());
						ossUtil.deleteObject(null, key);
						return R.failed("failed:" + e.getMessage());
					}
				} else {
					return R.failed(OrderConstants.OPERATE_FAILED);
				}
			}
		}
		return R.ok(OrderConstants.OPERATE_SUCCESS);
	}

}
