package com.kxs.transfer.api.service.user.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyun.dts.subscribe.clients.record.OperationType;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kxs.common.core.constant.SecurityConstants;
import com.kxs.common.core.constant.enums.ErrorTypeEnum;
import com.kxs.common.core.exception.GlobalCustomerException;
import com.kxs.common.core.util.R;
import com.kxs.product.api.model.KxsMachine;
import com.kxs.store.api.feign.RemoteKxsStoreService;
import com.kxs.store.api.model.KxsWarehouseLimit;
import com.kxs.system.api.feign.RemoteUserMsgService;
import com.kxs.system.api.model.KxsUserMsg;
import com.kxs.system.api.util.MsgTemplateUtil;
import com.kxs.transfer.api.mapper.user.*;
import com.kxs.transfer.api.model.table.DMLData;
import com.kxs.transfer.api.model.table.FieldData;
import com.kxs.transfer.api.service.user.KxsUserService;
import com.kxs.user.api.model.*;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 用户表(KxsSecurityUser)表服务实现类
 *
 * @author 快秃顶的码农
 * @since 2023-12-05 13:50:24
 */
@Service
@RequiredArgsConstructor
public class KxsUserServiceImpl extends ServiceImpl<KxsUserMapper, KxsUser> implements KxsUserService {

    private final KxsUserRealMapper kxsUserRealMapper;

    private final KxsUserBankMapper kxsUserBankMapper;

    private final KxsPartnerMapper kxsPartnerMapper;

    private final KxsUserAmountMapper kxsUserAmountMapper;

    private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeUser(DMLData dmlData) {
        //修改的字段值
        Map<String, Object> fieldDataMap = dmlData.getValidFieldDataMap();
        //修改的字段
        List<String> changeFieldList = dmlData.getChangeFieldList();
        //操作的主键
        String userId = dmlData.getId();

        KxsUser user = new KxsUser();
        UpdateWrapper<KxsUserReal> wrapper = new UpdateWrapper<>();
        LambdaUpdateWrapper<KxsUserReal> lambda = wrapper.lambda().eq(KxsUserReal::getUserId, userId);

        KxsUserReal userReal = new KxsUserReal();
        KxsUserBank userBank = new KxsUserBank();
        //操作类型
        OperationType operation = dmlData.getOperation();
        if (operation.equals(OperationType.DELETE)) {
            // 更新数据
            baseMapper.deleteById(userId);
            //删除用户账户
            kxsUserAmountMapper.delete(Wrappers.<KxsUserAmount>lambdaQuery().eq(KxsUserAmount::getUserId, userId));
            return;
        }
        for (String field : changeFieldList) {

            switch (field) {
                case "RealName":
                    if(fieldDataMap.get(field) != null){
                        user.setUsername(fieldDataMap.get(field).toString());
                        userReal.setRealName(fieldDataMap.get(field).toString());
                    }
                    break;
                case "CertId":
                    if(fieldDataMap.get(field) != null){
                        userReal.setIdCard(fieldDataMap.get(field).toString());
                    }
                    break;
                case "HandCertImage":
                    userReal.setIdCardHand(fieldDataMap.get(field).toString());
                    break;
                case "CertReverseImage":
                    userReal.setIdCardRear(fieldDataMap.get(field).toString());
                    break;
                case "CertFrontImage":
                    userReal.setIdCardFront(fieldDataMap.get(field).toString());
                    break;
                case "SettleBankName":
                    if(fieldDataMap.get(field) != null){
                        userBank.setBankName(fieldDataMap.get(field).toString());
                    }
                    break;
                case "Mobile":
                    user.setPhone(fieldDataMap.get(field).toString());
                    break;
                case "SettleBankCardNo":
                    if(fieldDataMap.get(field) != null){
                        userBank.setBankCode(fieldDataMap.get(field).toString());
                    }
                    break;
                case "BankCardPositiveImage":
                    userBank.setBankPic(fieldDataMap.get(field).toString());
                    break;
                case "SeoTitle":
                    if(fieldDataMap.get(field) != null){
                        userBank.setBankOpen(fieldDataMap.get(field).toString());
                    }
                    break;
                case "SettleBankCardName":
                    userBank.setBankCardName(fieldDataMap.get(field).toString());
                    break;
                case "LoginPwdDisplay":
                    user.setPassword(fieldDataMap.get(field).toString());
                    break;
                case "ReferralUserId":
                    user.setHiddenLevel(Integer.valueOf(fieldDataMap.get(field).toString()));
                    break;
                case "Areas":
                    user.setAddress(fieldDataMap.get(field).toString());
                    break;
                case "ParentUserId":
                    user.setPid(Integer.valueOf(fieldDataMap.get(field).toString()));
                    break;
                case "ParentNav":
                    String pidPath = fieldDataMap.get(field).toString().replaceAll(",,", ",");
                    user.setPidPath("0" + pidPath);
                    break;
                case "MakerCode":
                    user.setUserCode(fieldDataMap.get(field).toString());
                    break;
                case "HeadPhoto":
                    user.setAvatar(fieldDataMap.get(field).toString());
                    break;
                case "UserLevel":
                    user.setUserLevel(Integer.valueOf(fieldDataMap.get(field).toString()));
                    break;
                case "PayPwdDisplay":
                    user.setPayPwd(fieldDataMap.get(field).toString());
                    break;
                case "AuthFlag":
                    user.setRealStatus(Integer.valueOf(fieldDataMap.get(field).toString()));
                    break;
                case "AuthDate":
                    if (fieldDataMap.get(field) != null) {
                        userReal.setCreateTime(LocalDateTimeUtil.parse(fieldDataMap.get(field).toString(), DatePattern.NORM_DATETIME_PATTERN));
                        userBank.setCreateTime(LocalDateTimeUtil.parse(fieldDataMap.get(field).toString(), DatePattern.NORM_DATETIME_PATTERN));
                    }
                    break;
                case "Status":
                    if(Integer.parseInt(fieldDataMap.get(field).toString()) == 0 || Integer.parseInt(fieldDataMap.get(field).toString()) == 1){
                        user.setStatus(1);
                    }else{
                        user.setStatus(0);
                    }
                    break;
                case "MerchantType":
                    user.setIsMerchantMaker(Integer.valueOf(fieldDataMap.get(field).toString()));
                    break;
                case "LockStatus":
                    if(Integer.parseInt(fieldDataMap.get(field).toString()) == 1){
                        user.setStatus(2);
                    }else{
                        user.setStatus(1);
                    }
                    break;
                case "Remark":
                    user.setRemark(fieldDataMap.get(field).toString());
                    break;
                case "MerchantDate":
                    user.setToMerchantMakerTime(LocalDateTimeUtil.parse(fieldDataMap.get(field).toString(), DatePattern.NORM_DATETIME_PATTERN));
                    break;
                case "LogOutDate":
                    if(fieldDataMap.get(field) != null){
                        user.setUpdateTime(LocalDateTimeUtil.parse(fieldDataMap.get(field).toString(), DatePattern.NORM_DATETIME_PATTERN));
                    }
                    break;
                case "CreateDate":
                    user.setCreateTime(LocalDateTimeUtil.parse(fieldDataMap.get(field).toString(), DatePattern.NORM_DATETIME_PATTERN));
                    break;
                case "UserType":
                    //合伙人等级改变
                    int userType = Integer.parseInt(fieldDataMap.get(field).toString());
                    if(userType > 0){
                        KxsPartner kxsPartner = kxsPartnerMapper.selectOne(Wrappers.<KxsPartner>lambdaQuery().eq(KxsPartner::getUserId, userId));
                        if (kxsPartner == null){
                            kxsPartner = new KxsPartner();
                            kxsPartner.setId(Integer.valueOf(userId));
                            kxsPartner.setUserId(Integer.valueOf(userId));
                            if(userType == 1){
                                kxsPartner.setPartnerType(0);
                            }
                            if(userType == 2){
                                kxsPartner.setPartnerType(1);
                            }
                            if(userType == 3){
                                kxsPartner.setPartnerType(2);
                            }
                            if(userType == 4){
                                kxsPartner.setPartnerType(3);
                            }
                            kxsPartner.setPartnerLevel(9);
                            kxsPartnerMapper.insert(kxsPartner);
                        }else{
                            if(userType == 1){
                                kxsPartner.setPartnerType(0);
                            }
                            if(userType == 2){
                                kxsPartner.setPartnerType(1);
                            }
                            if(userType == 3){
                                kxsPartner.setPartnerType(2);
                            }
                            if(userType == 4){
                                kxsPartner.setPartnerType(3);
                            }
                            kxsPartnerMapper.updateById(kxsPartner);
                        }
                    }
                    break;
            }
        }

        if(operation.equals(OperationType.UPDATE)){

            if(BeanUtil.isNotEmpty(userReal, "entityClass")){
                KxsUserReal kxsUserReal = kxsUserRealMapper.selectOne(Wrappers.<KxsUserReal>lambdaQuery().eq(KxsUserReal::getUserId, userId));
                if(kxsUserReal != null){
                    userReal.setId(kxsUserReal.getId());
                    //如果为注销实名状态
                    kxsUserRealMapper.updateById(userReal);
                }else{
                    userReal.setUserId(Integer.valueOf(userId));
                    kxsUserRealMapper.insert(userReal);
                }
            }
            if(BeanUtil.isNotEmpty(userBank, "entityClass")){
                KxsUserBank kxsUserBank = kxsUserBankMapper.selectOne(Wrappers.<KxsUserBank>lambdaQuery().eq(KxsUserBank::getUserId, userId));
                if(kxsUserBank != null){
                    userBank.setId(kxsUserBank.getId());
                    kxsUserBankMapper.updateById(userBank);
                }else{
                    userBank.setUserId(Integer.valueOf(userId));
                    kxsUserBankMapper.insert(userBank);
                }
            }
            if(BeanUtil.isNotEmpty(user, "entityClass")){
                user.setId(Integer.valueOf(userId));
                baseMapper.updateById(user);

                if(user.getRealStatus() != null && user.getRealStatus() == 0){
                    kxsUserRealMapper.delete(Wrappers.<KxsUserReal>lambdaQuery().eq(KxsUserReal::getUserId, userId));
                    kxsUserBankMapper.delete(Wrappers.<KxsUserBank>lambdaQuery().eq(KxsUserBank::getUserId, userId));
                }
            }
        }
        //新增数据必然没有实名信息，所以不做操作
        if(operation.equals(OperationType.INSERT)){
            KxsUser kxsUser = baseMapper.selectById(userId);
            if(kxsUser == null){
                //加盐
                String salt = UUID.randomUUID().toString();
                user.setSalt(salt);
                //登陆密码
                user.setPassword(ENCODER.encode(user.getPassword() + salt));
                user.setId(Integer.valueOf(userId));
                baseMapper.insert(user);
            }

        }

    }

    @Override
    public void changeUserPwd(DMLData dmlData) {

        Map<String, FieldData> fieldDataMap = dmlData.getFieldDataMap();

        FieldData userId = fieldDataMap.get("UserId");
        FieldData loginPwd = fieldDataMap.get("LoginPwd");
        FieldData payPwd = fieldDataMap.get("PayPwd");

        KxsUser user = baseMapper.selectById(userId.getValue().toString());
        if(user != null){
            //加盐
            String salt;
            if(StrUtil.isNotBlank(user.getSalt())){
                salt = user.getSalt();
            }else{
                salt = UUID.randomUUID().toString();
            }
            user.setSalt(salt);
            if(loginPwd.getValue() != null && !ENCODER.matches(loginPwd.getValue() + salt, user.getPassword())){
                //登陆密码
                user.setPassword(ENCODER.encode(loginPwd.getValue() + salt));
            }
            if(payPwd.getValue() != null && !ENCODER.matches(payPwd.getValue() + salt, user.getPayPwd())){
                //支付密码
                user.setPayPwd(ENCODER.encode(payPwd.getValue() + salt));
            }
            baseMapper.updateById(user);
        }


    }


}

