package com.ningdatech.carapi.open.manage;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.cache.model.cache.CacheKey;
import com.ningdatech.cache.repository.CachePlusOps;
import com.ningdatech.carapi.common.constant.UserRoleTypeEnum;
import com.ningdatech.carapi.common.util.CodeUtil;
import com.ningdatech.carapi.common.util.SignUtil;
import com.ningdatech.carapi.open.model.dto.UserLoginDTO;
import com.ningdatech.carapi.sys.contants.UserLoginConstant;
import com.ningdatech.carapi.sys.entity.Company;
import com.ningdatech.carapi.sys.entity.UserRole;
import com.ningdatech.carapi.sys.service.CompanyService;
import com.ningdatech.carapi.sys.service.UserRoleService;
import com.ningdatech.carapi.user.entity.NdUserAuth;
import com.ningdatech.carapi.user.entity.NdUserInfo;
import com.ningdatech.carapi.user.service.INdUserAuthService;
import com.ningdatech.carapi.user.service.INdUserInfoService;
import com.ningdatech.sms.send.GyytzMarketSmsHelper;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author CMM
 * @since 2023/01/06 16:40
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class UserLoginManage {

    private final INdUserInfoService ndUserInfoService;
    private final INdUserAuthService ndUserAuthService;
    private final UserRoleService userRoleService;
    private final CachePlusOps cachePlusOps;
    private final GyytzMarketSmsHelper gyytzMarketSmsHelper;
    private final RestTemplate restTemplate;
    private final CompanyService companyService;
    @Value("${sms.interfaceKey}")
    private String smsKey;

    @Value("${sms.transmitUrl}")
    private String transmitUrl;


    public String getVerificationCode(UserLoginDTO param) {
        // 获取用户名入参信息
        String userName = param.getUsername();
        // 根据用户名获取用户账号信息
        NdUserAuth userAuth = ndUserAuthService.getOne(Wrappers.lambdaQuery(NdUserAuth.class)
                .eq(NdUserAuth::getIdentifier, userName));
        VUtils.isTrue(Objects.isNull(userAuth)).throwMessage("该用户不存在!");
        // 根据用户ID获取用户信息
        NdUserInfo ndUserInfo = ndUserInfoService.getOne(Wrappers.lambdaQuery(NdUserInfo.class)
                .eq(NdUserInfo::getId, userAuth.getUserId()));
        VUtils.isTrue(Objects.isNull(ndUserInfo)).throwMessage("该用户不存在!");
        // 根据用户信息获取用户角色
        Long userId = ndUserInfo.getId();
        Long companyId = ndUserInfo.getCompanyId();
        UserRole userRole = userRoleService.getOne(Wrappers.lambdaQuery(UserRole.class).eq(UserRole::getUserId, userId));
        String mobile = null;
        if (Objects.nonNull(userRole)){
            Long roleId = userRole.getRoleId();
            // 如果是企业用户,优先获取企业联系人电话
            if (UserRoleTypeEnum.COMPANY_INFO_OFFICER_ROLE_ID.getId().equals(roleId)){
                // 获取企业联系人电话
                Company company = companyService.getById(companyId);
                String contactPhone = company.getContactPhone();
                if (Objects.nonNull(contactPhone)) {
                    mobile = contactPhone;
                }else {
                    // 如果没有联系人，则向企业关联的法人手机号发送短信
                    mobile = ndUserInfo.getMobile();
                }
            }else {
                mobile = ndUserInfo.getMobile();
            }
        }
        VUtils.isTrue(StringUtils.isBlank(mobile)).throwMessage("该用户没有设置手机号!");

        // 生成验证码,保存到用户信息表中
        String verificationCode = CodeUtil.codeFen(6);
        ndUserInfo.setVerificationCode(verificationCode);
        ndUserInfoService.updateById(ndUserInfo);

        // 将验证码保存到redis中，并设置过期时间
        CacheKey key = new CacheKey(UserLoginConstant.RedisKey.USER_LOGIN + userName);
        key.setExpire(Duration.ofMinutes(10));
        cachePlusOps.set(key,verificationCode,false);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("mobile", mobile);
        requestBody.put("verificationCode", verificationCode);
        // 生成签名
        String sign = SignUtil.generateSign(requestBody, smsKey);
        requestBody.put("sign",sign);

        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
        try {
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(transmitUrl, requestEntity, String.class);
            return responseEntity.getBody();
        } catch (RestClientException e) {
            throw new BizException("调用短信转发服务失败!");
        }
    }
}
