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

import com.ym.mec.auth.api.dto.SysUserInfo;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.auth.dal.dao.SysUserDao;
import com.ym.mec.auth.service.SysRoleMenuService;
import com.ym.mec.auth.service.SysUserService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.entity.ImResult;
import com.ym.mec.common.entity.ImUserModel;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.common.tenant.TenantContextHolder;
import com.ym.mec.im.ImFeignService;
import com.ym.mec.web.WebFeignService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class SysUserServiceImpl extends BaseServiceImpl<Integer, SysUser> implements SysUserService {

    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysRoleMenuService sysRoleMenuService;
    @Autowired
    private ImFeignService imFeignService;
    @Autowired
    private WebFeignService userFeignService;
    @Autowired
    private SysUserService sysUserService;

    @Value("${auth.sysconfig.tenantId}")
    private Integer lesseeOrganId;

    @Override
    public BaseDAO<Integer, SysUser> getDAO() {
        return sysUserDao;
    }

    @Override
    public SysUser queryByUsername(String username) {
        return sysUserDao.queryByUsername(username);
    }

    @Override
    public SysUser queryByPhone(String phone) {
        return sysUserDao.queryByPhone(phone);
    }

    @Override
    public SysUser queryLockByPhone(String phone) {
        return sysUserDao.queryLockByPhone(phone);
    }

    @Override
    public SysUser queryByPhoneAndClient(String phone, String client) {
        return sysUserDao.queryByPhoneAndClient(phone, client);
    }

    @Override
    public SysUserInfo queryUserInfoByUsername(String username) {
        return getSysUserInfo(queryByUsername(username));
    }

    @Override
    public SysUserInfo queryUserInfoByPhone(String phone) {
        return getSysUserInfo(queryLockByPhone(phone));
    }

    private SysUserInfo getSysUserInfo(SysUser sysUser) {
        if (sysUser == null) {
            return null;
        }
        SysUserInfo userInfo = new SysUserInfo();
        userInfo.setSysUser(sysUser);
        List<String> permissionList = sysRoleMenuService.queryPermissionsByRoleIdList(sysUser.getId());
        String[] strArray = permissionList.toArray(new String[permissionList.size()]);
        userInfo.setPermissions(strArray);
        return userInfo;
    }

    @Override
    public Integer add(SysUser sysUser) {
        sysUserDao.insert(sysUser);
        ImResult imResult = imFeignService.register(new ImUserModel(sysUser.getId().toString(), sysUser.getUsername(), sysUser.getAvatar()));
        sysUser.setImToken(imResult.getToken());
        sysUserDao.update(sysUser);
        return sysUser.getId();
    }

    @Override
    public ImUserModel getBasic(Integer userId) {
        return sysUserDao.getBasic(userId);
    }

    @Override
    public void updateBaseInfo(SysUser sysUser) {
        sysUserDao.update(sysUser);
        imFeignService.update(new ImUserModel(sysUser.getId().toString(), sysUser.getRealName() == null ? sysUser.getUsername() : sysUser.getRealName(), sysUser.getAvatar()));
    }

    @Override
    public SysUser queryUserInfo(Integer userId) {
        return sysUserDao.get(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysUserInfo initUser(Integer tenantId, String organId, String phone, String clientId) {
        if (StringUtils.equalsIgnoreCase(clientId, "TEACHER")) {
            SysUser sysUser = new SysUser();
            sysUser.setPhone(phone);
            sysUser.setUserType("TEACHER");
            sysUser.setTenantId(tenantId);
            sysUserDao.insert(sysUser);
            //添加用户现金账户
            imFeignService.register(new ImUserModel(sysUser.getId().toString(), phone, null));
            userFeignService.createCashAccount(sysUser.getId(), tenantId);
            //sysTenantAccount
            sysUserDao.insertSysTenantAccount(sysUser.getId());
            //创建teacher表
            sysUserDao.insertTeacher(sysUser.getId(), lesseeOrganId, tenantId);
            return queryUserInfoByPhone(phone);
        } else if (StringUtils.equalsIgnoreCase(clientId, "STUDENT")) {
            SysUser sysUser = new SysUser();
            sysUser.setPhone(phone);
            sysUser.setUserType("STUDENT");
            if (StringUtils.isBlank(organId)) {
                sysUser.setOrganId(lesseeOrganId);
            } else {
                sysUser.setOrganId(Integer.parseInt(organId));
            }
            sysUser.setTenantId(tenantId);
            sysUserDao.insert(sysUser);
            sysUserService.saveStudent(sysUser.getId(), tenantId);
            //添加用户现金账户
            imFeignService.register(new ImUserModel(sysUser.getId().toString(), phone, null));
            userFeignService.createCashAccount(sysUser.getId(), tenantId);
            return queryUserInfoByPhone(phone);
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void refreshImToken(SysUser sysUser) {
        sysUserDao.refreshImToken(sysUser.getId(), sysUser.getImToken());
    }

    @Override
    public void saveStudent(Integer userId, Integer tenantId) {
        sysUserDao.saveStudent(userId, tenantId);
    }

    @Override
    public void saveTeacher(Integer userId, Integer tenantId) {
        sysUserDao.insertTeacher(userId, lesseeOrganId, tenantId);
    }

    @Override
    public Integer getLesseeOrganId() {
        return lesseeOrganId;
    }

    /**
     * 通过手机号及姓名进行模糊查询
     *
     * @param search 关键字
     */
    @Override
    public List<SysUser> queryLikeByPhoneOrName(String search) {
        if (StringUtils.isBlank(search.trim())) {
            return new ArrayList<>();
        }
        List<SysUser> sysUsers = sysUserDao.queryLikeByPhoneOrName(search, TenantContextHolder.getTenantId());
        if (CollectionUtils.isEmpty(sysUsers)) {
            return new ArrayList<>();
        }
        //只查询管理及老师
        return sysUsers.stream()
                .filter(u -> u.getUserType().contains("SYSTEM") || u.getUserType().contains("TEACHER"))
                .collect(Collectors.toList());
    }

    @Override
    public String queryClientByPhone(String phone) {
        SysUser sysUser = queryByPhone(phone);
        if (sysUser == null) {
            return null;
        }
        return sysUser.getUserType();
    }

}
