package com.ym.mec.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.TenantProxyInfoDao;
import com.ym.mec.biz.dal.dto.TenantProxyDto;
import com.ym.mec.biz.dal.entity.TenantProxyInfo;
import com.ym.mec.biz.dal.entity.TenantProxyUserRelation;
import com.ym.mec.biz.dal.vo.ProxyUserVo;
import com.ym.mec.biz.service.TenantProxyInfoService;
import com.ym.mec.biz.service.TenantProxyUserRelationService;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.page.PageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 机构代理商信息表(TenantProxyInfo)表服务实现类
 *
 * @author hgw
 * @since 2022-04-22 14:08:20
 */
@Service("tenantProxyInfoService")
public class TenantProxyInfoServiceImpl extends ServiceImpl<TenantProxyInfoDao, TenantProxyInfo> implements TenantProxyInfoService {

    private final static Logger log = LoggerFactory.getLogger(TenantProxyInfoServiceImpl.class);

    @Autowired
    private SysUserFeignService sysUserFeignService;
    @Autowired
    private TenantProxyUserRelationService proxyUserRelationService;

    @Override
    public TenantProxyInfoDao getDao() {
        return this.baseMapper;
    }

    /**
     * 后台-添加代理商信息
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addProxyInfo(TenantProxyDto dto) {
        Optional.ofNullable(dto.getProxyName())
                .orElseThrow(() -> new RuntimeException("代理商名称不能为空"));
        //当前操作人id
        Integer opsUserId = getUser().getId();
        Date now = new Date();
        //添加sysUser人员信息
        Integer userId = addSysUser(dto, "PROXY");
        //添加代理商信息表
        TenantProxyInfo proxyInfo = new TenantProxyInfo();
        proxyInfo.setProxyName(dto.getProxyName());
        proxyInfo.setProxyUserId(userId);
        proxyInfo.setState(0);
        proxyInfo.setCreateBy(opsUserId);
        proxyInfo.setCreateTime(now);
        this.save(proxyInfo);
        //添加代理商人员关系表
        TenantProxyUserRelation userRelation = new TenantProxyUserRelation();
        userRelation.setProxyId(proxyInfo.getId());
        userRelation.setUserId(userId);
        userRelation.setRank(0);
        userRelation.setCreateTime(now);
        proxyUserRelationService.save(userRelation);
    }

    /**
     * 添加代理商下面的员工
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addProxyStaff(TenantProxyDto dto) {
        //获取父级Id
        Integer parentId = Optional.ofNullable(dto.getParentId()).orElseGet(() -> getUser().getId());
        //员工id
        Integer userId = addSysUser(dto, null);
        //查询父级信息
        TenantProxyUserRelation parentProxyUser = proxyUserRelationService.getOne(Wrappers.<TenantProxyUserRelation>lambdaQuery()
                .eq(TenantProxyUserRelation::getUserId, parentId)
                .isNull(TenantProxyUserRelation::getParentId)
        );
        //添加代理商人员关系表
        TenantProxyUserRelation userRelation = new TenantProxyUserRelation();
        userRelation.setProxyId(parentProxyUser.getProxyId());
        userRelation.setParentId(parentId);
        userRelation.setUserId(userId);
        userRelation.setRank(parentProxyUser.getRank() + 1);
        userRelation.setCreateTime(new Date());
        proxyUserRelationService.save(userRelation);
    }

    /**
     * 添加sysUser人员信息
     *
     * @return id
     */
    private Integer addSysUser(TenantProxyDto dto, String userType) {
        SysUser sysUser = sysUserFeignService.queryUserByMobile(dto.getPhone());
        if (Objects.nonNull(sysUser)) {
            throw new BizException("该手机号在系统已存在！");
        }
        sysUser = new SysUser();
        sysUser.setTenantId(-1);
        sysUser.setUsername(dto.getName());
        sysUser.setPhone(dto.getPhone());
        int phoneStrLen = sysUser.getPhone().length();
        sysUser.setPassword(new BCryptPasswordEncoder().encode("gym" + sysUser.getPhone().substring(phoneStrLen - 4, phoneStrLen)));
        sysUser.setUserType(userType);
        sysUser.setRealName(dto.getName());
        baseMapper.insertProxySysUser(sysUser);
        return sysUser.getId();
    }

    /**
     * 查询代理商下级人员数据
     *
     * @param userId 代理人id
     */
    public List<ProxyUserVo> queryProxyUserStaff(Integer userId) {
        return baseMapper.queryProxyUserStaff(userId);
    }

    /**
     * 分页查询代理商负责人数据
     *
     * @param param 传入参数
     *              <p> - state  状态 0正常 1冻结
     *              <p> - row 条数
     *              <p> - page 页数
     *              <p> - search 模糊搜索关键字
     */
    public PageInfo<ProxyUserVo> queryProxyUser(Map<String, Object> param) {
        Page<ProxyUserVo> pageInfo = PageUtil.getPageInfo(param);
        pageInfo.setAsc("c.create_time_");
        return PageUtil.pageInfo(baseMapper.queryProxyUser(pageInfo, param));
    }

    /**
     * 冻结/解冻代理商
     *
     * @param userId 代理负责人id
     * @param state  状态 0正常 1冻结
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void freezeProxy(Integer userId, Integer state) {
        //sysUser表 lock字段 9冻结 0解冻
        Integer lockFlag = state == 0 ? state : 9;
        //先冻结sysUser表
        baseMapper.updateProxySysUserLock(userId, lockFlag);
        //在修改代理商表
        TenantProxyInfo tenantProxyInfo = this.getOne(Wrappers.<TenantProxyInfo>lambdaUpdate()
                .eq(TenantProxyInfo::getProxyUserId, userId));
        tenantProxyInfo.setState(state);
        this.updateById(tenantProxyInfo);
    }

    /**
     * 修改人员信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateProxyUserInfo(TenantProxyDto dto) {
        Optional.ofNullable(dto.getUserId()).orElseThrow(() -> new BizException("人员id不能为空"));
        //查询父级信息
        TenantProxyUserRelation parentProxyUser = proxyUserRelationService.getOne(Wrappers.<TenantProxyUserRelation>lambdaQuery()
                .eq(TenantProxyUserRelation::getUserId, dto.getUserId()));
        //判断本次修改的是不是代理商负责人，如果是负责人可能要修改代理商名称
        if (Objects.isNull(parentProxyUser.getParentId())) {
            TenantProxyInfo tenantProxyInfo = this.getOne(Wrappers.<TenantProxyInfo>lambdaUpdate()
                    .eq(TenantProxyInfo::getProxyUserId, dto.getUserId()));
            tenantProxyInfo.setProxyName(dto.getProxyName());
            this.updateById(tenantProxyInfo);
        }
        baseMapper.updateSysUserPhone(dto.getUserId(), dto.getPhone(), dto.getName());
    }

    /**
     * 根据手机号/姓名模糊查询所有平台账号信息
     *
     * @param param 传入参数
     *              <p> - search 模糊搜索关键字
     */
    public List<SysUser> queryUserList(Map<String, Object> param) {
        log.info("queryUserList>>>>>> {}", JSON.toJSONString(param));
        return baseMapper.queryUserList(param);
    }

    /**
     * 根据token查询用户信息-代理商专用
     *
     * @return
     */
    public SysUser queryUserList() {
        SysUser user = getUser();
        SysUser result = new SysUser();
        result.setRealName(user.getRealName());
        result.setId(user.getId());
        result.setPhone(user.getPhone());
        return result;
    }

    private SysUser getUser() {
        //修改机构基础信息
        return Optional.ofNullable(sysUserFeignService.queryUserInfo())
                .orElseThrow(() -> new BizException("用户信息获取失败,请刷新页面或者重新登录!"));
    }

}

