package com.yonge.cooleshow.biz.dal.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
import com.yonge.cooleshow.auth.api.entity.SysUser;
import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantInfoMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantStaffMapper;
import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
import com.yonge.cooleshow.biz.dal.wrapper.TenantStaffWrapper;
import com.yonge.cooleshow.common.enums.UserLockFlag;
import com.yonge.toolset.base.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 机构员工表
 * 2023-07-21 17:32:49
 */
@Slf4j
@Service
public class TenantStaffServiceImpl extends ServiceImpl<TenantStaffMapper, TenantStaff> implements TenantStaffService {


    @Autowired
    private TenantInfoMapper tenantInfoMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysUserFeignService sysUserFeignService;

    /**
     * 查询详情
     *
     * @param id 详情ID
     * @return TenantStaff
     */
    @Override
    public TenantStaff detail(Long id) {

        return baseMapper.selectById(id);
    }

    /**
     * 分页查询
     *
     * @param page  IPage<TenantStaff>
     * @param query TenantStaffWrapper.TenantStaffQuery
     * @return IPage<TenantStaff>
     */
    @Override
    public IPage<TenantStaffWrapper.TenantStaff> selectPage(IPage<TenantStaffWrapper.TenantStaff> page, TenantStaffWrapper.TenantStaffQuery query) {
        IPage<TenantStaffWrapper.TenantStaff> pageResult = page.setRecords(baseMapper.selectPage(page, query));
        List<TenantStaffWrapper.TenantStaff> records = pageResult.getRecords();
        if (CollectionUtils.isNotEmpty(records)) {
            List<Long> tenantIdList = records.stream().map(TenantStaffWrapper.TenantStaff::getTenantId).distinct().collect(Collectors.toList());
            QueryWrapper<TenantInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(TenantInfo::getId, tenantIdList);
            List<TenantInfo> tenantInfos = tenantInfoMapper.selectList(queryWrapper);
            Map<Long, String> idNameMap = tenantInfos.stream().collect(Collectors.toMap(TenantInfo::getId, TenantInfo::getName));
            records.forEach(next -> next.setTenantName(idNameMap.getOrDefault(next.getTenantId(), "")));
        }
        return pageResult;
    }

    /**
     * 添加
     *
     * @param tenantStaff TenantStaffWrapper.TenantStaff
     * @return Boolean
     */
    @Override
    public Boolean add(TenantStaffWrapper.TenantStaff tenantStaff) {

        return this.save(JSON.parseObject(tenantStaff.jsonString(), TenantStaff.class));
    }

    /**
     * 更新
     *
     * @param tenantStaff TenantStaffWrapper.TenantStaff
     * @return Boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean update(TenantStaffWrapper.TenantStaffAdd tenantStaff) {
        TenantStaff staff = this.getById(tenantStaff.getId());
        if (staff == null) {
            throw new BizException("机构人员不存在");
        }
        staff.setNickname(tenantStaff.getNickname());
        // 主管理员不能修改身份
        if (Boolean.FALSE.equals(staff.getManageAdmin()) && Boolean.FALSE.equals(tenantStaff.getManageAdmin())) {
            staff.setManageAdmin(tenantStaff.getManageAdmin());
            // 更换了机构，清理wx关联ID
            if (!staff.getTenantId().equals(tenantStaff.getTenantId())) {
                staff.setTenantId(tenantStaff.getTenantId());
                staff.setWxOpenid(null);
            }
        }
        Long userId = staff.getUserId();
        com.yonge.cooleshow.biz.dal.entity.SysUser sysUser = new com.yonge.cooleshow.biz.dal.entity.SysUser();
        sysUser.setId(userId);
        sysUser.setUsername(tenantStaff.getNickname());
        sysUser.setGender(tenantStaff.getGender());

        String phone = tenantStaff.getPhone();
        // 修改手机号，处理账号
        com.yonge.cooleshow.biz.dal.entity.SysUser oldUser = sysUserMapper.selectById(userId);
        if (!oldUser.getPhone().equals(phone)) {
            SysUser userByPhone = sysUserMapper.findUserByPhone(phone);
            if (userByPhone != null) {
                throw new BizException("该手机号已经注册账号");
            } else {
                sysUser.setPhone(phone);
            }
            String wxOpenid = staff.getWxOpenid();
            // 存在值，说明登录并绑定过，执行退出登录
            if (StringUtils.isNotEmpty(wxOpenid)) {
                // 旧手机号退出登录
                sysUserFeignService.exitByPhoneAndOpenId(ClientEnum.ORGANIZATION.getCode().toLowerCase(),
                        oldUser.getPhone(), wxOpenid);
                staff.setWxOpenid(null);
            }
        }
        sysUserMapper.updateById(sysUser);

        tenantInfoMapper.update(null, Wrappers.<TenantInfo>lambdaUpdate()
                .set(TenantInfo::getPhone, tenantStaff.getPhone())
                .set(TenantInfo::getUsername, tenantStaff.getNickname())
                .eq(TenantInfo::getUserId, staff.getUserId()));

       return this.lambdaUpdate()
                .set(TenantStaff::getWxOpenid, staff.getWxOpenid())
                .set(TenantStaff::getTenantId, staff.getTenantId())
                .set(TenantStaff::getManageAdmin, staff.getManageAdmin())
                .set(TenantStaff::getNickname, staff.getNickname())
                .eq(TenantStaff::getId, staff.getId())
                .update();
    }

    @Override
    public TenantStaff getByPhone(String phone) {
        return baseMapper.getByPhone(phone);

    }

    /**
     * 根据用户ID获取员工信息
     *
     * @param userId 用户Id
     * @return TenantStaff
     */
    @Override
    public TenantStaff getByUserId(Long userId) {

        return lambdaQuery().eq(TenantStaff::getUserId, userId).last("LIMIT 1").one();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateStatus(Long id, UserLockFlag status) {
        if (UserLockFlag.LOCKED.equals(status)) {
            clearWxOpenId(id);
        }
        this.lambdaUpdate()
                .set(TenantStaff::getStatus, status)
                .eq(TenantStaff::getId, id)
                .update();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void clearWxOpenId(Long id) {
        TenantStaff staff = this.getById(id);
        if (staff == null) {
            return;
        }
        String wxOpenid = staff.getWxOpenid();
        if (StringUtils.isNotEmpty(wxOpenid)) {
            SysUser sysUser = sysUserMapper.getByUserId(staff.getUserId());
            sysUserFeignService.exitByPhoneAndOpenId(ClientEnum.ORGANIZATION.getCode().toLowerCase(),
                    sysUser.getPhone(), wxOpenid);
            this.lambdaUpdate()
                    .set(TenantStaff::getWxOpenid, null)
                    .eq(TenantStaff::getId, id)
                    .update();
        }
    }
}