package cn.pluss.platform.merchant.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.jiguang.common.utils.StringUtils;
import cn.pluss.platform.api.PageInfo;
import cn.pluss.platform.deviceStock.DeviceStockService;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.jfShop.JfShopHandler;
import cn.pluss.platform.mapper.*;
import cn.pluss.platform.merchant.*;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.roleUserInfo.RoleUserInfoService;
import cn.pluss.platform.systemConfig.SystemConfigService;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.userInfo.UserInfoService;
import cn.pluss.platform.util.MD5Util;
import cn.pluss.platform.util.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 商户收银点表 服务实现类
 * </p>
 *
 * @author Djh
 * @since 2021-03-23
 */
@Service
public class MerchantCashierCounteServiceImpl implements MerchantCashierCounteService {

    @Setter(onMethod_ = {@Autowired})
    private UserAppService userAppService;

    @Setter(onMethod_ = {@Autowired})
    private MerchantChannelStatusService channelStatusService;

    @Setter(onMethod_ = {@Autowired})
    private MerchantCashPlaceStaffService cashPlaceStaffService;

    @Setter(onMethod_ = {@Autowired})
    private MerchantBaseInfoService merchantBaseInfoService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MerchantCashPayCodeService cashPayCodeService;

    @Setter(onMethod_ = {@Autowired})
    private DeviceStockService deviceStockService;

    @Setter(onMethod_ = {@Autowired})
    private MerchantCashPayCodeMapper merchantCashPayCodeMapper;

    @Setter(onMethod_ = {@Autowired})
    private MerchantCashPlaceStaffMapper merchantCashPlaceStaffMapper;

    @Setter(onMethod_ = {@Autowired})
    private UserAppMapper userAppMapper;
    @Setter(onMethod_ = {@Autowired})
    private SystemConfigService systemConfigService;
    @Setter(onMethod_ = {@Autowired})
    private UserInfoService userInfoService;
    @Setter(onMethod_ = {@Autowired})
    private RoleUserInfoService roleUserInfoService;
    @Resource
    private MerchantBaseInfoMapper merchantBaseInfoMapper;
    @Autowired
    private IdCardMapper idCardMapper;
    @Autowired
    private BankCardMapper bankCardMapper;
    @Autowired
    private UserPromotionMapper userPromotionMapper;

    @Autowired
    private MerchantCashPlaceMapper merchantCashPlaceMapper;
    @Autowired
    private UserCashPlaceMapper userCashPlaceMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Setter(onMethod_ = {@Autowired, @Lazy})
    private JfShopHandler jfShopHandler;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public long addCashierCounte(MerchantCashPlace merchantCashPlace, UserApp userApp1) {

        if (StringUtils.isEmpty(merchantCashPlace.getName())) {
            throw new MsgException("缺少收银台名称");
        }
        QueryWrapper<MerchantCashPlace> query = new QueryWrapper<>();
        query.eq("name", merchantCashPlace.getName());
        long sum = merchantCashPlaceMapper.selectCount(query);
        if (sum > 0) {
            throw new MsgException("该收银点名称已存在");
        }
        UserInfo userInfo1 = userInfoMapper.selectById(userApp1.getUserId());
        if (userInfo1.getLoginName().contains("-")) {
            throw new MsgException("请使用登录账号创建收银点");
        }
        QueryWrapper<UserCashPlace> wrapper = new QueryWrapper<>();
        wrapper.eq("root_account_id", merchantCashPlace.getUserId());
        wrapper.eq("is_root_account", "true");
        List<UserCashPlace> list = userCashPlaceMapper.selectList(wrapper);
        int rootAccountId = userApp1.getUserId().intValue();
        String orgCode = userInfo1.getPhone();
        if (list.size() > 0) {
            UserCashPlace userCashPlace = list.iterator().next();
            rootAccountId = userCashPlace.getRootAccountId();
            UserInfo userInfo = userInfoMapper.selectById(userCashPlace.getRootAccountId());
            orgCode = userInfo.getLoginName();
            QueryWrapper<MerchantCashPlace> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("root_account_id", rootAccountId);
            queryWrapper.eq("pay_passage_id", merchantCashPlace.getPayPassageId());
            long num = merchantCashPlaceMapper.selectCount(queryWrapper);
            if (num > 0) {
                throw new MsgException("该进件通道已存在");
            }
        }
        QueryWrapper<MerchantCashPlace> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("root_account_id", rootAccountId);
        long sydNum = merchantCashPlaceMapper.selectCount(queryWrapper);
        long infoId = merchantCashPlace.getUserId();
        long userId = merchantCashPlace.getUserId();
        String isRoot = "true";
        if (sydNum > 0) {
            UserInfo userInfo = userInfoMapper.selectById(merchantCashPlace.getUserId());
            QueryWrapper<UserCashPlace> userCashPlaceQueryWrapper = new QueryWrapper<>();
            userCashPlaceQueryWrapper.eq("root_account_id", merchantCashPlace.getUserId());
            long sumNum = userCashPlaceMapper.selectCount(userCashPlaceQueryWrapper);
            userInfo.setId(null);
            userInfo.setLoginName(userInfo.getLoginName().concat("-").concat(String.format("%02d", sumNum + 1)));
            userInfo.setCreateTime(new Date());
            userInfo.setPassword(MD5Util.MD5Encode("czg12345678", "utf-8"));
            Long roleId = null;
            // 获取全部的角色信息
            List<SystemConfig> systemConfigs = systemConfigService.querySystemConfigList(new SystemConfig());
            for (SystemConfig systemConfig : systemConfigs) {
                if (systemConfig.getPropertyKey().equalsIgnoreCase("promoter_role_id")) {
                    roleId = Long.parseLong(systemConfig.getPropertyValue());
                }
            }
            if (roleId == null) {
                throw new MsgException("收银点添加失败！");
            }
            userInfo.setCreateTime(new Date());
            userInfoService.saveUserInfo(userInfo);
            // 可能和数据库存储的数据不一致

            RoleUserInfo role = new RoleUserInfo();
            role.setRoleId(roleId);
            role.setUserId(userInfo.getId());
            //如果没有邀请码默认是平台用户
            UserApp userApp = getSaveUserAppInfo(userInfo, merchantCashPlace.getUserId());
            userApp.setInviteNum(getRandomNum());
            userApp.setId(null);
            userApp.setLogo(userApp1.getLogo());
            userApp.setLoginName(userApp1.getLoginName());
            userApp.setUserName(userApp1.getUserName());
            userApp.setBankStatus(userApp1.getBankStatus());
            userApp.setStatus(userApp1.getStatus());
            userApp.setToken(userInfo.getLoginName());
            userApp.setUserId(userInfo.getId());
            //查找代理
            UserPromotion promotion = getUserPromotionByUserId(String.valueOf(244));
            String parenId = promotion.getUserId().toString();
            UserPromotion promotionNew = new UserPromotion();
            promotionNew.setUserId(userInfo.getId());
            promotionNew.setParentUserId(parenId);
            if (userInfo.getTypeCode().equals("FB")) {
                if (promotion.getCurrentFee().compareTo(userInfo.getCurrentFee()) > 0 ||
                        userInfo.getCurrentFee().compareTo(getUserPromotionByUserId("244").getCurrentFee()) < 0) {
                    MsgException.checkNull(null, "错误的费率信息");
                }
            }

            if (userInfo.getTypeCode().equals("SB")) {
                if (promotion.getCurrentFee().compareTo(userInfo.getCurrentFee()) > 0 ||
                        userInfo.getCurrentFee().compareTo(getUserPromotionByUserId("244").getCurrentFee()) < 0) {
                    MsgException.checkNull(null, "错误的费率信息");
                }
            }
            //如果是普通商户默认费率0.38
            if (userInfo.getTypeCode().equals("MC")) {
                promotion.setCurrentFee("0.38");
            }
            promotionNew.setCurrentFee(promotion.getCurrentFee());
            promotionNew.setTypeCode(userInfo.getTypeCode());
            promotionNew.setIsExtend(userInfo.getTypeCode().equals("MC") ? "0" : "1");
            promotionNew.setCreateTime(new Date());
            userPromotionMapper.insert(promotionNew);
            // 获取当前用户的id保存用户的角色信息
            // 保存信息
            userAppService.save(userApp);
            roleUserInfoService.saveRoleUserInfo(role);
            // 删除验证码

            //TODO 同步用户到新版积分商城
            jfShopHandler.syncJfShopUser(userApp, userInfo);
            infoId = userInfo.getId();
            isRoot = "false";
            QueryWrapper<IdCard> cardQueryWrapper = new QueryWrapper<>();
            cardQueryWrapper.eq("userId", userApp1.getUserId());
            List<IdCard> idCardList = idCardMapper.selectList(cardQueryWrapper);
            for (IdCard idCard : idCardList) {
                idCard.setId(null);
                idCard.setUserId(infoId + "");
                idCard.setCreateTime(new Date());
                idCard.setUpdateTime(new Date());
                idCardMapper.insert(idCard);
            }
            QueryWrapper<BankCard> bankCardQueryWrapper = new QueryWrapper<>();
            bankCardQueryWrapper.eq("userId", userApp1.getUserId());
            List<BankCard> cardList = bankCardMapper.selectList(bankCardQueryWrapper);
            for (BankCard idCard : cardList) {
                idCard.setId(null);
                idCard.setUserId(infoId + "");
                idCard.setCreateTime(new Date());
                idCard.setUpdateTime(new Date());
                bankCardMapper.insert(idCard);
            }
        }

        // 查看对应的收银台是否已经存在
        merchantCashPlace.setRootAccountId(userId);
        merchantCashPlace.setUserId(infoId);
        merchantCashPlace.setCreateTime(new Date());
        merchantCashPlace.setCode(getCode());
        merchantCashPlaceMapper.insert(merchantCashPlace);
        if ("true".equals(isRoot)) {
            QueryWrapper<UserCashPlace> placeQueryWrapper = new QueryWrapper<>();
            placeQueryWrapper.eq("is_root_account", "true");
            placeQueryWrapper.eq("user_id", userApp1.getUserId());
            UserCashPlace childUserCashPlace = userCashPlaceMapper.selectOne(placeQueryWrapper);
            if (Objects.isNull(childUserCashPlace)) {
                childUserCashPlace = new UserCashPlace();
                childUserCashPlace.setChasplaceId(merchantCashPlace.getId());
                childUserCashPlace.setCreateTime(new Date());
                childUserCashPlace.setIsRootAccount("true");
                childUserCashPlace.setOrgCode(orgCode);
                childUserCashPlace.setRootAccountId(rootAccountId);
                childUserCashPlace.setUserId(infoId);
                userCashPlaceMapper.insert(childUserCashPlace);
            } else {
                childUserCashPlace.setChasplaceId(merchantCashPlace.getId());
                childUserCashPlace.setUpdateTime(new Date());
                userCashPlaceMapper.updateById(childUserCashPlace);
            }
        } else {
            UserCashPlace childUserCashPlace = new UserCashPlace();
            childUserCashPlace.setChasplaceId(merchantCashPlace.getId());
            childUserCashPlace.setCreateTime(new Date());
            childUserCashPlace.setIsRootAccount("false");
            childUserCashPlace.setOrgCode(orgCode);
            childUserCashPlace.setRootAccountId(rootAccountId);
            childUserCashPlace.setUserId(infoId);
            userCashPlaceMapper.insert(childUserCashPlace);
        }

        return infoId;
    }

    public static void main(String[] args) {
        System.out.println(MD5Util.MD5Encode("1234qwer", "utf-8"));
    }

    @Override
    public PageInfo selectList(Integer current, Integer size, Long userId, String name) {
        QueryWrapper<UserCashPlace> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        UserCashPlace userCashPlace = userCashPlaceMapper.selectOne(queryWrapper);
        if (Objects.nonNull(userCashPlace)) {
            QueryWrapper<UserCashPlace> wrapper = new QueryWrapper<>();
            wrapper.select("user_id");
            wrapper.eq("root_account_id", userCashPlace.getRootAccountId());
            List<Object> list = userCashPlaceMapper.selectObjs(wrapper);
            QueryWrapper<MerchantCashPlace> placeQueryWrapper = new QueryWrapper<>();
            placeQueryWrapper.in("userId", list);
            if (StringUtils.isNotEmpty(name)){
                placeQueryWrapper.like("name",name);
            }
            placeQueryWrapper.orderByAsc("id");
//            List<MerchantCashPlace> placeList = merchantCashPlaceMapper.selectList(placeQueryWrapper);
            IPage<MerchantCashPlace> iPage = merchantCashPlaceMapper.selectPage(new Page<>(current, size), placeQueryWrapper);

//            if (iPage.getRecords().size() < 1) {
//                return  new PageInfo<MerchantCashPlace>(current, 0,0,
//                        size, iPage.getRecords());;
//            } else {
            for (MerchantCashPlace merchantCashPlace : iPage.getRecords()) {
                if (userId.intValue() == merchantCashPlace.getUserId().intValue()) {
                    merchantCashPlace.setTab(1);
                } else {
                    merchantCashPlace.setTab(0);
                }
            }
            PageInfo<MerchantCashPlace> pager = new PageInfo<MerchantCashPlace>(iPage.getCurrent(), iPage.getTotal(), iPage.getPages(),
                    iPage.getSize(), iPage.getRecords());
            return pager;
//            }
        }
        return new PageInfo<MerchantCashPlace>(current.longValue(), 0L, 0L,
                size.longValue(), new ArrayList<>());

    }

    @Override
    public Map<String, Object> cutCashier(long fromChannel, long toChannel) {
        MerchantCashPlace fromCash = merchantCashPlaceMapper.selectById(fromChannel);
        MerchantCashPlace toCash = merchantCashPlaceMapper.selectById(toChannel);
        QueryWrapper<UserCashPlace> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", fromCash.getUserId());
        UserCashPlace userCashPlace = userCashPlaceMapper.selectOne(queryWrapper);
        if (Objects.isNull(userCashPlace)) {
            throw new MsgException("收银点切换失败");
        }
        QueryWrapper<UserCashPlace> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", toCash.getUserId());
        wrapper.eq("root_account_id", userCashPlace.getRootAccountId());
        long sum = userCashPlaceMapper.selectCount(wrapper);
        if (sum < 1) {
            throw new MsgException("切换收银点不匹配");
        }
        Map<String, Object> resultMap = new HashMap<>();
        UserInfo checkUserInfo = userInfoMapper.selectById(toCash.getUserId());

        MsgException.checkNull(checkUserInfo, "切换失败！");

        // 原则上不能以原密码进行对比，这里只是给后台登录页面一个方便
        UserApp queryUserApp;
        queryUserApp = userAppMapper.selectUserApp(new QueryWrapper<>().eq("ua.userId", checkUserInfo.getId()));
        String genRandomNum = StringUtil.genRandomNum(6) + StringUtil.getBillno() + StringUtil.genRandomNum(6);
        UserApp uApp = new UserApp();
        uApp.setToken(genRandomNum);
        uApp.setId(queryUserApp.getId());
        userAppMapper.updateById(uApp);
        queryUserApp.setToken(genRandomNum);
        resultMap.put("userInfo", checkUserInfo);
        Long userId = checkUserInfo.getId();
        MerchantBaseInfo merchantBaseInfo = new MerchantBaseInfo();
        merchantBaseInfo.setUserId(userId + "");
        List<MerchantBaseInfo> queryMerchantBaseInfoList = merchantBaseInfoService.queryMerchantBaseInfoList(merchantBaseInfo);
        if (null != queryMerchantBaseInfoList && !queryMerchantBaseInfoList.isEmpty()) {
            merchantBaseInfo = queryMerchantBaseInfoList.get(0);
            queryUserApp.setMercId(merchantBaseInfo.getId());
            queryUserApp.setMerchantType(merchantBaseInfo.getMerchantType());
            queryUserApp.setMerchantName(merchantBaseInfo.getAlias());
            queryUserApp.setAlias(merchantBaseInfo.getAlias());
        }
        resultMap.put("userApp", queryUserApp);
        return resultMap;
    }

    private UserPromotion getUserPromotionByUserId(String userId) {
        UserPromotion userPromotion = new UserPromotion();
        userPromotion.setUserId(Long.valueOf(userId));
        UserPromotion promotion = userPromotionMapper.selectOne(new QueryWrapper<>(userPromotion));

        if (ObjectUtil.isNotEmpty(promotion)) {
            if ("MG".equals(promotion.getTypeCode()) || "FB".equals(promotion.getTypeCode()) ||
                    "SB".equals(promotion.getTypeCode()) || "1".equals(promotion.getIsExtend()) ||
                    "2".equals(promotion.getIsExtend()) || "AG".equals(promotion.getTypeCode())) {
                return promotion;
            }
        }
        getUserPromotionByUserId(promotion.getParentUserId());
        return promotion;
    }

    protected UserApp getSaveUserAppInfo(UserInfo userInfo, Long userId) {

        // 保存用户信息到userApp表
        UserApp userApp = new UserApp();
        userApp.setUserId(userInfo.getId());
        // 默认一级推广员
        userApp.setLevel(1);
        userApp.setCreateDt(new Date());
        userApp.setStatus(0);
        userApp.setUserType("promoter");

        userApp.setInviteNum(getRandomNum());

        QueryWrapper<UserApp> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", userId);
        UserApp parentUserApp = userAppMapper.selectOne(queryWrapper);
        if (Objects.nonNull(parentUserApp)) {
            userApp.setParentId(parentUserApp.getParentId());
            userApp.setAgentStaffId(parentUserApp.getUserId());
        }

        // 根据邀请码查询确定当前用户的上级关系
        return userApp;
    }

    private String getRandomNum() {
        String inviteNum;
        UserApp condition = new UserApp();

        do {
            inviteNum = StringUtil.genRandomNum(5);
            condition.setInviteNum(inviteNum);
            UserApp userApp = userAppService.queryUserApp(condition);
            if (userApp == null) {
                return inviteNum;
            }
        } while (true);
    }


    public String getCode() {
        String randomDigits = generateRandomDigits(2);
        String randomLetters = generateRandomLetters(6);
        String randomString = randomDigits + randomLetters;
        return randomString;
    }

    // 生成n位随机数字
    private static String generateRandomDigits(int n) {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < n; i++) {
            int digit = random.nextInt(10);
            sb.append(digit);
        }

        return sb.toString();
    }

    private static String generateRandomLetters(int n) {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < n; i++) {
            char letter = (char) (random.nextInt(26) + 'A');
            sb.append(letter);
        }

        return sb.toString();
    }
}
