package com.cyksj.service.luma.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.util.StringUtil;
import com.cyksj.mapper.*;
import com.cyksj.model.entity.*;
import com.cyksj.model.views.LumaUserInfoView;
import com.cyksj.redis.RedisService;
import com.cyksj.service.luma.LumaService;
import com.cyksj.service.user.UserBindRelationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import javax.imageio.stream.FileImageOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 项目名: yhlxj2
 * 文件名: LumaServiceImpl
 * 创建者: JavaZou
 * 创建时间:2024/8/5 11:55
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class LumaServiceImpl implements LumaService {
	private final GoodsDonMapper goodsDonMapper;

	private final GoodsDonSkuMapper skuMapper;

	private final UserBindRelationService userBindRelationService;

	private final GroupsRelationMapper groupsRelationMapper;

	private final GroupsMapper groupsMapper;

	private final LumaUserMapper lumaUserMapper;

	private final UserMapper userMapper;

	private final RedisService redisService;

	@Override
	public LumaUser getLumaUser(Long userId, Long relationId) {
		GroupsRelation groupsRelation = getGroupsRelation(userId, relationId);
		GroupsTrips groupsTrips = getGroupsTrips(groupsRelation);
		GoodsDonSku goodsDonSku = skuMapper.selectById(groupsTrips.getSkuId());

		if (goodsDonSku != null && goodsDonSku.getGoodsId() == Constant.LUMA_GOODS_ID) {
			return getLumaUser(userId, relationId, groupsRelation, goodsDonSku);
		} else {
			throw BusinessRuntimeException.getInstance("服务器出了点问题");
		}
	}

	@Override
	public LumaUserInfoView getLumaUserInfo(long userId, Long relationId) {
		LumaUser lumaUser = getLumaUser(userId, relationId);

		LumaUserInfoView userInfoView = new LumaUserInfoView();
		userInfoView.setUserToken(lumaUser.getUserToken());
		userInfoView.setRelationId(relationId);
		userInfoView.setExpireTime(lumaUser.getExpireTime());
		userInfoView.setLumaNum(lumaUser.getLumaNum());
		//用户可用次数
		userInfoView.setLumaUserNum(lumaUser.getNum());
		return userInfoView;
	}

	private GroupsRelation getGroupsRelation(Long userId, Long relationId) {
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		GroupsRelation groupsRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class).in(GroupsRelation::getUserId, userIdList).eq(GroupsRelation::getId, relationId));
		if (groupsRelation == null) {
			throw BusinessRuntimeException.getInstance("车票不存在");
		}
		return groupsRelation;
	}

	/**
	 * 获取车队信息
	 *
	 * @param groupsRelation
	 * @return
	 */
	private GroupsTrips getGroupsTrips(GroupsRelation groupsRelation) {
		GroupsTrips groupsTrips = groupsMapper.selectById(groupsRelation.getGroupsId());
		if (groupsTrips == null) {
			throw BusinessRuntimeException.getInstance("车队异常");
		}
		return groupsTrips;
	}

	private LumaUser getLumaUser(Long userId, Long relationId, GroupsRelation groupsRelation, GoodsDonSku goodsDonSku) {
		LumaUser lumaUser = lumaUserMapper.selectOne(Wrappers.lambdaQuery(LumaUser.class).eq(LumaUser::getRelationId, relationId));
		User user = userMapper.selectById(userId);
		if (lumaUser == null) {
			lumaUser = createLumaUser(groupsRelation, user, goodsDonSku);
		} else {
			updateLumaUser(groupsRelation, user, lumaUser);
		}
		lumaUser.setLumaNum(goodsDonSku.getLumaNum());
		return lumaUser;
	}

	private void updateLumaUser(GroupsRelation groupsRelation, User user, LumaUser lumaUser) {
		lumaUser.setName(user.getNickname());
		lumaUser.setImg(getWxImg(user.getHeadimgurl(), user));
		lumaUser.setExpireTime(groupsRelation.getExpiryTime());
		lumaUserMapper.updateById(lumaUser);
		lumaUser.setAqType(groupsRelation.getAqType());
		redisService.set(RedisService.key.LUMA_USER.getName() + lumaUser.getUserToken(), lumaUser, RedisService.key.LUMA_USER.getTimeout());
	}

	private LumaUser createLumaUser(GroupsRelation groupsRelation, User user, GoodsDonSku goodsDonSku) {
		LumaUser lumaUser = new LumaUser();
		lumaUser.setExpireTime(groupsRelation.getExpiryTime());
		lumaUser.setName(user.getNickname());
		lumaUser.setImg(getWxImg(user.getHeadimgurl(), user));
		lumaUser.setRelationId(groupsRelation.getId());
		lumaUser.setUserToken(UUID.randomUUID().toString());
		if (groupsRelation.getAqType() == 2) {
			lumaUser.setNum(goodsDonSku.getLumaNum());
		} else {
			lumaUser.setNum(goodsDonSku.getLumaNum());
		}
		lumaUser.setAqType(groupsRelation.getAqType());
		try {
			lumaUserMapper.insert(lumaUser);
		} catch (DuplicateKeyException e) {
		}
		redisService.set(RedisService.key.LUMA_NUM_LIMIT.getName() + lumaUser.getId(), lumaUser.getNum(), RedisService.key.LUMA_NUM_LIMIT.getTimeout());
		return lumaUser;
	}

	/**
	 * 更换wx头像至oss
	 */
	private String getWxImg(String headimgurl, User user) {
		if (headimgurl.contains("thirdwx.qlogo.cn")) {
			try {
				return uploadPic(headimgurl, "wxheadimg-" + user.getId());
			} catch (Exception ex) {
				log.error("上传微信头像错误！msg:{}", StringUtil.getErrorText(ex));
				return "./avatars.png";
			}
		} else {
			return user.getHeadimgurl();
		}
	}

	private static String uploadPic(String url, String prefix) throws IOException {
		byte[] body = HttpUtil.downloadBytes(url);
		Path tempFile = Files.createTempFile(prefix, ".jpeg");
		try (FileImageOutputStream imageOutput = new FileImageOutputStream(tempFile.toFile())) {
			imageOutput.write(body, 0, body.length);
		}
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("file", tempFile.toFile());
		JSONObject result = JSONUtil.parseObj(HttpUtil.post("https://files.liuliangbang.vip/pic/ups", paramMap));
		FileUtil.del(tempFile);
		return result.getJSONObject("value").getJSONArray("saved").getJSONObject(0).getJSONObject("info").getStr("cdnUrl");
	}
}
