package com.iformall.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iformall.common.ErrorCode;
import com.iformall.common.IdWorker;
import com.iformall.common.ResultData;
import com.iformall.domain.po.MallPermission;
import com.iformall.domain.po.MallUserInfo;
import com.iformall.domain.po.MallUserRole;
import com.iformall.domain.po.WxMsgValidationcode;
import com.iformall.domain.vo.MallUserInfoVo;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.MallPermissionMapper;
import com.iformall.mapper.MallUserInfoMapper;
import com.iformall.mapper.MallUserRoleMapper;
import com.iformall.mapper.WxMsgValidationcodeMapper;
import com.iformall.service.MallUserInfoService;
import com.iformall.service.WxMallService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MallUserInfoServiceImpl implements MallUserInfoService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    MallUserInfoMapper mallUserInfoMapper;

    @Autowired
    MallUserRoleMapper userRoleMapper;

    @Autowired
    MallPermissionMapper mallPermissionMapper;

    @Autowired
    WxMsgValidationcodeMapper wxMsgValidationcodeMapper;

    @Autowired
    private WxMallService mallService;


    @Override
    public PageInfo<MallUserInfo> listAsPage(MallUserInfo record, Integer pageIndex, Integer pageSize) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> mallUserInfoMapper.findList(record));
    }

    @Override
    public int cntUserList(MallUserInfo record) {
        return mallUserInfoMapper.selectCount(new QueryWrapper(record));
    }

    @Override
    public MallUserInfo getById(Long id) {
        return mallUserInfoMapper.getById(id);
    }

    @Override
    public List<MallUserInfo> getByIds(Collection<? extends Serializable> ids) {
        if(CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>() ;
        }
        return mallUserInfoMapper.selectBatchIds(ids) ;
    }

    @Override
    public List<MallUserInfo> selectList(Wrapper<MallUserInfo> queryWrapper) {
        return mallUserInfoMapper.selectList(queryWrapper) ;
    }

    @Override
    public MallUserInfo getByBOpenId(String openId, String tenantId) {
        return mallUserInfoMapper.selectByBOpenId(openId, tenantId);
    }

    @Override
    public void updateBOpenId(MallUserInfo user) {
        MallUserInfo updateUser = new MallUserInfo();
        updateUser.setId(user.getId());
        updateUser.setBopenId(user.getBopenId());
        mallUserInfoMapper.updateById(user);
    }

    @Override
    public MallUserInfo getByPhone(String phone, String tenantId) {
        return mallUserInfoMapper.selectByPhone(phone, tenantId);
    }

    @Override
    public List<MallUserInfoVo> getUserByPhone(String phone) {
        return mallUserInfoMapper.selectUsersByPhone(phone);
    }

    @Override
    public List<MallUserInfo> getByWebOpenId(String webOpenId) {
        return mallUserInfoMapper.selectByWebOpenId(webOpenId);
    }

    @Override
    public List<MallUserInfoVo> getUsersByWebOpenId(String webOpenId) {
        return mallUserInfoMapper.selectUsersByWebOpenId(webOpenId);
    }

    @Override
    public MallUserInfo getByUsernameWebOpenId(String username, String webOpenId) {
        return mallUserInfoMapper.selectByUserNameWebOpen(username, webOpenId);
    }

    @Override
    public void updateWebOpenId(MallUserInfo user) {
        MallUserInfo updateUser = new MallUserInfo();
        updateUser.setId(user.getId());
        updateUser.setWebOpenId(user.getWebOpenId());
        mallUserInfoMapper.updateById(updateUser);
    }

    @Override
    public void cleanWebOpenId(MallUserInfo user) {
        MallUserInfo updateUser = new MallUserInfo();
        updateUser.setId(user.getId());
        updateUser.setTenantId(user.getTenantId());
        updateUser.setUsername(user.getUsername());
        mallUserInfoMapper.removeWebOpenId(updateUser);
    }


    @Override
    public void cleanAllOpenId(MallUserInfo user) {
        MallUserInfo updateUser = new MallUserInfo();
        updateUser.setId(user.getId());
        updateUser.setTenantId(user.getTenantId());
        updateUser.setUsername(user.getUsername());
        mallUserInfoMapper.removeAllOpenId(updateUser);
    }

    @Override
    public void saveOrUpdate(MallUserInfo record) {
        if (record.getId() == null) {
            //record.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            final IdWorker idWorker = IdWorker.get();
            record.setId(idWorker.nextId());
            mallUserInfoMapper.insert(record);
        } else {
            mallUserInfoMapper.updateById(record);
        }
    }

    @Override
    public void deleteById(Long id) {
        mallUserInfoMapper.deleteById(id);
    }

    @Override
    public MallUserInfo getByUsername(String username) {
        return mallUserInfoMapper.selectByUserName(username);
    }

    @Override
    public int cntByUserName(String username) {
        Map<String, Object> params = new HashMap<>();
        params.put("username", username);
        return mallUserInfoMapper.cntByUserName(params);
    }

    @Override
    public int cntByUserPhone(String phone) {
        Map<String, Object> params = new HashMap<>();
        params.put("phone", phone);
        return mallUserInfoMapper.cntByUserName(params);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(Long id) {
        mallUserInfoMapper.deleteById(id);
        MallUserRole userRole = new MallUserRole();
        userRole.setUid(id);
        userRoleMapper.delete(new UpdateWrapper<>(userRole));
    }

    @Override
    public boolean hasButtonPermission(Long userId, String permission) {
        return mallUserInfoMapper.hasButtonPermission(userId, permission) == null ? false : true;
    }

    @Override
    public boolean cntByUserName(String username, Long id) {
        Map<String, Object> params = new HashMap<>();
        params.put("username", username);
        params.put("id", id);
        return mallUserInfoMapper.cntByUserName(params) > 0 ? true : false;
    }

    @Override
    public boolean cntByUserPhone(String phone, Long id) {
        Map<String, Object> params = new HashMap<>();
        params.put("phone", phone);
        params.put("id", id);
        return mallUserInfoMapper.cntByUserName(params) > 0 ? true : false;
    }

    @Override
    public ResultData updatepwd(MallUserInfo user, String code) {
        if(checkCodeValid(user, code)) {
            try {
                MallUserInfo updateUser = new MallUserInfo();
                updateUser.setId(user.getId());
                updateUser.setTenantId(user.getTenantId());
                updateUser.setPassword(user.getPassword());
                mallUserInfoMapper.updateById(updateUser);
            } catch (Exception e) {
                logger.error("db failed: 用户-" + user.getUsername() + ", e:" + e.getMessage());
                throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
            }
        } else {
            return new ResultData(ErrorCode.MSG_VERIFY_CODE_NOT_FOUND, false);
        }
        return new ResultData();
    }

    @Override
    public boolean checkCodeValid(MallUserInfo user, String code) {
        WxMsgValidationcode wxMsgValidationcode = new WxMsgValidationcode();
        wxMsgValidationcode.setTenantId(user.getTenantId());
        wxMsgValidationcode.setPhone(user.getPhone());
        wxMsgValidationcode.setCode(code);
        List<WxMsgValidationcode> wxmsgvalidationcodelist = wxMsgValidationcodeMapper.findList(wxMsgValidationcode);
        Date currentdate = new Date();
        wxmsgvalidationcodelist = wxmsgvalidationcodelist.stream().filter(validationcode ->
                validationcode.getExpiretime().after(currentdate)).collect(Collectors.toList());
        if (wxmsgvalidationcodelist.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public List<MallUserInfo> findList(MallUserInfo record){
        return mallUserInfoMapper.findList(record);
    }

    @Override
    public Set<String> getUserPermissions(MallUserInfo record) {
        List<String> permsList;
        if(record.isFmSuperAdmin()) {
            // 富茂超管
            MallPermission q = new MallPermission();
            q.setAvailable("Y");
            List<MallPermission> menuList = mallPermissionMapper.selectList(new QueryWrapper(q));

            permsList = new ArrayList<>(menuList.size());
            for(MallPermission menu : menuList){
                permsList.add(menu.getPermission());
            }
        } else {
            permsList = mallUserInfoMapper.queryAllPerms(record.getId());
        }
        //用户权限列表
        Set<String> permsSet = new HashSet<>();
        for(String perms : permsList){
            if(StringUtils.isBlank(perms)){
                continue;
            }
            permsSet.addAll(Arrays.asList(perms.trim().split(",")));
        }
        return permsSet;
    }

}
