package com.kmall.admin.fromcomm.service.impl;

import com.google.common.collect.ImmutableBiMap;
import com.kmall.admin.dao.ExportExceptionDataDao;
import com.kmall.admin.dao.MerchDao;
import com.kmall.admin.dao.StoreDao;
import com.kmall.admin.dao.ThirdMerchantBizDao;
import com.kmall.admin.dto.SysUserDto;
import com.kmall.admin.entity.ExportExceptionDataEntity;
import com.kmall.admin.entity.MerchEntity;
import com.kmall.admin.entity.StoreEntity;
import com.kmall.admin.entity.ThirdMerchantBizEntity;
import com.kmall.admin.fromcomm.entity.SysRoleEntity;
import com.kmall.admin.utils.ShiroUtils;
import com.kmall.common.Global;
import com.kmall.admin.fromcomm.dao.SysUserDao;
import com.kmall.admin.fromcomm.entity.SysUserEntity;
import com.kmall.admin.fromcomm.service.SysRoleService;
import com.kmall.admin.fromcomm.service.SysUserRoleService;
import com.kmall.admin.fromcomm.service.SysUserService;
import com.kmall.common.constant.Dict;
import com.kmall.common.utils.*;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


/**
 * 系统用户
 *
 * @author Scott
 * @email
 * @date 2016年12月18日 上午9:46:09
 */
@Service("sysUserService")
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private StoreDao storeDao;
    @Autowired
    private MerchDao merchDao;
    @Autowired
    private ThirdMerchantBizDao thirdMerchantBizDao;
    @Autowired
    private ExportExceptionDataDao exportExceptionDataDao;

    @Override
    public List<String> queryAllPerms(Long userId) {
        return sysUserDao.queryAllPerms(userId);
    }

    @Override
    public List<Long> queryAllMenuId(Long userId) {
        return sysUserDao.queryAllMenuId(userId);
    }

    @Override
    public SysUserEntity queryByUserName(String username) {
        return sysUserDao.queryByUserName(username);
    }

    @Override
    public SysUserEntity queryObject(Long userId) {
        return sysUserDao.queryObject(userId);
    }

    @Override
    public List<SysUserEntity> queryList(Map<String, Object> map) {
        return sysUserDao.queryList(map);
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        return sysUserDao.queryTotal(map);
    }

    @Override
    @Transactional
    public void save(SysUserEntity user) {
        Map<String, Object> valideDate = MapBeanUtil.fromObject(user);
        ImmutableBiMap.Builder builder = new ImmutableBiMap.Builder();
        builder.put("username", "用户名");
        builder.put("email", "邮箱");
        builder.put("mobile", "手机号");
        builder.put("roleType", "数据角色类型");
        builder.put("status", "状态");
        builder.put("roleId", "角色");

        R r = ValidatorUtil.isEmpty(builder.build(), valideDate);
        if (Integer.valueOf(r.get("code").toString()) != 0) {
            throw new RRException(r.get("msg").toString());
        } else {
            if (Dict.roleType.item_2.getItem().equalsIgnoreCase(user.getRoleType())) {
                builder.put("merchSn", "商户");
                builder.put("thirdPartyMerchCode", "第三方商户");
                builder.put("storeId", "门店");
            }else if (Dict.roleType.item_3.getItem().equalsIgnoreCase(user.getRoleType())) {
                builder.put("merchSn", "商户");
            }else if (Dict.roleType.item_4.getItem().equalsIgnoreCase(user.getRoleType())) {
                builder.put("merchSn", "商户");
                builder.put("thirdPartyMerchCode", "第三方商户");
            }else if (Dict.roleType.item_1.getItem().equalsIgnoreCase(user.getRoleType())) {
                user.setMerchSn(null);
                user.setThirdPartyMerchCode(null);
                user.setStoreId(null);
            }
            r = ValidatorUtil.isEmpty(builder.build(), valideDate);
            if (Integer.valueOf(r.get("code").toString()) != 0) {
                throw new RRException(r.get("msg").toString());
            }
        }

        if (!user.getEmail().matches("^[a-z0-9A-Z]+[- | a-z0-9A-Z . _]+@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-z]{2,}$")) {
            throw new RRException("邮箱格式错误！");
        }
        if (!PhoneFormatCheckUtils.isPhoneLegal(user.getMobile())) {
            throw new RRException("手机号格式错误！");
        }

        user.setCreateTime(new Date());
        //sha256加密
        user.setPassword(new Sha256Hash(Global.DEFAULT_PASS_WORD).toHex());
        sysUserDao.save(user);

        //检查角色是否越权
        checkRole(user);

        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleId());
    }

    @Override
    @Transactional
    public void update(SysUserEntity user) {
        Map<String, Object> valideDate = MapBeanUtil.fromObject(user);
        ImmutableBiMap.Builder builder = new ImmutableBiMap.Builder();
        builder.put("username", "用户名");
        builder.put("email", "邮箱");
        builder.put("mobile", "手机号");
        builder.put("roleType", "数据角色类型");
        builder.put("status", "状态");
        builder.put("roleId", "角色");

        R r = ValidatorUtil.isEmpty(builder.build(), valideDate);
        if (Integer.valueOf(r.get("code").toString()) != 0) {
            throw new RRException(r.get("msg").toString());
        } else {
            if (Dict.roleType.item_2.getItem().equalsIgnoreCase(user.getRoleType())) {
                builder.put("merchSn", "商户");
                builder.put("thirdPartyMerchCode", "第三方商户");
                builder.put("storeId", "门店");
            }else if (Dict.roleType.item_3.getItem().equalsIgnoreCase(user.getRoleType())) {
                builder.put("merchSn", "商户");
            }else if (Dict.roleType.item_4.getItem().equalsIgnoreCase(user.getRoleType())) {
                builder.put("merchSn", "商户");
                builder.put("thirdPartyMerchCode", "第三方商户");
            }else if (Dict.roleType.item_1.getItem().equalsIgnoreCase(user.getRoleType())) {
                user.setMerchSn(null);
                user.setStoreId(null);
                user.setThirdPartyMerchCode(null);
            }
            r = ValidatorUtil.isEmpty(builder.build(), valideDate);
            if (Integer.valueOf(r.get("code").toString()) != 0) {
                throw new RRException(r.get("msg").toString());
            }
        }

        if (!user.getEmail().matches("^[a-z0-9A-Z]+[- | a-z0-9A-Z . _]+@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-z]{2,}$")) {
            throw new RRException("邮箱格式错误！");
        }
        if (!PhoneFormatCheckUtils.isPhoneLegal(user.getMobile())) {
            throw new RRException("手机号格式错误！");
        }

        if (StringUtils.isBlank(user.getPassword())) {
            user.setPassword(new Sha256Hash(Global.DEFAULT_PASS_WORD).toHex());
        } else {
            user.setPassword(new Sha256Hash(user.getPassword()).toHex());
        }

        //检查角色是否越权
        checkRole(user);

        sysUserDao.update(user);

        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleId());
    }

    @Override
    @Transactional
    public void deleteBatch(Long[] userId) {
        sysUserDao.deleteBatch(userId);
    }

    @Override
    public int updatePassword(Long userId, String password, String newPassword) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        map.put("password", password);
        map.put("newPassword", newPassword);
        return sysUserDao.updatePassword(map);
    }

    /**
     * 检查角色是否越权
     */
    private void checkRole(SysUserEntity user) {
        //如果不是超级管理员，则需要判断用户的角色是否自己创建
        if (Dict.roleType.item_1.getItem().equalsIgnoreCase(ShiroUtils.getUserEntity().getRoleType())) {
            return;
        }
        if (user.getCreateUserId() == Constant.SUPER_ADMIN) {
            return;
        }

        //查询用户创建的角色列表
        List<Long> roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId());

        //判断是否越权
        if (!roleIdList.containsAll(user.getRoleIdList())) {
            throw new RRException("新增用户所选角色，不是本人创建");
        }
    }

    @Override
    public int uploadExcel(List<SysUserDto> sysUserDtoList){
        SysUserEntity user = ShiroUtils.getUserEntity();
        String merchSn = user.getMerchSn();
        boolean isFail = false;
        List<String> failThirdMerchSnList = new ArrayList<>(), failMerchSnList = new ArrayList<>(),
                failStoreNameList = new ArrayList<>(), failRoleTypeList = new ArrayList<>(),
                failEmailList = new ArrayList<>(), failMobieList = new ArrayList<>(), failRoleList = new ArrayList<>();
        if (sysUserDtoList != null && sysUserDtoList.size() > 0) {
            for (int i = 0; i < sysUserDtoList.size(); i++) {
                SysUserDto sysUserDto = sysUserDtoList.get(i);
                SysUserEntity sysUserEntity = new SysUserEntity();
                Map<String, Object> valideDate = MapBeanUtil.fromObject(sysUserDto);
                ImmutableBiMap.Builder builder = new ImmutableBiMap.Builder();
                builder.put("userName", "用户名");
                builder.put("email", "邮箱");
                builder.put("mobile", "手机");
                builder.put("roleType", "角色类型");
                builder.put("roleName", "角色名称");

                R r = ValidatorUtil.isEmpty(builder.build(), valideDate);
                if (Integer.valueOf(r.get("code").toString()) != 0) {
                    throw new RRException(r.get("msg").toString());
                }
                if (Dict.roleType.item_2.getItem().equalsIgnoreCase(sysUserDto.getRoleType())) {
                    builder.put("merchSn", "商户编号");
                    builder.put("thirdPartyMerchCode", "第三方商户代码");
                    builder.put("storeName", "门店名称");
                }else if (Dict.roleType.item_3.getItem().equalsIgnoreCase(sysUserDto.getRoleType())) {
                    builder.put("merchSn", "商户编号");
                }else if (Dict.roleType.item_4.getItem().equalsIgnoreCase(sysUserDto.getRoleType())) {
                    builder.put("merchSn", "商户编号");
                    builder.put("thirdPartyMerchCode", "第三方商户代码");
                }else if (Dict.roleType.item_1.getItem().equalsIgnoreCase(sysUserDto.getRoleType())) {
                    sysUserEntity.setMerchSn(null);
                    sysUserEntity.setThirdPartyMerchCode(null);
                    sysUserEntity.setStoreId(null);
                }
                r = ValidatorUtil.isEmpty(builder.build(), valideDate);
                if (Integer.valueOf(r.get("code").toString()) != 0) {
                    throw new RRException(r.get("msg").toString());
                }
                if(!sysUserDto.getRoleType().equalsIgnoreCase(Dict.roleType.item_1.getItem()) && !sysUserDto.getRoleType().equalsIgnoreCase(Dict.roleType.item_2.getItem())
                        && !sysUserDto.getRoleType().equalsIgnoreCase(Dict.roleType.item_3.getItem()) && !sysUserDto.getRoleType().equalsIgnoreCase(Dict.roleType.item_4.getItem())){
                    isFail = true;
                    failRoleTypeList.add(sysUserDto.getStoreName());
                }
                if (!user.getEmail().matches("^[a-z0-9A-Z]+[- | a-z0-9A-Z . _]+@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-z]{2,}$")) {
                    isFail = true;
                    failEmailList.add(sysUserDto.getStoreName());
                }
                if (!PhoneFormatCheckUtils.isPhoneLegal(user.getMobile())) {
                    isFail = true;
                    failMobieList.add(sysUserDto.getStoreName());
                }
                SysRoleEntity sysRoleEntity = sysRoleService.queryObjectByName(sysUserDto.getRoleName());
                if(sysRoleEntity == null){
                    isFail = true;
                    failRoleList.add(sysUserDto.getStoreName());
                }else {
                    sysUserEntity.setRoleId(sysRoleEntity.getRoleId());
                }
                if(sysUserDto.getRoleType().equalsIgnoreCase(Dict.roleType.item_4.getItem()) ||
                        sysUserDto.getRoleType().equalsIgnoreCase(Dict.roleType.item_2.getItem()) ||
                        sysUserDto.getRoleType().equalsIgnoreCase(Dict.roleType.item_3.getItem())){
                    MerchEntity merchEntity = merchDao.findByMerchSn(sysUserDto.getMerchSn());
                    if(merchEntity != null){
                        sysUserEntity.setMerchSn(merchEntity.getMerchSn());
                    }else{//商户不存在
                        isFail = true;
                        failMerchSnList.add(sysUserDto.getStoreName());
                    }
                }
                if(sysUserDto.getRoleType().equalsIgnoreCase(Dict.roleType.item_2.getItem()) ||
                        sysUserDto.getRoleType().equalsIgnoreCase(Dict.roleType.item_4.getItem())){
                    ThirdMerchantBizEntity thirdMerchantBizEntity = thirdMerchantBizDao.getThirdMerchangByCode(sysUserDto.getThirdPartyMerchCode());
                    if(thirdMerchantBizEntity != null){
                        sysUserEntity.setThirdPartyMerchCode(thirdMerchantBizEntity.getThirdPartyMerchCode());
                    }else{//第三方商户不存在
                        isFail = true;
                        failThirdMerchSnList.add(sysUserDto.getStoreName());
                    }
                }
                if(sysUserDto.getRoleType().equalsIgnoreCase(Dict.roleType.item_2.getItem())){
                    StoreEntity store = storeDao.queryObjectByName(sysUserDto.getStoreName().trim());
                    if (store != null) {
                        sysUserEntity.setStoreId(Integer.parseInt(String.valueOf(store.getId())));
                        sysUserEntity.setMerchSn(store.getMerchSn());
                    }else{
                        isFail = true;
                        failStoreNameList.add(sysUserDto.getStoreName());
                    }
                }
                sysUserEntity.setUsername(sysUserDto.getUserName());
                sysUserEntity.setEmail(sysUserDto.getEmail());
                sysUserEntity.setMobile(sysUserDto.getMobile());
                sysUserEntity.setRoleType(sysUserDto.getRoleType());
                sysUserEntity.setCreateUserId(user.getUserId());
                sysUserEntity.setStatus(Integer.parseInt(Dict.status.item_1.getItem()));
                sysUserEntity.setCreateTime(new Date());
                if(!isFail){
                    //sha256加密
                    sysUserEntity.setPassword(new Sha256Hash(Global.DEFAULT_PASS_WORD).toHex());
                    sysUserDao.save(sysUserEntity);

                    //检查角色是否越权
                    checkRole(sysUserEntity);

                    //保存用户与角色关系
                    sysUserRoleService.saveOrUpdate(sysUserEntity.getUserId(), sysUserEntity.getRoleId());
                }

                ExportExceptionDataEntity exportExceptionDataEntity = new ExportExceptionDataEntity();
                exportExceptionDataEntity.setCreaterSn(user.getUserId().toString());
                exportExceptionDataEntity.setUserId(user.getUserId().intValue());
                exportExceptionDataEntity.setCreateTime(new Date());
                exportExceptionDataEntity.setModTime(new Date());
                exportExceptionDataEntity.setMerchSn(merchSn);
                exportExceptionDataEntity.setStoreId(user.getStoreId());
                exportExceptionDataEntity.setExportDataType(Dict.exportDataType.item_3.getItem());

                if(failEmailList != null && failEmailList.size() > 0){
                    exportExceptionDataEntity.setExportExceptionData("邮箱格式不正确，请检查管理员excel中门店名称【"+ failEmailList +"】的邮箱列信息！");
                    exportExceptionDataDao.save(exportExceptionDataEntity);
                    throw new RRException("导入数据异常【邮箱格式不正确】，异常信息请在商品管理》》导入异常数据中查看检查");
                }
                if(failMobieList != null && failMobieList.size() > 0){
                    exportExceptionDataEntity.setExportExceptionData("手机格式不正确，请检查管理员excel中门店名称【"+ failMobieList +"】的手机列信息！");
                    exportExceptionDataDao.save(exportExceptionDataEntity);
                    throw new RRException("导入数据异常【手机格式不正确】，异常信息请在商品管理》》导入异常数据中查看检查");
                }
                if(failRoleList != null && failRoleList.size() > 0){
                    exportExceptionDataEntity.setExportExceptionData("角色信息不存在，请检查管理员excel中门店名称【"+ failRoleList +"】的角色名称列信息！");
                    exportExceptionDataDao.save(exportExceptionDataEntity);
                    throw new RRException("导入数据异常【角色信息不存在】，异常信息请在商品管理》》导入异常数据中查看检查");
                }
                if(failStoreNameList != null && failStoreNameList.size() > 0){
                    exportExceptionDataEntity.setExportExceptionData("门店名称不存在，请检查管理员excel中门店名称【"+ failStoreNameList +"】的门店名称信息！");
                    exportExceptionDataDao.save(exportExceptionDataEntity);
                    throw new RRException("导入数据异常【门店名称不存在】，异常信息请在商品管理》》导入异常数据中查看检查");
                }
                if(failThirdMerchSnList != null && failThirdMerchSnList.size() > 0){
                    exportExceptionDataEntity.setExportExceptionData("第三方商户代码不存在，请检查管理员excel中门店名称【"+failThirdMerchSnList+"】的第三方商户代码信息！");
                    exportExceptionDataDao.save(exportExceptionDataEntity);
                    throw new RRException("导入数据异常【第三方商户代码不存在】，异常信息请在商品管理》》导入异常数据中查看检查");
                }
                if(failMerchSnList != null && failMerchSnList.size() > 0){
                    exportExceptionDataEntity.setExportExceptionData("商户编号不存在！请检查管理员excel中门店名称【" + failMerchSnList + "】的商户列信息！");
                    exportExceptionDataDao.save(exportExceptionDataEntity);
                    throw new RRException("导入数据异常【商户编号不存在】，异常信息请在商品管理》》导入异常数据中查看检查");
                }
                if(failRoleTypeList != null && failRoleTypeList.size() > 0){
                    exportExceptionDataEntity.setExportExceptionData("商户编码不存在，请检查管理员excel中门店名称【"+failRoleTypeList+"】的角色类型列信息！");
                    exportExceptionDataDao.save(exportExceptionDataEntity);
                    throw new RRException("导入数据异常【商户编码不存在】，异常信息请在商品管理》》导入异常数据中查看检查");
                }
            }
        }else{
            throw new RRException("导入数据为空，或者检查数据是否为空");
        }
        throw new RRException("导入成功！");
//        return 1;
    }
}
