package com.izouma.nineth.service;

import com.izouma.nineth.config.SysConstants;
import com.izouma.nineth.domain.Invite;
import com.izouma.nineth.domain.User;
import com.izouma.nineth.dto.UserRegister;
import com.izouma.nineth.enums.AuthorityName;
import com.izouma.nineth.enums.LoginType;
import com.izouma.nineth.exception.BusinessException;
import com.izouma.nineth.repo.InviteRepo;
import com.izouma.nineth.repo.UserRepo;
import com.izouma.nineth.security.Authority;
import com.izouma.nineth.service.loginLog.LoginLogService;
import com.izouma.nineth.service.sms.SmsService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Pattern;

/**
 * 注册统一处理
 */
@Service
@Slf4j
@AllArgsConstructor
public class UserRegisterService {
    private UserService userService;
    private UserRepo userRepo;
    private SmsService            smsService;
    private InviteRepo            inviteRepo;
    private SysConfigService sysConfigService;
    private ProjectService projectService;
    private final LoginLogService loginLogService;

    /**
     * 手机号注册
     * @param phone
     * @param code
     * @param password
     * @param inviteCode
     * @param invitor
     * @return
     */
    public User phoneRegister(String phone, String code, String password, String inviteCode, Long invitor) {
        String name = projectService.getUserPrefix() + RandomStringUtils.randomAlphabetic(8);
        Invite invite = null;
        if (StringUtils.isNotBlank(inviteCode)) {
            invite = inviteRepo.findFirstByCode(inviteCode).orElse(null);
        }
        smsService.verify(phone, code);
        User user = userService.create(UserRegister.builder()
                .authorities(Collections.singleton(Authority.get(AuthorityName.ROLE_USER)))
                .username(name)
                .nickname(name)
                .password(password)
                .avatar(sysConfigService.getString(SysConstants.DEFAULT_AVATAR))
                .phone(phone)
                .invitorPhone(Optional.ofNullable(invite).map(Invite::getPhone).orElse(null))
                .invitorName(Optional.ofNullable(invite).map(Invite::getName).orElse(null))
                .inviteCode(Optional.ofNullable(invite).map(Invite::getCode).orElse(null))
                .invitor(invitor)
                .build());
        if (invite != null) {
            inviteRepo.increaseNum(invite.getId());
        }
        //创建nft账户
        userService.createNFTAccount(user.getId());
        loginLogService.pushLoginLog(true, LoginType.REGISTER, phone,user.getId());
        return user;
    }

    /**
     * 验证码登录注册
     * @param phone
     * @param code
     * @return
     */
    public User loginByPhone(String phone, String code) {
        User user = null;
        boolean loginSuccess = true;
        try {
            user = userRepo.findByPhoneAndDelFalse(phone).orElseThrow(new BusinessException("该手机未注册"));
            smsService.verify(phone, code);
            return user;
        }catch (Exception e){
            loginSuccess = false;
            throw e;
        }finally {
            loginLogService.pushLoginLog(loginSuccess, LoginType.SMS, phone, user == null ? null : user.getId());
        }
    }

    /**
     * 创建方式注册
     * @param userRegister
     * @return
     */
    public User registerUser(UserRegister userRegister){
        User user = userService.create(userRegister);
        //创建nft账户
        userService.createNFTAccount(user.getId());
        return user;
    }


    /**
     * 批量注册，多个用户不需要整体事务
     * @param phones
     * @param defaultPassword
     * @return
     */
    public Map<String, Object> batchRegister(String phones, String defaultPassword) {
        List<String> exist = new ArrayList<>();
        List<String> err = new ArrayList<>();
        List<String> success = new ArrayList<>();
        Arrays.stream(phones.replaceAll(",", " ")
                .replaceAll("，", " ")
                .replaceAll("\n", " ")
                .replaceAll("\r\n", " ")
                .split(" ")).forEach(phone -> {

            if (userRepo.findByPhoneAndDelFalse(phone).isPresent()) {
                exist.add(phone);
            } else {
                if (!Pattern.matches("^1[3-9]\\d{9}$", phone)) {
                    err.add(phone);
                } else {
                    try {
                        String name = projectService.getUserPrefix() + RandomStringUtils.randomAlphabetic(8);
                        User user = userService.create(UserRegister.builder()
                                .authorities(Collections.singleton(Authority.get(AuthorityName.ROLE_USER)))
                                .username(name)
                                .nickname(name)
                                .password(defaultPassword)
                                .avatar(sysConfigService.getString(SysConstants.DEFAULT_AVATAR))
                                .phone(phone)
                                .build());
                        //创建nft账户
                        userService.createNFTAccount(user.getId());
                        success.add(phone);
                    } catch (Exception e) {
                        log.error("注册失败", e);
                        err.add(phone);
                    }
                }
            }
        });
        Map<String, Object> map = new HashMap<>();
        map.put("exist", exist);
        map.put("error", err);
        map.put("success", success);
        return map;
    }


}
