package cn.meowrain.aioj.backend.userservice.service.impl;

import cn.hutool.crypto.digest.BCrypt;
import cn.meowrain.aioj.backend.framework.core.errorcode.ErrorCode;
import cn.meowrain.aioj.backend.framework.core.exception.ClientException;
import cn.meowrain.aioj.backend.framework.core.exception.ServiceException;
import cn.meowrain.aioj.backend.framework.core.utils.ContextHolderUtils;
import cn.meowrain.aioj.backend.userservice.common.enums.ChainMarkEnums;
import cn.meowrain.aioj.backend.userservice.dao.entity.User;
import cn.meowrain.aioj.backend.userservice.dao.mapper.UserMapper;
import cn.meowrain.aioj.backend.userservice.dto.chains.context.UserRegisterRequestParamVerifyContext;

import cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequestDTO;
import cn.meowrain.aioj.backend.userservice.dto.resp.UserAuthRespDTO;
import cn.meowrain.aioj.backend.userservice.service.EmailService;
import cn.meowrain.aioj.backend.userservice.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

	private final UserRegisterRequestParamVerifyContext userRegisterRequestParamVerifyContext;

	private final EmailService emailService;

	@Override
	public Long userRegister(UserRegisterRequestDTO request) {
		UserAuthRespDTO authInfoByUserAccount = findAuthInfoByUserAccount(request.getUserAccount());
		if (authInfoByUserAccount != null) {
			throw new ClientException("重复创建用户");
		}

		log.info("进行用户注册");
		userRegisterRequestParamVerifyContext.handler(ChainMarkEnums.USER_REGISTER_REQ_PARAM_VERIFY.getMarkName(),
				request);
		// 使用 BCrypt 加密密码
		Date now = new Date();
		String salt = BCrypt.gensalt();
		String encryptPassword = BCrypt.hashpw(request.getUserPassword(), salt);
		User user = new User().setUserAccount(request.getUserAccount())
			.setUserPassword(encryptPassword)
			.setUserRole("user")
			.setCreateTime(now)
			.setUpdateTime(now);
		try {
			// 需要修改表，使得用户名是唯一的
			this.save(user);
		}
		catch (DuplicateKeyException e) {
			log.error("重复创建用户");
			throw new ServiceException("用户名已存在", ErrorCode.SYSTEM_ERROR);
		}

		return user.getId();
	}

	@Override
	public UserAuthRespDTO findAuthInfoByUserAccount(String userAccount) {
		User one = this.lambdaQuery().eq(User::getUserAccount, userAccount).one();
		UserAuthRespDTO userAuthDTO = new UserAuthRespDTO();
		if (one != null) {
			BeanUtils.copyProperties(one, userAuthDTO);
			return userAuthDTO;
		}
		return null;
	}

	@Override
	public UserAuthRespDTO findAuthInfoByUserId(Long userId) {
		User one = this.lambdaQuery().eq(User::getId, userId).one();
		UserAuthRespDTO userAuthDTO = new UserAuthRespDTO();
		if (one != null) {
			BeanUtils.copyProperties(one, userAuthDTO);
			return userAuthDTO;
		}
		return null;

	}

	@Override
	public void sendEmailCode(String email) {
		emailService.sendVerifyCode(email);
	}

	@Override
	public void bindEmail(String email, String code) {
		Long currentUserId = ContextHolderUtils.getCurrentUserId();


	}

	@Override
	public void unbindEmail(Long userId) {
		User one = this.lambdaQuery().eq(User::getId, userId).one();

	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void setProfileAvatar(Long fileId) {
		Long currentUserId = ContextHolderUtils.getCurrentUserId();
		User user = this.lambdaQuery().eq(User::getId, currentUserId).one();
		user.setUserAvatar(fileId);
		user.setUpdateTime(new Date());
		this.updateById(user);
	}

}
