package thyyxxk.webserver.service.hutoolcache;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.BizException;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.hutoolcache.HutoolCacheDao;
import thyyxxk.webserver.entity.login.UserInfo;
import thyyxxk.webserver.utils.ListUtil;
import thyyxxk.webserver.utils.TokenUtil;

import java.util.*;

@Service
@RequiredArgsConstructor
public class UserCache implements HutoolCacheInterface<UserInfo> {
    private final HutoolCacheDao dao;
    private final DeptCache deptCache;
    private static final int CACHE_SIZE = 512;
    private final Cache<String, UserInfo> cache = CacheUtil.newLFUCache(CACHE_SIZE);
    private final Map<String, String> userPwd = new HashMap<>();

    @Override
    public void put(String key, UserInfo value) {
        if (value == null) {
            return;
        }
        cache.put(key, value);
        userPwd.put(key, value.getPassword());
    }

    public String getUserPwd(String key) {
        return userPwd.get(key);
    }

    @Override
    public UserInfo get(String key) {
        if (StrUtil.isBlank(key)) {
            return new UserInfo();
        }
        UserInfo userInfo = cache.get(key);
        if (userInfo == null) {
            userInfo = dbInfo(key);
            put(key, userInfo);
        }
        userInfo.setPassword(null);
        return userInfo;
    }

    public String getEmployeeName(String userId) {
        if (userId == null) {
            return "";
        }

        UserInfo userInfo = get(userId);
        if (userInfo == null) {
            return "";
        }
        return userInfo.getName();
    }

    @Override
    public void del(String key) {
        cache.remove(key);
        userPwd.remove(key);
    }

    private UserInfo dbInfo(String code) {
        UserInfo userInfo = dao.selectUserInfo(code);
        if (null == userInfo) {
            //说明用户被删除了
            userInfo = dao.selectUserInfoFromHis(code);
            if (null == userInfo) {
                throw new BizException(ExceptionEnum.USER_NOT_EXIST, "【code=" + code + "】的用户不存在。");
            }
            //先删除
            dao.delNewUserToDjUserBase(userInfo.getCode());
            dao.insertNewUserToDjUserBase(userInfo);
        }
        userInfo.setDeptName(deptCache.getDeptName(userInfo.getDeptCode()));
        userInfo.setHzDay(dao.getDeptHzDayByCode(userInfo.getDeptCode()));
        userInfo.setRoles(dao.selectUserRoles(code));
        userInfo.setPartTimeDept(dao.selectUserPartTimeDept(userInfo.getCode()));

        Set<String> deptList = getDept(userInfo.getDeptCode(), userInfo.getPartTimeDept());
        if (!deptList.isEmpty()) {
            Map<String, String> tempMap = new HashMap<>(deptList.size());
            deptList.forEach(item -> {
                if (item != null) {
                    tempMap.put(item, deptCache.getDeptName(item));
                }
            });
            userInfo.setPartTimeDeptMap(tempMap);
        }
        return userInfo;
    }

    private Set<String> getDept(String code, List<String> partTimeDept) {
        Set<String> list = new HashSet<>();
        if (ListUtil.notBlank(partTimeDept)) {
            list.addAll(partTimeDept);
        }
        list.add(code);
        QueryWrapper<?> qw = new QueryWrapper<>();
        qw.in("parent_code", list);
        List<String> temp = dao.selectChildDeptByCodeList(qw);
        if (ListUtil.notBlank(temp)) {
            list.addAll(temp);
        }
        return list;
    }

    public UserInfo getUserInfoByToken() {
        return get(TokenUtil.getInstance().getTokenUserId());
    }

    @Override
    public List<CacheAll> getAll() {
        return this.getAllUtils(cache.cacheObjIterator());
    }

    @Override
    public void refreshCache(String key) {
        put(key, dbInfo(key));
    }

    @Override
    public void clear() {
        cache.clear();
        userPwd.clear();
    }

    @Override
    public String getLabel() {
        return "人员";
    }
}
