package com.imooc.service.impl;

import com.github.pagehelper.PageHelper;
import com.google.common.collect.Maps;
import com.imooc.base.BaseInfoProperties;
import com.imooc.bo.UpdatedUserBO;
import com.imooc.enums.Sex;
import com.imooc.enums.UserInfoModifyType;
import com.imooc.enums.YesOrNo;
import com.imooc.exceptions.GraceException;
import com.imooc.grace.result.ResponseStatusEnum;
import com.imooc.mapper.FansMapper;
import com.imooc.mapper.FansMapperCustom;
import com.imooc.service.FansService;
import com.imooc.mapper.UserMemberMapper;
import com.imooc.mapper.UsersMapper;
import com.imooc.mo.Token;
import com.imooc.pojo.Fans;
import com.imooc.pojo.UserMember;
import com.imooc.pojo.Users;
import com.imooc.service.UserService;
import com.imooc.utils.*;
import com.imooc.vo.FansVO;
import com.imooc.vo.UsersVO;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.n3r.idworker.Sid;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import tk.mybatis.mapper.entity.Example;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.imooc.base.BaseInfoProperties.REDIS_USER_TOKEN;
import static com.imooc.base.BaseInfoProperties.MOBILE_SMSCODE;

/**
 * @author vercen
 * @version 1.0
 * @date 2023/5/25 21:02
 */
@Slf4j
@Service
public class UserServiceImpl extends BaseInfoProperties implements UserService {
	@Autowired
	private UsersMapper usersMapper;
	@Autowired
	private FansMapperCustom fansMapperCustom;
	@Autowired
	private FansService fansService;

	@Resource
	private PasswordEncoder passwordEncoder;

	@Autowired
	private UserMemberMapper userMemberMapper;

	@Autowired
	private FansMapper fansMapper;

	//@Autowired
	//public RedisOperator redis;
	
	@Resource(name = "redisTemplate")
	private RedisTemplate<String, Object> redisTemplate;

	@Autowired
	private Sid sid;
	private static final String USER_FACE1 = "http://43.143.227.203:29000/bucket/logo.png";

	@Override
	public Users queryMobileIsExist(String mobile) {
		Example userExample = new Example(Users.class);
		Example.Criteria criteria = userExample.createCriteria();
		criteria.andEqualTo("mobile", mobile);
		Users user = usersMapper.selectOneByExample(userExample);
		return user;
	}

	@Override
	public Users createUser(String mobile) {
		// 获得全局唯一主键
		String userId = sid.nextShort();

		Users user = new Users();
		user.setId(userId);
		user.setPassword(mobile);
		user.setMobile(mobile);
		user.setNickname("用户：" + DesensitizationUtil.commonDisplay(mobile));
		user.setImoocNum("用户：" + DesensitizationUtil.commonDisplay(mobile));
		user.setFace(USER_FACE1);

		user.setBirthday(DateUtil.stringToDate("1999-01-01"));
		user.setSex(Sex.secret.type);
		user.setBgImg(USER_FACE1);
		user.setCountry("中国");
		user.setProvince("");
		user.setCity("");
		user.setDistrict("");
		user.setDescription("这家伙很懒，什么都没留下~");
		user.setCanImoocNumBeUpdated(YesOrNo.YES.type);
		user.setCreatedTime(new Date());
		user.setUpdatedTime(new Date());

		usersMapper.insert(user);

		return user;
	}

	@Override
	public Users getUser(String userId) {
		Users users = usersMapper.selectByPrimaryKey(userId);
		return users;
	}


	@Transactional
	@Override
	public Users updateUserInfo(UpdatedUserBO updatedUserBO) {

		Users users = new Users();
		BeanUtils.copyProperties(updatedUserBO, users);
		usersMapper.updateByPrimaryKeySelective(users);
		return getUser(updatedUserBO.getId());
	}

	@Transactional
	@Override
	public Users updateUserInfo(UpdatedUserBO updatedUserBO, Integer type) {
		if (type == UserInfoModifyType.NICKNAME.type) {
			usersMapper.updateNickname(updatedUserBO);
		}
		if (type == UserInfoModifyType.SEX.type) {
			usersMapper.updateSex(updatedUserBO);
		}
		if (type == UserInfoModifyType.BIRTHDAY.type) {
			usersMapper.updateBirthday(updatedUserBO);
		}
		if (type == UserInfoModifyType.LOCATION.type) {
			usersMapper.updateLocation(updatedUserBO);
		}
		if (type == UserInfoModifyType.DESC.type) {
			usersMapper.updateDescription(updatedUserBO);
		}
		if (type == UserInfoModifyType.IMOOCNUM.type) {
			if (updatedUserBO.getCanImoocNumBeUpdated() == YesOrNo.NO.type) {
				GraceException.display(ResponseStatusEnum.USER_INFO_CANT_UPDATED_IMOOCNUM_ERROR);
			}
			// 校验唯一性
			List<UsersVO> haveImooc = usersMapper.selectByImoocNum(updatedUserBO.getImoocNum());
			if (haveImooc != null && !haveImooc.isEmpty()) {
				GraceException.display(ResponseStatusEnum.USER_INFO_UPDATED_IMOOCNUM_EXIST_ERROR);
			}
			usersMapper.updateVnum(updatedUserBO);
		}


		return getUser(updatedUserBO.getId());

//		Example example = new Example(Users.class);
//		Example.Criteria criteria = example.createCriteria();
//		if (type == UserInfoModifyType.NICKNAME.type) {
//			criteria.andEqualTo("nickname", updatedUserBO.getNickname());
//			Users user = usersMapper.selectOneByExample(example);
//			if (user != null) {
//				GraceException.display(ResponseStatusEnum.USER_INFO_UPDATED_NICKNAME_EXIST_ERROR);
//			}
//		}
//
//		if (type == UserInfoModifyType.IMOOCNUM.type) {
//			criteria.andEqualTo("imoocNum", updatedUserBO.getImoocNum());
//			Users user = usersMapper.selectOneByExample(example);
//			if (user != null) {
//				GraceException.display(ResponseStatusEnum.USER_INFO_UPDATED_NICKNAME_EXIST_ERROR);
//			}
//
//			Users tempUser = getUser(updatedUserBO.getId());
//			if (tempUser.getCanImoocNumBeUpdated() == YesOrNo.NO.type) {
//				GraceException.display(ResponseStatusEnum.USER_INFO_CANT_UPDATED_IMOOCNUM_ERROR);
//			}
//
//			updatedUserBO.setCanImoocNumBeUpdated(YesOrNo.NO.type);
//		}
//
//		return updateUserInfo(updatedUserBO);

	}

	@Transactional(rollbackFor = RuntimeException.class)
	@Override
	public Map<String, Object> createUserNew(String mobile) {
		// 获得全局唯一主键
		String userId = sid.nextShort();
		// 创建短视频系统账号
		Users user = new Users();
		user.setId(userId);
		user.setPassword(passwordEncoder.encode(mobile));
		user.setMobile(mobile);
		user.setNickname("用户：" + DesensitizationUtil.commonDisplay(mobile));
		user.setImoocNum("用户：" + DesensitizationUtil.commonDisplay(mobile));
		user.setFace(USER_FACE1);
		user.setBirthday(DateUtil.stringToDate("1999-01-01"));
		user.setSex(Sex.secret.type);
		user.setBgImg(USER_FACE1);
		user.setCountry("中国");
		user.setProvince("");
		user.setCity("");
		user.setDistrict("");
		user.setDescription("这家伙很懒，什么都没留下~");
		user.setBgImg("");
		user.setCanImoocNumBeUpdated(YesOrNo.YES.type);
		user.setCreatedTime(new Date());
		user.setUpdatedTime(new Date());

		int row = usersMapper.insert(user);

		if (row > 0) {
			Map<String, Object> result = Maps.newHashMap();
			result.put("user", user);
			// 创建商城系统账号,获取商城系统token
			String url = "http://localhost:8888/buyer/passport/member/registerFromTik";
			MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
			param.add("userName", mobile);
			param.add("password", mobile);
			param.add("mobilePhone", mobile);
			param.add("userId", user.getId());

			RestTemplateUtil.post(null, null, null, url, param, String.class, t -> {
				if (t.getStatusCode() == HttpStatus.OK) {
					String content = t.getBody();
					if (StringUtils.isNotBlank(content)) {
						Token token = GsonUtil.jsonToBean(content, Token.class);
						result.put("token", token);
					} else {
						throw new RuntimeException("账号注册异常");
					}
				} else {
					throw new RuntimeException("账号注册异常");
				}
			});
			return result;
		}
		return null;
	}

	@Override
	public Token getShopToken(String userId) {
		Token[] tokens = { null };
		String url = "http://localhost:8888/buyer/passport/member/getTokenFromTik";
		MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
		param.add("userId", userId);
		RestTemplateUtil.post(null, null, null, url, param, String.class, t -> {
			if (t.getStatusCode() == HttpStatus.OK) {
				String content = t.getBody();
				if (StringUtils.isNotBlank(content)) {
					tokens[0] = GsonUtil.jsonToBean(content, Token.class);
				} else {
					throw new RuntimeException("账号注册异常");
				}
			} else {
				throw new RuntimeException("账号注册异常");
			}
		});
		return tokens[0];
	}

	@Transactional(rollbackFor = RuntimeException.class)
	@Override
	public Users createUserFromShop(String mobile, String memberId) {
		String tempMobile = StringUtils.isBlank(mobile) ? "unionID" : mobile;
		// 获得全局唯一主键
		String userId = sid.nextShort();
		Users user = new Users();
		user.setId(userId);
		user.setPassword(tempMobile);
		user.setMobile(tempMobile);
		user.setNickname("用户：" + DesensitizationUtil.commonDisplay(tempMobile));
		user.setImoocNum("WZJ" + (System.currentTimeMillis() / 1000) + (int)(Math.random() * 1000));
		user.setFace(USER_FACE1);
		user.setBirthday(DateUtil.stringToDate("1999-01-01"));
		user.setSex(Sex.secret.type);
		user.setBgImg("https://wuzhongjie.com.cn/download/logo.png"); // 测试用地址
		user.setCountry("中国");
		user.setProvince("");
		user.setCity("");
		user.setDistrict("");
		user.setDescription("这家伙很懒，什么都没留下~");
		user.setCanImoocNumBeUpdated(YesOrNo.YES.type);
		user.setCreatedTime(new Date());
		user.setUpdatedTime(new Date());

		// 短视频用户与商城账号关系
		UserMember userMember = new UserMember();
		userMember.setUserId(user.getId());
		userMember.setMemberId(memberId);

		if (usersMapper.insert(user) > 0 && userMemberMapper.insert(userMember) > 0) {
			return user;
		}
		return null;
	}

	@Override
	public String getUserInfoFromShop(String memberId) {
		return Optional.ofNullable(userMemberMapper.getUserByMemberId(memberId))//
				.map(user -> {
					String uToken = UUID.randomUUID().toString();
					//redis.set(REDIS_USER_TOKEN + ":" + user.getId(), uToken);
					redisTemplate.opsForValue().set(REDIS_USER_TOKEN + ":" + user.getId(), uToken);
					// 返回给前端
					UsersVO usersVO = new UsersVO();
					BeanUtils.copyProperties(user, usersVO);
					usersVO.setUserToken(uToken);

					return GsonUtil.beanToJson(usersVO);
				})//
				.orElseGet(() -> StringUtils.EMPTY);
	}

	@Override
	public List<UsersVO> searchByNickname(String nickname, Integer page, Integer pageSize, String currentUserId) {
		try {
			PageHelper.startPage(page, pageSize);
			List<UsersVO> userList = usersMapper.searchByNickname(nickname);

			if(currentUserId.isEmpty()){
				return userList;
			}

			// 提取模糊查询出的用户 ID 列表
			List<String> vlogerIds = userList.stream().map(UsersVO::getId).collect(Collectors.toList());
			log.info("用户列表" + vlogerIds);
			if (vlogerIds.isEmpty()) {
				log.info("没有查询到用户 ID，跳过关注关系查询");
				return userList;
			}
			//
			userList.forEach(usersVO -> {
				// 当前用户是否关注博主
				Boolean isFollowed = fansService.queryDoIFollowVloger(currentUserId,usersVO.getId());
				// 我的粉丝总数
				String myFansCountsStr = redis.get(REDIS_MY_FANS_COUNTS + ":" + usersVO.getId());
				// 获赞总数
				String likedVlogerCountsStr = redis.get(REDIS_VLOGER_BE_LIKED_COUNTS + ":" + usersVO.getId());

				int fansCount = 0;
				int likeCount = 0;
				if (myFansCountsStr != null) {
					try {
						fansCount = Integer.parseInt(myFansCountsStr);
					} catch (NumberFormatException e) {
						// 可选：记录日志或处理异常
						fansCount = 0;
					}
				}
				if (likedVlogerCountsStr != null) {
					try {
						likeCount = Integer.parseInt(likedVlogerCountsStr);
					} catch (NumberFormatException e) {
						// 可选：记录日志或处理异常
						likeCount = 0;
					}
				}

				usersVO.setMyFansCounts(fansCount);
				usersVO.setTotalLikeMeCounts(likeCount);

				if (isFollowed) {
					String relationship = redis.get(REDIS_FANS_AND_VLOGGER_RELATIONSHIP + ":" + usersVO.getId() + ":" + currentUserId);
					if (StringUtils.isNotBlank(relationship) && relationship.equalsIgnoreCase("1")) {
						usersVO.setFollowStatus("互相关注");
					}else {
						usersVO.setFollowStatus("已关注");
					}
				} else {
					usersVO.setFollowStatus("未关注");
				}
			});
			return userList;

//
//
//
//
//			// 获取当前用户关注的
//			List<java.util.Map<String, Object>> followedRelations = fansMapper.getFollowedVlogerIds(currentUserId, vlogerIds);
//			log.info("获取当前用户关注的: {}", followedRelations);
//			// 构建 vlogerId 到 is_fan_friend_of_mine 的映射
//			java.util.Map<String, Integer> relationMap = followedRelations.stream()
//					.filter(Objects::nonNull)  // 排除整个 map 为 null 的情况
//					.collect(Collectors.toMap(
//							map -> (String) map.get("vloger_id"),
//							map -> (Integer) map.get("is_fan_friend_of_mine")
//					));
//			log.info("构造的 relationMap: {}", relationMap);
//			Set<String> followedVlogerIds = relationMap.keySet();
//
//			// 遍历设置每个用户的关注状态及展示状态
//			userList.forEach(usersVO -> {
//				boolean isFollowed = followedVlogerIds.contains(usersVO.getId());
//				usersVO.setIsFollowed(isFollowed);
//				if (isFollowed) {
//					Integer isFanFriendOfMine = relationMap.get(usersVO.getId());
//					if (isFanFriendOfMine != null && isFanFriendOfMine == 1) {
//						usersVO.setFollowStatus("互相关注"); // 假设 UsersVO 有此方法设置展示状态
//					} else {
//						usersVO.setFollowStatus("已关注");
//					}
//				} else {
//					usersVO.setFollowStatus("未关注");
//				}
//			});
//
//			log.info("用户列表" + userList);
//			return userList;
		} catch (Exception e) {
			log.error("搜索用户时发生异常", e);
			throw new RuntimeException("搜索用户时发生异常", e);
		}
	}
}

