package com.yonge.cooleshow.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.yonge.cooleshow.admin.dao.UmsAdminRoleRelationDao;
import com.yonge.cooleshow.admin.service.UmsAdminCacheService;
import com.yonge.cooleshow.admin.service.UmsAdminService;
import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
import com.yonge.cooleshow.auth.api.entity.SysUser;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.cooleshow.mall.common.util.RequestUtil;
import com.yonge.cooleshow.mbg.mapper.SysConfigMapper;
import com.yonge.cooleshow.mbg.mapper.UmsAdminLoginLogMapper;
import com.yonge.cooleshow.mbg.mapper.UmsAdminMapper;
import com.yonge.cooleshow.mbg.mapper.UmsAdminRoleRelationMapper;
import com.yonge.cooleshow.mbg.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 后台用户管理Service实现类
 * Created by macro on 2018/4/26.
 */
@Service
public class UmsAdminServiceImpl implements UmsAdminService {
    private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminServiceImpl.class);
    @Autowired
    private SysUserFeignService sysUserFeignService;
    @Autowired
    private UmsAdminMapper adminMapper;
    @Autowired
    private UmsAdminRoleRelationMapper adminRoleRelationMapper;
    @Autowired
    private UmsAdminRoleRelationDao adminRoleRelationDao;
    @Autowired
    private UmsAdminLoginLogMapper loginLogMapper;
    @Autowired
    private UmsAdminCacheService adminCacheService;

    @Autowired
    private SysConfigMapper configMapper;

    @Override
    public UmsAdmin getAdminByUsername(String username) {
        UmsAdmin admin = adminCacheService.getAdmin(username);
        if(admin!=null) return  admin;
        UmsAdminExample example = new UmsAdminExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<UmsAdmin> adminList = adminMapper.selectByExample(example);
        if (adminList != null && adminList.size() > 0) {
            admin = adminList.get(0);
            adminCacheService.setAdmin(admin);
            return admin;
        }
        return null;
    }


    /**
     * 添加登录记录
     * @param username 用户名
     */
    private void insertLoginLog(String username) {
        UmsAdmin admin = getAdminByUsername(username);
        if(admin==null) return;
        UmsAdminLoginLog loginLog = new UmsAdminLoginLog();
        loginLog.setAdminId(admin.getId());
        loginLog.setCreateTime(new Date());
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        loginLog.setIp(RequestUtil.getRequestIp(request));
        loginLogMapper.insert(loginLog);
    }

    /**
     * 根据用户名修改登录时间
     */
    private void updateLoginTimeByUsername(String username) {
        UmsAdmin record = new UmsAdmin();
        record.setLoginTime(new Date());
        UmsAdminExample example = new UmsAdminExample();
        example.createCriteria().andUsernameEqualTo(username);
        adminMapper.updateByExampleSelective(record, example);
    }


    @Override
    public UmsAdmin getItem(Long id) {
        return adminMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<UmsAdmin> list(String keyword, Integer pageSize, Integer pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        UmsAdminExample example = new UmsAdminExample();
        UmsAdminExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(keyword)) {
            criteria.andUsernameLike("%" + keyword + "%");
            example.or(example.createCriteria().andNickNameLike("%" + keyword + "%"));
        }
        return adminMapper.selectByExample(example);
    }

    @Override
    public int update(Long id, UmsAdmin admin) {
        admin.setId(id);
        UmsAdmin rawAdmin = adminMapper.selectByPrimaryKey(id);
        if(rawAdmin.getPassword().equals(admin.getPassword())){
            //与原加密密码相同的不需要修改
            admin.setPassword(null);
        }else{
            //与原加密密码不同的需要加密修改
            if(StrUtil.isEmpty(admin.getPassword())){
                admin.setPassword(null);
            }else{
                admin.setPassword(null);
            }
        }
        int count = adminMapper.updateByPrimaryKeySelective(admin);
        adminCacheService.delAdmin(id);
        return count;
    }

    @Override
    public int delete(Long id) {
        adminCacheService.delAdmin(id);
        int count = adminMapper.deleteByPrimaryKey(id);
        adminCacheService.delResourceList(id);
        return count;
    }

    @Override
    public int updateRole(Long adminId, List<Long> roleIds) {
        int count = roleIds == null ? 0 : roleIds.size();
        //先删除原来的关系
        UmsAdminRoleRelationExample adminRoleRelationExample = new UmsAdminRoleRelationExample();
        adminRoleRelationExample.createCriteria().andAdminIdEqualTo(adminId);
        adminRoleRelationMapper.deleteByExample(adminRoleRelationExample);
        //建立新关系
        if (!CollectionUtils.isEmpty(roleIds)) {
            List<UmsAdminRoleRelation> list = new ArrayList<>();
            for (Long roleId : roleIds) {
                UmsAdminRoleRelation roleRelation = new UmsAdminRoleRelation();
                roleRelation.setAdminId(adminId);
                roleRelation.setRoleId(roleId);
                list.add(roleRelation);
            }
            adminRoleRelationDao.insertList(list);
        }
        adminCacheService.delResourceList(adminId);
        return count;
    }

    @Override
    public List<UmsRole> getRoleList(Long adminId) {
        return adminRoleRelationDao.getRoleList(adminId);
    }

    @Override
    public List<UmsResource> getResourceList(Long adminId) {
        List<UmsResource> resourceList = adminCacheService.getResourceList(adminId);
        if(CollUtil.isNotEmpty(resourceList)){
            return  resourceList;
        }
        resourceList = adminRoleRelationDao.getResourceList(adminId);
        if(CollUtil.isNotEmpty(resourceList)){
            adminCacheService.setResourceList(adminId,resourceList);
        }
        return resourceList;
    }



    @Override
    public UmsAdmin getAdminById(Long id) {
        return adminMapper.selectByPrimaryKey(id);
    }

    @Override
    public boolean createRootAdmin(UmsAdmin admin) {
        adminMapper.addRootAdmin(admin);
        List<Long> roleIds = new ArrayList<>();
        roleIds.add(1L);
        return updateRole(admin.getId(),roleIds) > 0;
    }

    @Override
    public boolean addRootAdmin(List<UmsAdmin> adminList) {

        if (CollUtil.isEmpty(adminList)) {
            return true;
        }
        adminMapper.saveRootAdminList(adminList);
        return addAdminRootRole(adminList);
    }

    @Override
    public void saveAdmin() {
        // 调用远程，保存用户
        SysUserQueryInfo sysUserQueryInfo = new SysUserQueryInfo();
        String now = LocalDateTimeUtil.format(LocalDateTime.now(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String syncTime = configMapper.getConfig(SysConfig.SYNC_TIME);
        sysUserQueryInfo.setCreateEndDate(now);
        sysUserQueryInfo.setCreateStartDate(syncTime);
        HttpResponseResult<List<SysUser>> result = sysUserFeignService.page(sysUserQueryInfo);
        if (result.getStatus()) {
            List<SysUser> rows = result.getData();
            List<UmsAdmin> adminList = new ArrayList<>();
            for (SysUser row : rows) {
                UmsAdmin admin = getUmsAdmin(row);
                adminList.add(admin);
            }
            addRootAdmin(adminList);
        }
        configMapper.setConfig(SysConfig.SYNC_TIME,now);
    }

    @Override
    public void updateInfo(Long umsAdminId, SysUser sysUser) {
        UmsAdmin umsAdmin = getUmsAdmin(sysUser);
        adminMapper.updateByPrimaryKeySelective(umsAdmin);
    }

    private UmsAdmin getUmsAdmin(SysUser row) {
        UmsAdmin admin = new UmsAdmin();
        admin.setId(row.getId());
        admin.setCreateTime(row.getCreateTime());
        admin.setUsername(row.getUsername());
        admin.setNickName(row.getUsername());
        admin.setPassword(row.getPassword());
        admin.setStatus(1);
        admin.setIcon(row.getAvatar());
        return admin;
    }

    /**
     * 添加默认权限
     *
     * @param adminList
     */
    private boolean addAdminRootRole(List<UmsAdmin> adminList) {
        List<Long> adminIdList = adminList.stream().map(UmsAdmin::getId).collect(Collectors.toList());

        // 已经设置里权限的不做处理
        UmsAdminRoleRelationExample adminRoleRelationExample = new UmsAdminRoleRelationExample();
        adminRoleRelationExample.createCriteria().andAdminIdIn(adminIdList);
        List<UmsAdminRoleRelation> umsAdminRoleRelations = adminRoleRelationMapper.selectByExample(
                adminRoleRelationExample);
        Set<Long> hasRoleAdminIdList = new HashSet<>();
        if (CollUtil.isNotEmpty(umsAdminRoleRelations)) {
            hasRoleAdminIdList = umsAdminRoleRelations.stream()
                                                     .map(UmsAdminRoleRelation::getAdminId)
                                                     .collect(Collectors.toSet());
        }
        Set<Long> finalHasRoleAdminIdList = hasRoleAdminIdList;
        adminIdList = adminIdList.stream()
                                 .filter(id -> !finalHasRoleAdminIdList.contains(id))
                                 .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(adminIdList)) {
            return true;
        }
        // 设置权限
        List<UmsAdminRoleRelation> list = new ArrayList<>();
        for (Long adminId : adminIdList) {
            UmsAdminRoleRelation roleRelation = new UmsAdminRoleRelation();
            roleRelation.setAdminId(adminId);
            roleRelation.setRoleId(1L);
            list.add(roleRelation);
        }
        return adminRoleRelationDao.insertList(list) > 0;

    }
}
