package cn.quantgroup.xyqb.service.register.impl;

import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.entity.Address;
import cn.quantgroup.xyqb.entity.Contact;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.event.RegisterEvent;
import cn.quantgroup.xyqb.model.UserRegisterParam;
import cn.quantgroup.xyqb.service.register.IUserRegisterService;
import cn.quantgroup.xyqb.service.user.IUserService;
import cn.quantgroup.xyqb.util.PasswordUtil;
import cn.quantgroup.xyqb.util.TenantUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @author liqing
 * @date 2017/12/4 0004
 */
@Service("userRegisterService")
@Slf4j
    public class UserRegisterServiceImpl implements IUserRegisterService {

    @Resource
    private ApplicationEventPublisher applicationEventPublisher;

    @Resource
    private IUserService userService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public User register(Long registerFrom, String phoneNo) {
        UserRegisterParam userRegisterParam = UserRegisterParam.builder()
                .registerFrom(registerFrom)
                .phoneNo(phoneNo)
                .channelId(registerFrom)
                .sendSuccessSms(true)
                .sendAppSms(true)
                .sendSuccessMq(true)
                .build();
        User user = saveUser(userRegisterParam);
        applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
        return user;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public User register(Long registerFrom, String phoneNo, Integer tenantId) {
        UserRegisterParam userRegisterParam = UserRegisterParam.builder()
                .registerFrom(registerFrom)
                .phoneNo(phoneNo)
                .channelId(registerFrom)
                .sendSuccessSms(true)
                .sendAppSms(true)
                .sendSuccessMq(true)
                .build();
        User user = saveUser(userRegisterParam);
        if (tenantId == null || tenantId.equals(TenantUtil.TENANT_DEFAULT)) {
            applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
        }
        return user;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public User register(Long registerFrom, String phoneNo, String idNo, String name, Long channelId, Long btRegisterChannelId) {
        UserRegisterParam userRegisterParam = UserRegisterParam.builder()
                .registerFrom(registerFrom)
                .phoneNo(phoneNo)
                .idNo(idNo)
                .name(name)
                .channelId(channelId)
                .btRegisterChannelId(btRegisterChannelId)
                .sendSuccessSms(true)
                .sendAppSms(true)
                .sendSuccessMq(true)
                .build();
        User user = saveUser(userRegisterParam);
        applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
        return user;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public User register(Long registerFrom, String phoneNo,  Long channelId, Long btRegisterChannelId) {
        UserRegisterParam userRegisterParam = UserRegisterParam.builder()
                .registerFrom(registerFrom)
                .phoneNo(phoneNo)
                .channelId(channelId)
                .btRegisterChannelId(btRegisterChannelId)
                .sendSuccessSms(true)
                .sendAppSms(true)
                .sendSuccessMq(true)
                .build();
        User user = saveUser(userRegisterParam);
        applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
        return user;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public User register(Long registerFrom, String phoneNo, String idNo, String name, Long channelId, Long btRegisterChannelId, Integer tenantId) {
        UserRegisterParam userRegisterParam = UserRegisterParam.builder()
                .registerFrom(registerFrom)
                .phoneNo(phoneNo)
                .idNo(idNo)
                .name(name)
                .channelId(channelId)
                .btRegisterChannelId(btRegisterChannelId)
                .sendSuccessSms(true)
                .sendAppSms(true)
                .sendSuccessMq(true)
                .build();
        User user = saveUser(userRegisterParam);
        if (tenantId == null || tenantId.equals(TenantUtil.TENANT_DEFAULT)) {
            applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
        }
        return user;
    }

    private User saveUser(UserRegisterParam userRegisterParam) {
        String uuid = UUID.randomUUID().toString();
        User user = new User();
        user.setUuid(uuid);
        user.setEnable(true);
        user.setPhoneNo(userRegisterParam.getPhoneNo());
        Long registerFrom = userRegisterParam.getRegisterFrom();
        if (Objects.isNull(registerFrom)) {
            registerFrom = 1L;
        }
        Long channelId = userRegisterParam.getChannelId();
        if (Objects.equals(channelId, Constants.Channel.BAITIAO)) {
            user.setRegisteredFrom(channelId);
        } else {
            user.setRegisteredFrom(registerFrom);
        }
        String password = StringUtils.defaultString(userRegisterParam.getPassword(), "");
        // 如果需要生成随机密码
        if (userRegisterParam.isGenerateRandomPwd()) {
            password = PasswordUtil.generateRandomPwd(Constants.RANDOM_PWD_LEN);
        }
        if (StringUtils.isNotBlank(password)) {
            user.setPassword(PasswordUtil.MD5WithSalt(password));
        }
        user = userService.saveUser(user);
        userRegisterParam.setUser(user);
        return user;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean register(String phoneNo, String password, Long registerFrom, String ip, Long channelId, Long btRegisterChannelId, String dimension) {
        UserRegisterParam userRegisterParam = UserRegisterParam.builder()
                .registerFrom(registerFrom)
                .phoneNo(phoneNo).password(password)
                .channelId(channelId)
                .btRegisterChannelId(btRegisterChannelId)
                .dimension(dimension)
                .sendSuccessSms(true)
                .sendAppSms(true)
                .sendSuccessMq(true)
                .build();
        User user = saveUser(userRegisterParam);
        applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
        return user != null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public User register(String phoneNo, Long channelId, Long registerFrom, String appChannel, Long btRegisterChannelId, String dimension) {
        UserRegisterParam userRegisterParam = UserRegisterParam.builder()
                .registerFrom(registerFrom)
                .phoneNo(phoneNo)
                .channelId(channelId)
                .btRegisterChannelId(btRegisterChannelId)
                .dimension(dimension)
                .sendSuccessSms(true)
                .sendAppSms(true)
                .sendSuccessMq(true)
                .build();
        User user = saveUser(userRegisterParam);
        applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
        return user;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public User register(String phoneNo, Long channelId, Long registerFrom, String appChannel, Long btRegisterChannelId, String dimension, Integer tenantId) {
        UserRegisterParam userRegisterParam = UserRegisterParam.builder()
                .registerFrom(registerFrom)
                .phoneNo(phoneNo)
                .channelId(channelId)
                .btRegisterChannelId(btRegisterChannelId)
                .dimension(dimension)
                .sendSuccessSms(true)
                .sendAppSms(true)
                .sendSuccessMq(true)
                .build();
        User user = saveUser(userRegisterParam);
        if (tenantId == null || tenantId.equals(TenantUtil.TENANT_DEFAULT)) {
            applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
        }
        return user;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public User register(Long registeredFrom, Long channelId, String phoneNo, String name, String idNo, Address addressObj, String contacts, List<Contact> contactList, Long btRegisterChannelId) {
        UserRegisterParam userRegisterParam = UserRegisterParam.builder()
                .registerFrom(registeredFrom)
                .phoneNo(phoneNo)
                .idNo(idNo)
                .name(name)
                .channelId(channelId)
                .btRegisterChannelId(btRegisterChannelId)
                .address(addressObj)
                .contacts(contacts)
                .contactList(contactList)
                .sendSuccessSms(true)
                .sendAppSms(true)
                .sendSuccessMq(true)
                .build();
        User user = saveUser(userRegisterParam);
        applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
        return user;
    }

}
