package thyyxxk.webserver.service.redislike;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.dao.his.LoginDao;
import thyyxxk.webserver.dao.his.redislike.RedisLikeDao;
import thyyxxk.webserver.dao.his.zhuyuanyisheng.YiZhuLuRuDao;
import thyyxxk.webserver.entity.dictionary.CodeName;
import thyyxxk.webserver.entity.login.UserInfo;
import thyyxxk.webserver.entity.settings.IntergrationPlatformRoleMenu;
import thyyxxk.webserver.entity.zhuyuanyisheng.yizhuluru.YzZdOrderItemConfirm;
import thyyxxk.webserver.service.RedisServer;
import thyyxxk.webserver.utils.ListUtil;
import thyyxxk.webserver.utils.StringUtil;
import thyyxxk.webserver.utils.TokenUtil;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@Component
public class RedisLikeService {
    private final RedisServer redisServer;
    public final static String SCROLLING_MESSAGES = "scrollingMessages";
    public final static String SYSTEM_UPDATES_MESSAGE = "systemUpdatesMessage";
    private final static Map<String, String> EMPLOYEE_NAME_MAP = new HashMap<>();
    private final static Map<String, String> DEPT_NAME_MAP = new HashMap<>();
    private final static Map<String, String> DEPT_AND_EMPLOYEE_NAME = new HashMap<>();
    private final static Map<String, String> REGION_MAP = new HashMap<>();
    private final static Map<String, String> WJW_ANAESTHESIA_MAP = new HashMap<>();
    private final static Map<String, String> WJW_DEPARTMENT_MAP = new HashMap<>();
    private final static Map<String, String> WJW_NATION_MAP = new HashMap<>();
    private final static Map<String, String> COUNTRY_MAP = new HashMap<>();
    private final static Map<String, String> NATION_MAP = new HashMap<>();
    private final static Map<String, String> OCCUPATION_MAP = new HashMap<>();
    private final static Map<String, String> YB_CONTACT_RELATION_MAP = new HashMap<>();
    private final static Map<String, String> YB_DEPT_MAP = new HashMap<>();
    private final static Map<String, String> CODE_RS_MAP = new HashMap<>();
    public static final Map<String, YzZdOrderItemConfirm> specialMedicalAdvice = new HashMap<>();
    private final RedisLikeDao dao;
    private final YiZhuLuRuDao yzDao;
    private final LoginDao loginDao;

    private final static Map<String, String> MESSAGE = new HashMap<>(2);

    public void setMessage(String key, String value) {
        MESSAGE.put(key, value);
    }

    public Map<String, String> getMessage() {
        return MESSAGE;
    }

    public RedisLikeService(RedisServer redisServer, RedisLikeDao dao, YiZhuLuRuDao yzDao, LoginDao loginDao) {
        this.redisServer = redisServer;
        this.dao = dao;
        this.yzDao = yzDao;
        this.loginDao = loginDao;
    }

    public String getEmployeeName(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        String username = EMPLOYEE_NAME_MAP.get(code);
        if (null == username) {
            username = dao.selectEmployeeName(code);
            EMPLOYEE_NAME_MAP.put(code, username);
        }
        return username;
    }

    public String getDeptAndEmployeeName(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        String result = DEPT_AND_EMPLOYEE_NAME.get(code);
        if (null == result) {
            result = dao.selectDeptAndUser(code);
            DEPT_AND_EMPLOYEE_NAME.put(code, result);
        }
        return result;
    }

    public String getDeptName(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        String deptName = DEPT_NAME_MAP.get(code);
        if (null == deptName) {
            deptName = dao.selectDeptName(code);
            DEPT_NAME_MAP.put(code, deptName);
        }
        return deptName;
    }

    public String getRegionName(String code) {
        if (StringUtil.isBlank(code)) {
            return null;
        }
        String regionName = REGION_MAP.get(code);
        if (null == regionName) {
            CodeName region = dao.selectAdmdvsNameAndParentName(code);
            if (null == region) {
                region = dao.selectAdmdvsName(code);
                if (null == region) {
                    region = dao.selectAdmdvsNameAndParentName(code.substring(0, 4) + "00");
                    if (null == region) {
                        region = dao.selectAdmdvsName(code.substring(0, 4) + "00");
                    }
                }
            }
            if (null == region) {
                regionName = "未知";
            } else {
                regionName = region.getCode() + region.getName();
            }
            REGION_MAP.put(code, regionName);
        }
        return regionName;
    }

    public String getWjwAnaesthesia(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        String wjwCode = WJW_ANAESTHESIA_MAP.get(code);
        if (null == wjwCode) {
            wjwCode = dao.selectWjwAnaesthesia(code);
            WJW_ANAESTHESIA_MAP.put(code, wjwCode);
        }
        return wjwCode;
    }

    public String getWjwDepartment(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        String wjwCode = WJW_DEPARTMENT_MAP.get(code);
        if (null == wjwCode) {
            wjwCode = dao.selectWjwDepartment(code);
            WJW_DEPARTMENT_MAP.put(code, wjwCode);
        }
        return wjwCode;
    }

    public String getYbDept(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        String ybCode = YB_DEPT_MAP.get(code);
        if (null == ybCode) {
            ybCode = dao.selecYbDept(code);
            YB_DEPT_MAP.put(code, ybCode);
        }
        return ybCode;
    }

    public String getCodeRs(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        String codeRs = CODE_RS_MAP.get(code);
        if (null == codeRs) {
            codeRs = dao.selectCodeRs(code);
            CODE_RS_MAP.put(code, codeRs);
        }
        return codeRs;
    }

    public String getWjwNation(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        String wjwCode = WJW_NATION_MAP.get(code);
        if (null == wjwCode) {
            wjwCode = dao.selectWjwNation(code);
            WJW_NATION_MAP.put(code, wjwCode);
        }
        return wjwCode;
    }

    /**
     * @description:获取医保联系人关系
     * @author: lihong
     * @date: 2023/2/9 15:14
     * @param: code
     * @return: java.lang.String
     **/
    public String getYbCodeContactRelation(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        String ybCode = YB_CONTACT_RELATION_MAP.get(code);
        if (null == ybCode) {
            ybCode = dao.selectYbCodeContactRelation(code);
            YB_CONTACT_RELATION_MAP.put(code, ybCode);
        }
        return ybCode;
    }

    public String getCountryName(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        String name = COUNTRY_MAP.get(code);
        if (null == name) {
            name = dao.selectCountryName(code);
            COUNTRY_MAP.put(code, name);
        }
        return name;
    }

    public String getNationName(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        String name = NATION_MAP.get(code);
        if (null == name) {
            name = dao.selectNationName(code);
            NATION_MAP.put(code, name);
        }
        return name;
    }

    public String getOccupationName(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        String name = OCCUPATION_MAP.get(code);
        if (null == name) {
            name = dao.selectOccupationName(code);
            OCCUPATION_MAP.put(code, name);
        }
        return name;
    }

    public void setUserInfo(UserInfo us) {
        redisServer.setData(RedisServer.USER_INFO(us.getCode()), us);
    }

    public Set<String> getDept(boolean needPartTimeDept, UserInfo userInfo) {
        Set<String> list = new HashSet<>();
        if (needPartTimeDept && ListUtil.notBlank(userInfo.getPartTimeDept())) {
            list.addAll(userInfo.getPartTimeDept());
        }
        list.add(userInfo.getDeptCode());
        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 dbUserInfo(String code) {
        UserInfo userInfo = dao.selectUserInfo(code);
        if (null == userInfo) {
            //说明用户被删除了
            userInfo = dao.selectUserInfoFromHis(code);
            //先删除
            dao.delNewUserToDjUserBase(userInfo.getCode());
            dao.insertNewUserToDjUserBase(userInfo);
        }
        userInfo.setDeptName(getDeptName(userInfo.getDeptCode()));
        userInfo.setRoles(dao.selectUserRoles(code));
        userInfo.setPartTimeDept(dao.selectUserPartTimeDept(userInfo.getCode()));
        Set<String> deptList = getDept(true, userInfo);
        if (!deptList.isEmpty()) {
            Map<String, String> tempMap = new HashMap<>(deptList.size());
            deptList.forEach(item -> {
                tempMap.put(item, getDeptName(item));
            });
            userInfo.setPartTimeDeptMap(tempMap);
        }
        userInfo.setHzDay(loginDao.getDeptHzDayByCode(userInfo.getDeptCode()));
        return userInfo;
    }

    /**
     * 获取用户信息，并且放入 redis
     *
     * @param code 用户 code
     */
    @DS("his")
    public UserInfo getUserInfoByCode(String code) {
        if (StringUtil.invalidValue(code)) {
            return null;
        }
        return redisServer.getData(RedisServer.USER_INFO(code), () -> dbUserInfo(code));
    }

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

    @PostConstruct
    public void initSpecialMedicalAdvice() {
        refreshSpecialMedicalAdvice();
        setIntergrationRoleMenu();
    }

    @Scheduled(cron = "0 0 0 * * ?")
    public void refreshSpecialMedicalAdvice() {
        specialMedicalAdvice.clear();
        List<YzZdOrderItemConfirm> list = yzDao.selectYzItemConfirm();
        list.forEach(item -> {
            specialMedicalAdvice.put(item.getOrderCode(), item);
        });
    }

    public void setIntergrationRoleMenu() {
        List<IntergrationPlatformRoleMenu> list = dao.selectPlatformRoleMenu();

        Map<Integer, List<IntergrationPlatformRoleMenu>> roleMap = list.stream()
                .collect(Collectors.groupingBy(IntergrationPlatformRoleMenu::getRoleId));

        redisServer.setData("IntergrationRoleMenu", roleMap);
    }

    public Map<Integer, List<IntergrationPlatformRoleMenu>> getIntergrationRoleMenu() {
        return redisServer.getData("IntergrationRoleMenu");
    }

    public void updateUserInfo(String code) {
        String key = RedisServer.USER_INFO(code);
        UserInfo us = redisServer.getData(key);
        if (us == null) {
            return;
        }
        UserInfo dbUserInfo = dbUserInfo(code);
        dbUserInfo.setSid(us.getSid());
        dbUserInfo.setToken(us.getToken());
        dbUserInfo.setAvatar(us.getAvatar());
        redisServer.setData(key, dbUserInfo);
    }

}
