/**
 * Copyright (c) 2022 雷掣 All rights reserved.
 *
 * https://www.lc_crm.com
 *
 * 版权所有，侵权必究！
 */

package io.renren.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.dahantc.sms.api.SmsSendClient;
import com.dahantc.sms.api.SmsTemplateClient;
import com.dahantc.sms.entity.param.msg.SmsSendParam;
import com.dahantc.sms.entity.param.template.SmsTemplateData;
import com.dahantc.sms.entity.param.template.SmsTemplateSubmitParam;
import com.dahantc.sms.entity.param.template.SmsTemplateVariable;
import com.dahantc.sms.entity.response.SmsSendResponse;
import com.dahantc.sms.entity.response.template.SmsTemplateSubmitResponse;

import io.renren.common.dao.RdSmsLogDao;
import io.renren.common.entity.RdSmsLogEntity;
import io.renren.common.exception.ErrorCode;
import io.renren.common.exception.RenException;
import io.renren.common.redis.RedisKeys;
import io.renren.common.service.impl.BaseServiceImpl;
import io.renren.common.validator.AssertUtils;
import io.renren.dao.UserDao;
import io.renren.dto.LoginQuickDTO;
import io.renren.entity.AppSysUserEntity;
import io.renren.entity.TokenEntity;
import io.renren.entity.UserEntity;
import io.renren.dto.LoginDTO;
import io.renren.interceptor.ThreadLocalLoginUser;
import io.renren.service.AppSysUserService;
import io.renren.service.TokenService;
import io.renren.service.UserService;
import io.renren.util.CacheUtils;
import io.renren.util.Constant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@Slf4j
public class UserServiceImpl extends BaseServiceImpl<UserDao, UserEntity> implements UserService {
	@Autowired
	private TokenService tokenService;
	@Autowired
	private AppSysUserService appSysUserService;
	@Autowired
	private RdSmsLogDao rdSmsLogDao;
	@Autowired
	private CacheUtils cacheUtils;
	@Value("${aliyun.sms.access_key}")
	private String accessKey;
	@Value("${aliyun.sms.access_secret}")
	private String accessSecret;
	@Value("${aliyun.sms.sign_name}")
	private String signName;
	@Value("${aliyun.sms.template_code}")
	private String templateCode;


	@Override
	public UserEntity getByMobile(String mobile) {
		return baseDao.getUserByMobile(mobile);
	}

	@Override
	public UserEntity getUserByUserId(Long userId) {
		return baseDao.getUserByUserId(userId);
	}

	@Override
	public Map<String, Object> login(LoginDTO dto) {
		AppSysUserEntity userEntity = appSysUserService.selectByUserName(dto.getMobile());
		AssertUtils.isNull(userEntity, ErrorCode.ACCOUNT_PASSWORD_ERROR);

		//密码错误
		if(!userEntity.getPassword().equals(DigestUtils.sha256Hex(dto.getPassword()))){
			throw new RenException(ErrorCode.ACCOUNT_PASSWORD_ERROR);
		}

		//获取登录token
		TokenEntity tokenEntity = tokenService.createToken(userEntity.getId());

		Map<String, Object> map = new HashMap<>(2);
		map.put("token", tokenEntity.getToken());
		map.put("expire", tokenEntity.getExpireDate().getTime() - System.currentTimeMillis());
		map.put("userId", userEntity.getId());
		return map;
	}

	@Override
	public Map<String, Object> loginQuick(LoginQuickDTO dto) {
		AppSysUserEntity userEntity = appSysUserService.selectByUserName(dto.getMobile());

		boolean validateFlag = false;
		//校验手机验证码
		String code = cacheUtils.get(RedisKeys.getVerificationCodeKey(dto.getMobile()))!=null?cacheUtils.get(RedisKeys.getVerificationCodeKey(dto.getMobile())).toString():null;
		if(StringUtils.isNotEmpty(code) && dto.getVerificationCode().equals(code)){
			validateFlag = true;
		}else{
			if(userEntity!=null && userEntity.getSuperUser()!=null
					&& userEntity.getSuperUser()==1 && dto.getVerificationCode().equals(userEntity.getDefaultVerificationCode()) ){
				validateFlag = true;
			}
		}
		if (validateFlag==false){
			throw new RenException("手机验证码错误");
		}
		cacheUtils.remove(RedisKeys.getVerificationCodeKey(dto.getMobile()));
		if (userEntity==null){
			//新增用户
			userEntity = new AppSysUserEntity();
			userEntity.setUsername(dto.getMobile());
			userEntity.setMobile(dto.getMobile());
			userEntity.setCreateDate(new Date());
			userEntity.setCreator(ThreadLocalLoginUser.getUserId());
			appSysUserService.insert(userEntity);
			log.info("mobile={}添加完成",dto.getMobile());
		}



		//获取登录token
		TokenEntity tokenEntity = tokenService.createToken(userEntity.getId());

		Map<String, Object> map = new HashMap<>(2);
		map.put("token", tokenEntity.getToken());
		map.put("userId", userEntity.getId());
		map.put("expire", tokenEntity.getExpireDate().getTime() - System.currentTimeMillis());

		return map;
	}

	@Override
	public Boolean getverificationCode(String mobile) {
		try {
			// 生成验证码并存储到redis中
//			String code = new Random().nextInt(9999)+"";
			String chars = "0123456789";
			char[] rands = new char[4];
			for (int i = 0; i < 4; i++) {
				int rand = (int) (Math.random() * 10);
				rands[i] = chars.charAt(rand);
			}
			String code = String.valueOf(rands);
			HashMap<String, Object> map = new HashMap<>();
			map.put("code", code);
			boolean isSend = send(mobile, signName, templateCode, map);
			if (isSend) {
				cacheUtils.remove(RedisKeys.getVerificationCodeKey(mobile));
				cacheUtils.set(RedisKeys.getVerificationCodeKey(mobile), code, 300L);
				new Thread(new Runnable() {
					@Override
					public void run() {
						RdSmsLogEntity smsLogEntity = new RdSmsLogEntity();
						smsLogEntity.setChannel("1");
						smsLogEntity.setCode(code);
						smsLogEntity.setMobile(mobile);
						smsLogEntity.setCreateTime(new Date());
						smsLogEntity.setUpdateTime(new Date());
						rdSmsLogDao.insert(smsLogEntity);
					}
				}).start();
			}
			return isSend;
		}catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	
    private static SmsTemplateClient client = new SmsTemplateClient(Constant.REMOTE_URL);


	// 大汉三通
	public boolean send(String phoneNum, String signName,String templateCode, Map<String, Object> code) {
		
		
        SmsTemplateSubmitParam param = new SmsTemplateSubmitParam();
        param.setAccount(Constant.ACCOUNT);
        param.setPassword(Constant.PASSWORD);
        param.setPhones(phoneNum);
        SmsTemplateData smsTemplateData = new SmsTemplateData();
        smsTemplateData.setId(Constant.SMS_TEMPLATE);
        LinkedList<SmsTemplateVariable> variables = new LinkedList<>();
        SmsTemplateVariable smsTemplateVariable = new SmsTemplateVariable();
        smsTemplateVariable.setName("1");
        smsTemplateVariable.setValue(code.get("code").toString());
        variables.add(smsTemplateVariable);
        smsTemplateData.setVariables(variables);
        param.setTemplate(smsTemplateData);
        SmsTemplateSubmitResponse response = client.templateSubmit(param);
        String resultStr=response.getResult();
        if (resultStr.equals("0")){
        	return true;
        }
		return false;
	}

//阿里短信	
	public boolean send1(String phoneNum, String signName,String templateCode, Map<String, Object> code) {
		// 连接阿里云
		// 第一个参数一般不动,后面两个参数是我们申请用户组时保存的账户,密码
		DefaultProfile profile = DefaultProfile.getProfile("cn-qingdao", accessKey, accessSecret);
		IAcsClient client = new DefaultAcsClient(profile);
		// 构建请求
		CommonRequest request = new CommonRequest();
		request.setMethod(MethodType.POST);
		request.setDomain("dysmsapi.aliyuncs.com"); // 不要动
		request.setVersion("2017-05-25"); // 不要动
		request.setAction("SendSms");
		// 自定义的参数,手机号,验证码,签名,模板
		request.putQueryParameter("PhoneNumbers", phoneNum);
		request.putQueryParameter("SignName", signName);// 签名一般不变
		request.putQueryParameter("TemplateCode", templateCode);// 对应阿里云短信控制台我们设置的模板名
		request.putQueryParameter("TemplateParam", JSONObject.toJSONString(code));// code验证码
		try {
			CommonResponse response = client.getCommonResponse(request);
			System.out.println(response.getData());
			// 构建成功返回true
			return response.getHttpResponse().isSuccess();
		} catch (ServerException e) {
			e.printStackTrace();
		} catch (ClientException e) {
			e.printStackTrace();
		}
		// 构建失败返回false
		return false;
	}
}