package cn.superdesk.uniorder.service.sys.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.superdesk.uniorder.common.chinese.ChineseCharacterUtil;
import cn.superdesk.uniorder.common.enums.common.CommonEnabledEnum;
import cn.superdesk.uniorder.common.enums.common.CommonSoftDeleteEnum;
import cn.superdesk.uniorder.common.enums.common.CommonSourceFromEnum;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.organisation.SysCompany;
import cn.superdesk.uniorder.dao.entity.sys.SysUser;
import cn.superdesk.uniorder.dao.entity.sys.SysUserExample;
import cn.superdesk.uniorder.dao.entity.sys.SysUserOrderSourcetypeKey;
import cn.superdesk.uniorder.dao.entity.sys.role.SysRole;
import cn.superdesk.uniorder.dao.entity.sys.role.SysRoleExtData;
import cn.superdesk.uniorder.dao.entity.sys.role.SysRoleExtDataExample;
import cn.superdesk.uniorder.dao.mapper.organisation.SysCompanyMapper;
import cn.superdesk.uniorder.dao.mapper.sys.SysUserMapper;
import cn.superdesk.uniorder.dao.mapper.sys.SysUserMapperEx;
import cn.superdesk.uniorder.dao.mapper.sys.SysUserOrderSourcetypeMapper;
import cn.superdesk.uniorder.dao.mapper.sys.role.SysRoleExtDataMapper;
import cn.superdesk.uniorder.dao.mapper.sys.role.SysRoleMapper;
import cn.superdesk.uniorder.dto.param.system.SysUserQueryCriteria;
import cn.superdesk.uniorder.dto.vo._superdeskapp.jwt.SupperdeskAppTokenUser;
import cn.superdesk.uniorder.dto.vo.sys.SysUserView;
import cn.superdesk.uniorder.service.sys.SysUserService;
import cn.superdesk.uniorder.service.sys.role.SysRoleExtDataSampleService;
import cn.superdesk.uniorder.service.sys.role.SysRoleExtDataService;
import cn.superdesk.uniorder.service.sys.role.SysRoleService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: Java类作用描述
 * @Author: linjinyu
 * @CreateDate: 8/26/20 3:20 PM
 * @UpdateUser: linjinyu
 * @UpdateDate: 8/26/20 3:20 PM
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserMapper   sysUserMapper;
    @Autowired
    private SysUserMapperEx sysUserMapperEx;

    @Autowired
    private SysRoleMapper               sysRoleMapper;
    @Autowired
    private SysRoleService              sysRoleService;
    @Autowired
    private SysRoleExtDataMapper        sysRoleExtDataMapper;
    @Autowired
    private SysRoleExtDataService       sysRoleExtDataService;
    @Autowired
    private SysRoleExtDataSampleService sysRoleExtDataSampleService;

    @Autowired
    private SysUserOrderSourcetypeMapper sysUserOrderSourcetypeMapper;
    @Autowired
    private SysCompanyMapper             sysCompanyMapper;


    @Override
    public int insertSelective(SysUser t) {

        return sysUserMapper.insertSelective(t);
    }

    @Override
    public int updateByPrimaryKeySelective(SysUser t) {
        return sysUserMapper.updateByPrimaryKeySelective(t);

    }

    @Transactional
    @Override
    public void deleteObj(Long id) {

        sysUserOrderSourcetypeMapper.deleteByUserId(id);
        sysUserMapper.deleteByPrimaryKey(id);
    }

    public int opPhysicsDelete(Long id, LoginSysUser loginSysUser) {

        return sysUserMapper.deleteByPrimaryKey(id);
    }

    public int opLogicalDelete(Long id, LoginSysUser loginSysUser) {

        int ret = 0;

        SysUser originEntity = sysUserMapper.selectByPrimaryKey(id);

        if (ObjectUtil.isNotNull(originEntity)) {

            SysUser forUpdate = new SysUser();

            forUpdate.setId(id);
            forUpdate.setDeleted(CommonSoftDeleteEnum.删除.getKey());

            forUpdate.setUpdateTime(DateUtil.date());
            forUpdate.setUpdateUserId(loginSysUser.getSysUserId());

            ret = sysUserMapper.updateByPrimaryKeySelective(forUpdate);
        }

        return ret;

    }

    @Override
    public SysUser findById(Long id) {

        return sysUserMapper.selectByPrimaryKey(id);
    }


    @Override
    public List<SysUser> findBySysUserIds(List<Long> sysUserIds) {

        SysUserExample example = new SysUserExample();
        example.createCriteria()
                .andIdIn(sysUserIds);
        List<SysUser> resultList = sysUserMapper.selectByExample(example);

        return resultList;

    }


    @Override
    public List<SysUser> findAll(Map<String, Object> queryMap) {

        return sysUserMapperEx.findAll(queryMap);
    }

    @Deprecated
    @Override
    public PageInfo<SysUser> findByPaging(Map<String, Object> params, Integer pageNo, Integer pageSize) {

        return null;
    }


    @Override
    public R<List<SysUserView>> findAllPage(SysUserQueryCriteria queryCriteria) {

        PageHelper.startPage(queryCriteria.getPageNumber(), queryCriteria.getPageSize());
        List<SysUserView>     result = sysUserMapperEx.findSysUserView(queryCriteria);
        PageInfo<SysUserView> page   = new PageInfo<SysUserView>(result);

        for (SysUserView vo : result) {
            vo.setSourceFromName(CommonSourceFromEnum.getBySourceFromCode(vo.getSourceFrom()).getSourceFromName());
            vo.setSysRoleExtDataName(StringUtils.isBlank(vo.getSysRoleExtDataName()) ? "未配置" : vo.getSysRoleExtDataName());
        }

        return new R<List<SysUserView>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), result);
    }

    @Transactional
    @Override
    public SysUser addTran(SysUser sysUser, List<SysUserOrderSourcetypeKey> xResult) {

        sysUser.setDeleted(CommonSoftDeleteEnum.正常.getKey());
        sysUser.setEnabled(CommonEnabledEnum.启用.getKey());

        int ret = sysUserMapper.insert(sysUser);

        if (ret > 0 && xResult.size() > 0) {
            for (SysUserOrderSourcetypeKey item : xResult) {
                item.setUserId(sysUser.getId());
                sysUserOrderSourcetypeMapper.insert(item);
            }
        }

        return sysUser;
    }

    @Transactional
    @Override
    public void updateObjTran(SysUser user, List<SysUserOrderSourcetypeKey> xResult) {

        // 为了编辑时 不填写密码,密码就不要动了 20200903 by linjinyu
        if (StringUtils.isBlank(user.getUserPassword())) {
            user.setUserPassword(null);
        }

        sysUserMapper.updateByPrimaryKeySelective(user);

        if (xResult != null) {

            sysUserOrderSourcetypeMapper.deleteByUserId(user.getId());
            for (SysUserOrderSourcetypeKey item : xResult) {
                item.setUserId(user.getId());
                sysUserOrderSourcetypeMapper.insert(item);
            }
        }

    }

    private String ruleSysUser4SupplierOutSaleName(String outSaleName) {


        return ChineseCharacterUtil.getPingYin(outSaleName);
    }

    public SysUser getSysUser4SupperDeskUniMallSupplier(Long outSaleId, String outSaleName) {

        log.info("getSysUser4Supplier params : outSaleId -> {} outSaleName -> {}", outSaleId, outSaleName);

        // 一般登陆代码在 superdesk-uniorder/superdesk-uniorder-dubbo-provider/src/main/java/cn/superdesk/uniorder/dubbo/service/sys/DubboSysUserServiceImpl.java
//		Map<String, Object> queryMap = new HashMap<>();
//		queryMap.put("username", username);
//		queryMap.put("password", password);
//		List<SysUser> checkSysUserList = sysUserService.findAll(queryMap);

        // 看一下这个要怎样做
        // password 最好不要写死,为了以后可以直接登陆 , 先这样定义吧 TODO 规则 username 为 {outSaleName} ; password 为 {outSaleId}_{outSaleName}


        SysUserExample example = new SysUserExample();
        example.createCriteria()
                .andUserNameEqualTo(ruleSysUser4SupplierOutSaleName(outSaleName))
                .andUserPasswordEqualTo(outSaleId + "_" + ruleSysUser4SupplierOutSaleName(outSaleName));

        List<SysUser> sysUserListByUserNamePassword = sysUserMapper.selectByExample(example);
        if (CollUtil.isNotEmpty(sysUserListByUserNamePassword)) {
            return sysUserListByUserNamePassword.get(0);
        } else {


//			1. 再用 outSaleName 去查一下有没有这个账号
//			有 就是说 供应商改了密码
//			没有 就要去建一个了
            example.clear();
            example.createCriteria()
                    .andUserNameEqualTo(ruleSysUser4SupplierOutSaleName(outSaleName));
            List<SysUser> sysUserListByUserName = sysUserMapper.selectByExample(example);

            // 有 就是说 供应商改了密码
            if (CollUtil.isNotEmpty(sysUserListByUserName)) {
//				先给他登陆吧 因为这个接口是从供应商端过来的,所以可以先这样做,但不是最优的做法
                return sysUserListByUserName.get(0);
            }
            // 没有 就要去建一个了
            else {
                return createSysUser4SupperDeskUniMallSupplier(outSaleId, outSaleName);
            }
        }

//		return null;

    }

    public SysUser createSysUser4SupperDeskUniMallSupplier(Long outSaleId, String outSaleName) {

        // 过来的信息 先去 表 密码写死
//		SELECT * FROM `sys_user`

//		如果没有的话 要生成账号

        SysUser sysUser = new SysUser();

        sysUser.setUserName(ruleSysUser4SupplierOutSaleName(outSaleName));
        sysUser.setUserPassword(outSaleId + "_" + ruleSysUser4SupplierOutSaleName(outSaleName));
        sysUser.setFullname(outSaleName);// 真名
        sysUser.setPhone("");

        sysUser.setRoleId(1L);// 菜单权限ID
        sysUser.setSysRoleExtDataId(0L);// 数据权限ID

        sysUser.setSourceFrom(CommonSourceFromEnum.企业福利_侨城汇.getSourceFromCode());// 来源 商城

        sysUser.setPersonalizedLogo("");
        sysUser.setPersonalizedSubhead("");

        sysUser.setCreateTime(DateUtil.date());
        sysUser.setCreateUserId(1L);

        sysUser.setUpdateTime(DateUtil.date());
        sysUser.setUpdateUserId(1L);

        sysUser.setDeleted(CommonSoftDeleteEnum.正常.getKey());
        sysUser.setEnabled(CommonEnabledEnum.启用.getKey());

        try {
            sysUserMapper.insert(sysUser);
        } catch (Exception e) {
            e.printStackTrace();
        }

        log.info("生成账号:{}", AnJsonUtils.toJson(sysUser));

        return sysUser;

    }

    public SysUser getSysUser4SupperDeskUniService(SupperdeskAppTokenUser userToken) {

        log.info("getSysUser4SupperDeskUniService params : SupperdeskAppTokenUser -> {} ", AnJsonUtils.toJson(userToken));

        SysUser responseSysUser = null;

        SysUserExample example = new SysUserExample();
        example.createCriteria()
                .andUserNameEqualTo(userToken.getUserName())
                .andSourceFromEqualTo(CommonSourceFromEnum.服务之窗.getSourceFromCode())
                .andUserPasswordEqualTo(userToken.getUserName() + "_" + ruleSysUser4SupplierOutSaleName(userToken.getRealName()));

        List<SysUser> sysUserListByUserNamePassword = sysUserMapper.selectByExample(example);

        if (CollUtil.isNotEmpty(sysUserListByUserNamePassword)) {

            // TODO 更新channelId 补刀 mark by linjinyu at 20210630
            responseSysUser = sysUserListByUserNamePassword.get(0);
            updateSysUser4SupperDeskUniService(responseSysUser, userToken);
            return responseSysUser;

        } else {


//			1. 再用 userName 去查一下有没有这个账号
//			有 就是说 供应商 改了密码
//			没有 就要去建一个了
            example.clear();
            example.createCriteria()
                    .andUserNameEqualTo(userToken.getUserName())
                    .andSourceFromEqualTo(CommonSourceFromEnum.服务之窗.getSourceFromCode());
            List<SysUser> sysUserListByUserName = sysUserMapper.selectByExample(example);

            // 有 就是说 供应商改了密码
            if (CollUtil.isNotEmpty(sysUserListByUserName)) {

                // 先给他登陆吧 因为这个接口是从 服务之窗 过来的,所以可以先这样做,但不是最优的做法
                // TODO 更新channelId 补刀 mark by linjinyu at 20210630
                responseSysUser = sysUserListByUserName.get(0);
                updateSysUser4SupperDeskUniService(responseSysUser, userToken);
                return responseSysUser;
            }
            // 没有 就要去建一个了
            else {

                // TODO 更新channelId 补刀 mark by linjinyu at 20210630
                return createSysUser4SupperDeskUniService(userToken);
            }
        }

//		return null;

    }

    public SysUser createSysUser4SupperDeskUniService(SupperdeskAppTokenUser supperdeskAppTokenUser) {

        // 过来的信息 先去 表 密码写死
//		SELECT * FROM `sys_user`

//		如果没有的话 要生成账号

        SysUser sysUser = new SysUser();

        sysUser.setUserName(supperdeskAppTokenUser.getUserName());
        sysUser.setUserPassword(supperdeskAppTokenUser.getUserName() + "_" + ruleSysUser4SupplierOutSaleName(supperdeskAppTokenUser.getRealName()));
        sysUser.setFullname(supperdeskAppTokenUser.getRealName());// 真名
        sysUser.setPhone("");

        sysUser.setRoleId(getConvertRoleId(supperdeskAppTokenUser.getUserType()));// TODO 菜单权限ID
        sysUser.setSysRoleExtDataId(getConvertSysRoleExtDataId(supperdeskAppTokenUser.getCompId()));// TODO 数据权限ID

        sysUser.setSourceFrom(CommonSourceFromEnum.服务之窗.getSourceFromCode());// 来源 服务之窗
        sysUser.setSourceFromQuoteId(supperdeskAppTokenUser.getCompId());

        sysUser.setPersonalizedLogo("");
        sysUser.setPersonalizedSubhead("");

        sysUser.setCreateTime(DateUtil.date());
        sysUser.setCreateUserId(1L);

        sysUser.setUpdateTime(DateUtil.date());
        sysUser.setUpdateUserId(1L);

        sysUser.setDeleted(CommonSoftDeleteEnum.正常.getKey());
        sysUser.setEnabled(CommonEnabledEnum.启用.getKey());

        try {
            sysUserMapper.insert(sysUser);
        } catch (Exception e) {
            e.printStackTrace();
        }

        log.info("生成账号:{}", AnJsonUtils.toJson(sysUser));

        return sysUser;

    }

    /**
     * 更新channelId 补刀 mark by linjinyu at 20210630
     *
     * @param sysUser
     * @param supperdeskAppTokenUser
     */
    public void updateSysUser4SupperDeskUniService(SysUser sysUser, SupperdeskAppTokenUser supperdeskAppTokenUser) {

        SysUser sysUser4Update = new SysUser();
        sysUser4Update.setId(sysUser.getId());
        sysUser4Update.setSourceFromQuoteId(supperdeskAppTokenUser.getCompId());

        sysUserMapper.updateByPrimaryKeySelective(sysUser4Update);

    }

    private Long getConvertRoleId(Integer userType) {

        SysRole sysRole = null;

        switch (userType) {
            case 20:
                // 运营商管理员
                sysRole = sysRoleService.findByAvicCode("AVIC20");
                break;
            case 22:
                // 运营商操作员,关联统一订单运营商角色
                sysRole = sysRoleService.findByAvicCode("AVIC20");
                break;
            case 21:
                // 渠道商管理员
                sysRole = sysRoleService.findByAvicCode("AVIC21");
                break;
            case 23:
                // 渠道商操作员,关联统一订单渠道商角色
                sysRole = sysRoleService.findByAvicCode("AVIC21");
                break;
        }

        if (sysRole != null)
            return sysRole.getId();

        return null;
    }

    private Long getConvertSysRoleExtDataId(Long compId) {


        SysRoleExtDataExample sysRoleExtDataExample = new SysRoleExtDataExample();
        sysRoleExtDataExample.createCriteria()
                .andSourceFromQuoteIdEqualTo(compId);

        List<SysRoleExtData> resultList = sysRoleExtDataMapper.selectByExample(sysRoleExtDataExample);

        if (CollUtil.isNotEmpty(resultList)) {
            return resultList.get(0).getId();
        } else {

            // 标记
            return -1L;
        }

    }

    @Override
    public SysCompany getSysCompany(Long id) {

        return sysCompanyMapper.selectByPrimaryKey(id);
    }

//	@Override
//	public int insert(SysUser record) {
//
//		return 0;
//	}
//
//	@Override
//	public SysUser selectByPrimaryKey(String userId) {
//
//		return userMapper.selectByPrimaryKey(userId);
//	}


//	@Override
//	public SysUserVO refreshToken(String userId) {
//
//		SysUserVO rspVo = new SysUserVO();
//		TokenVO token = JwtUtil.createToken(rspVo.getUserId(),SystemConsts.RedisExpireTime.TOKEN_EXPIRE_TIME);
//		rspVo.setToken(token.getToken());
//		rspVo.setUserId(userId);
//
//		String createTime = AnDateHelper.formatDateToStr(token.getCreateTime());
//		Map<String,String> mapValue = Maps.newHashMap();
//		mapValue.put("updateTime", createTime);
//		mapValue.put("expireTime", AnDateHelper.formatDateToStr(token.getExpireTime()));
//		redisService.saveHash(mapValue, RedisKeyPrefix.TOKEN_CACHE,rspVo.getUserId() , SystemConsts.RedisExpireTime.REFRESH_TOKEN_EXPIRE_TIME);
//
//		return rspVo;
//	}

//	@Override
//	public int updateByPrimaryKeySelective(SysUser record) {
//
//		int res= userMapper.updateByPrimaryKeySelective(record);
//		if(res>0) {
//			return res;
//		}
//
//		return 0;
//	}
//
//	@Override
//	public int updateByPrimaryKey(SysUser record) {
//
//		return 0;
//	}
//
//
//	@Override
//	public ResponseResult<List<SysUserQueryVO>> listSysUser(SysUserParamsVO vo) throws MyException {
//		PageHelper.startPage(vo.getPageNo(), vo.getPageSize());
//		List<SysUserQueryVO> listSysUserQuery = userMapper.listSysUser(vo);
//		PageInfo<SysUserQueryVO> page = new PageInfo<SysUserQueryVO>(listSysUserQuery);
//		return new ResponseResult<List<SysUserQueryVO>>(page.getPageNum(), page.getPageSize(), (int)page.getTotal(), listSysUserQuery);
//	}
//
//	@Override
//	public ResponseResult<SysUserEditVO> getSysUser(SysUserParamsVO vo) throws MyException {
//		SysUserEditVO sysUser = userMapper.getSysUser(vo);
//
//		return new ResponseResult<SysUserEditVO>(sysUser);
//	}
//
//	@Override
//	public SysUser findbyContact(String contactNumber) {
//
//		return userMapper.selectByAccount(contactNumber);
//	}
//
//	@Override
//	public int insertSelective(SysUser record) {
//
//		return 0;
//	}

    /****************************************** 工具方法 sysUserIds 推导 start ******************************************/

    public List<String> convertSysUserIds2FullName(List<Long> sysUserIds) {
        List<String> result = new ArrayList<>();

        List<SysUser> sysEnterpriseList = findBySysUserIds(sysUserIds);

        if (CollUtil.isNotEmpty(sysEnterpriseList)) {
            result = sysEnterpriseList.stream()
                    .filter(AnLamdaUtils.distinctByKey(o -> o.getId()))
                    .map(SysUser::getFullname)
                    .collect(Collectors.toList());
        }

        return result;
    }

    public Map<Long, String> convertSysUserIds2MapSysUserId2FullName(List<Long> sysUserIds) {

        Map<Long, String> result = new HashMap<>();

        if (CollUtil.isNotEmpty(sysUserIds)) {
            List<SysUser> sysUserList = findBySysUserIds(sysUserIds);

            if (CollUtil.isNotEmpty(sysUserList)) {

                result = sysUserList.stream().collect(Collectors.toMap(SysUser::getId, SysUser::getFullname, (k, v) -> v));
            }
        }

        return result;
    }

    public Map<Long, SysUser> convertSysUserIds2MapSysUserId2Entity(List<Long> sysUserIds) {

        Map<Long, SysUser> result = new HashMap<>();

        if (CollUtil.isNotEmpty(sysUserIds)) {

            List<SysUser> sysUserList = findBySysUserIds(sysUserIds);

            if (CollUtil.isNotEmpty(sysUserList)) {

                result = sysUserList.stream().collect(Collectors.toMap(SysUser::getId, v -> v, (k, v) -> v));
            }
        }

        return result;

    }

    /****************************************** 工具方法 sysUserIds 推导   end ******************************************/

    @Override
    public SysUser createSysUser4Qchjc(String userId, String userName) {

        SysUser sysUser = new SysUser();

        //避免重名，加个后缀
        sysUser.setUserName(ruleSysUser4SupplierOutSaleName(userName) + System.currentTimeMillis());
        sysUser.setUserPassword(userId);
        sysUser.setFullname(userName);// 真名
        sysUser.setPhone("");

        sysUser.setRoleId(1L);// 菜单权限ID
        sysUser.setSysRoleExtDataId(0L);// 数据权限ID

        sysUser.setSourceFrom(CommonSourceFromEnum.企业商城_侨城汇.getSourceFromCode());// 来源 商城

        sysUser.setPersonalizedLogo("");
        sysUser.setPersonalizedSubhead("");

        sysUser.setCreateTime(DateUtil.date());
        sysUser.setCreateUserId(1L);

        sysUser.setUpdateTime(DateUtil.date());
        sysUser.setUpdateUserId(1L);

        sysUser.setDeleted(CommonSoftDeleteEnum.正常.getKey());
        sysUser.setEnabled(CommonEnabledEnum.启用.getKey());

        try {
            sysUserMapper.insert(sysUser);
        } catch (Exception e) {
            e.printStackTrace();
        }

        log.info("生成账号:{}", AnJsonUtils.toJson(sysUser));

        return sysUser;
    }


}
