package org.springblade.gateway.web_gateway.service.impl;

import cn.hutool.http.HttpResponse;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springblade.common.cache.ParamCache;
import org.springblade.common.cache.QrCodeCache;
import org.springblade.common.constant.Salesman;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.gateway.web_gateway.entity.dto.QrCodeDto;
import org.springblade.gateway.web_gateway.entity.dto.QrCodePageJsonDto;
import org.springblade.gateway.web_gateway.entity.vo.QrCodeVo;
import org.springblade.gateway.web_gateway.service.IQrCodeService;
import org.springblade.modules.resource.builder.oss.OssBuilder;
import org.springblade.wx.constant.MiniProgramType;
import org.springblade.wx.service.WeChatService;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import static org.springblade.gateway.web_gateway.entity.dto.QrCodePageJsonDto.SHOP;

/**
 * @author July
 * @version 1.0.0
 * @ClassName IQrCodeServiceImpl.java
 * @Description 二维码服务实现类
 * @createTime 2021年10月12日 16:23:00
 */
@Slf4j
@AllArgsConstructor
@Service
public class IQrCodeServiceImpl implements IQrCodeService {

	private WeChatService weChatService;
	private final OssBuilder ossBuilder;

	@SneakyThrows
	@Override
	public List<QrCodeVo> getCodes(Long userId) {
		ObjectMapper objectMapper = new ObjectMapper();
		String jsonData = QrCodeCache.getQrcode(userId);
		List<QrCodeVo> qrcode = new ArrayList<>();
		if (ObjectUtils.isEmpty(jsonData)) {
			String value = ParamCache.getValue(Salesman.EXTEND_QRCODE_PAGE);
			if (StringUtils.isNotEmpty(value)) {
				List<QrCodePageJsonDto> pages = objectMapper.readValue(value, new TypeReference<List<QrCodePageJsonDto>>() {
				});
				List<QrCodeDto> qrCodeDtoList = new ArrayList<>();
				for (QrCodePageJsonDto page : pages) {
					qrCodeDtoList.add(QrCodeDto.builder()
						.page(page.getPage())
						.pageType(page.getType())
						.queryData(userId.toString())
						.type(MiniProgramType.valueOf(page.getType()))
						.build());
				}
				qrcode = getQrCodeImg(qrCodeDtoList, qrcode);
				QrCodeCache.putQrcode(userId, new ObjectMapper().writeValueAsString(qrcode));
			}
		} else {
			qrcode = objectMapper.readValue(jsonData, new TypeReference<List<QrCodeVo>>() {
			});
		}
		return qrcode;
	}

	/**
	 * 生成二维码
	 */
	private List<QrCodeVo> getQrCodeImg(List<QrCodeDto> qrCodeDtoList, List<QrCodeVo> qrcode) {
		if (qrCodeDtoList != null) {
			for (QrCodeDto qrCodeDto : qrCodeDtoList) {
				HttpResponse code = weChatService.getUnlimitCode(qrCodeDto.getQueryData(), qrCodeDto.getType(), qrCodeDto.getPage());
				if (code.getStatus() != 200) {
					throw new ServiceException("生成二维码错误！");
				}
				BladeFile bladeFile = uploadImage(code.bodyBytes());
				qrcode.add(QrCodeVo.builder()
					.imgLink(bladeFile.getLink())
					.imgName(qrCodeDto.getPageType().equalsIgnoreCase(SHOP) ? "商店" : "代理")
					.build());
			}
		}
		return qrcode;
	}

	/**
	 * 上传图片
	 */
	private BladeFile uploadImage(byte[] bytes) {
		BladeFile bladeFile = new BladeFile();
		try (InputStream inputStream = new ByteArrayInputStream(bytes)) {
			MultipartFile multipartFile = new MockMultipartFile("file", "extendQrCode.jpg", "text/plain", inputStream);
			//上传到对象存储
			bladeFile = ossBuilder.template().putFile(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bladeFile;
	}
}
