package com.fzm.mall.server.front.user.service.impl;

import cn.fzm.chain.simplesdk.client.MainChainClient;
import cn.fzm.chain.simplesdk.client.ParaChainClient;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fzm.mall.server.front.asset.mapper.UserAssetMapper;
import com.fzm.mall.server.front.asset.model.UserAsset;
import com.fzm.mall.server.front.asset.model.UserAssetRecord;
import com.fzm.mall.server.front.asset.service.IUserAssetRecordService;
import com.fzm.mall.server.front.asset.service.IUserAssetService;
import com.fzm.mall.server.front.enums.CoinNameEnum;
import com.fzm.mall.server.front.enums.QueueTypeEnum;
import com.fzm.mall.server.front.mq.MsgProducer;
import com.fzm.mall.server.front.mq.model.MemberUp;
import com.fzm.mall.server.front.system.model.SysConfig;
import com.fzm.mall.server.front.system.service.ISysConfigService;
import com.fzm.mall.server.front.user.model.*;
import com.fzm.mall.server.front.user.mapper.UserMapper;
import com.fzm.mall.server.front.user.service.IOprationPopularizeCommissionService;
import com.fzm.mall.server.front.user.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.mall.server.front.constant.MALLGlobalConfig;
import com.fzm.mall.server.front.util.*;
import io.netty.util.internal.StringUtil;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author fzm
 * @since 2021-01-27
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private ChainUtil chainUtil;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserAssetMapper userAssetMapper;

    @Autowired
    private MsgProducer msgProducer;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private IUserAssetRecordService assetRecordService;

    @Override
    public User getAccount(String account) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", account);
        return getOne(queryWrapper);
    }

    @Override
    @Transactional
    public int register(String account, String registerCode, String area) {
        User user = getAccount(account);
        if (user != null) {
            return 3;
        } else {
            user = new User();
        }
        String uid = UUIdUtil.getUUID();
        user.setUid(uid);
        user.setPhone(account);
        if (!StringUtil.isNullOrEmpty(registerCode)) {
            User byRegisterCode = getByRegisterCode(registerCode);
            if (byRegisterCode == null) {
                return 2;
            }
            user.setRegisterCode(registerCode);
            msgProducer.send(byRegisterCode.getUid(), QueueTypeEnum.REGISTER_REWARD);
            MemberUp memberUp = new MemberUp();
            memberUp.setUid(byRegisterCode.getUid());
            memberUp.setAmount(BigDecimal.ZERO);
            msgProducer.send(JSON.toJSONString(memberUp), QueueTypeEnum.MEMBER_UP);
        }
        String inviteCode = CodeUtil.genInviteCode();
        while (existInviteCode(inviteCode)) {
            inviteCode = CodeUtil.genInviteCode();
        }
        user.setInviteCode(inviteCode);
        String userId = CodeUtil.genOutId();
        while (existUserId(userId)) {
            userId = CodeUtil.genOutId();
        }
        user.setUserId(userId);
        user.setNickName("昵称" + userId);
        //String xlsAddress = mainChainClient.walletCreateAccount(uid+ MALLGlobalConfig.MALL_SUFFIX);
        String xlsAddress = chainUtil.accountCreate(uid + MALLGlobalConfig.MALL_SUFFIX);
        if (StringUtil.isNullOrEmpty(xlsAddress)) {
            throw new RuntimeException("地址创建失败!!!");
        }
        user.setAddress(xlsAddress);
        user.setCreateTime(System.currentTimeMillis());
        user.setUpdateTime(System.currentTimeMillis());
        user.setArea(area);
        user.setLastLogin(System.currentTimeMillis());
        //TODO 资产初始化
        save(user);
        SysConfig register_reward = sysConfigService.getByKey("register_reward");
        UserAsset asset = new UserAsset();
        if (register_reward != null && new BigDecimal(register_reward.getDictValue()).compareTo(BigDecimal.ZERO) == 1) {
            asset.setAmount(new BigDecimal(register_reward.getDictValue()));
            //生成奖励
            UserAssetRecord assetRecord = new UserAssetRecord();
            assetRecord.setUid(uid);
            assetRecord.setFlowId(OrderUtil.getFlowId());
            assetRecord.setStatus(2);
            assetRecord.setCoin(CoinNameEnum.MALLCOIN.value());
            assetRecord.setType(23);
            assetRecord.setAmount(new BigDecimal(register_reward.getDictValue()));
            assetRecordService.save(assetRecord);
        } else {
            asset.setAmount(BigDecimal.ZERO);
        }
        asset.setUid(uid);
        asset.setCoin(CoinNameEnum.MALLCOIN.value());
        asset.setFrozen(BigDecimal.ZERO);
        userAssetMapper.insert(asset);
        return 1;
    }

    @Override
    public User getByToken(String token) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("token", token);
        return getOne(queryWrapper);
    }

    @Override
    public User getByUid(String uid) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", uid);
        return getOne(queryWrapper);
    }

    @Override
    public User getByAddress(String address) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("address", address);
        return getOne(queryWrapper);
    }

    @Override
    public List<Province> getProvinceList() {
        return userMapper.getProvinceList();
    }

    @Override
    public List<City> getCityList(Long code) {
        return userMapper.getCityList(code);
    }

    @Override
    public List<County> getCounty(Long code) {
        return userMapper.getCounty(code);
    }

    @Override
    public List<Street> getStreet(Long code) {
        return userMapper.getStreet(code);
    }

    @Override
    public void setPayPassword(String uid, String sha256String) {
        userMapper.setPayPassword(uid, sha256String);
    }

    @Override
    public Integer getInviteCount(String inviteCode) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("register_code", inviteCode);
        return count(queryWrapper);
    }

    private boolean existInviteCode(String inviteCode) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("invite_code", inviteCode);
        if (count(queryWrapper) != 0) {
            return true;
        }
        return false;
    }

    public User getByRegisterCode(String registerCode) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("invite_code", registerCode);
        return getOne(queryWrapper);
    }

    private boolean existUserId(String userId) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        if (count(queryWrapper) != 0) {
            return true;
        }
        return false;
    }
}
