package com.casic.missiles.modular.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.casic.missiles.core.application.service.AbstractDeptService;
import com.casic.missiles.core.application.service.AbstractTenantService;
import com.casic.missiles.modular.system.dao.TenantDeptMapper;
import com.casic.missiles.modular.system.dto.TenantDTO;
import com.casic.missiles.modular.system.model.Tenant;
import com.casic.missiles.modular.system.model.TenantDept;
import com.casic.missiles.modular.system.service.ITenantDeptService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lwh123
 * @since 2022-06-07
 */
@Service
public class TenantDeptServiceImpl extends ServiceImpl<TenantDeptMapper, TenantDept> implements ITenantDeptService {
    @Resource
    private AbstractTenantService abstractTenantService;
    @Resource
    private AbstractDeptService abstractDeptService;

    @Override
    public List<TenantDTO> tenantList(QueryWrapper<Tenant> query, Long deptId) {
        Map<String, String> deptMap = getDeptList();
        Map<String, String> tenantDeptMap = getTenantDeptList();
        List<Tenant> tenants = abstractTenantService.list(query);
        if(deptId==0){
            return tenants.stream().map(tenant -> appendDeptInfo(tenant, tenantDeptMap)).collect(Collectors.toList());
        }
        List<TenantDTO> dtos = tenants.stream().filter(
                tenant -> filterByDept(tenant, tenantDeptMap, deptId, deptMap)
        ).map(tenant -> appendDeptInfo(tenant, tenantDeptMap)).collect(Collectors.toList());
        return dtos;
    }

    @Override
    public void relateTenant(TenantDept tenantDept) {
        QueryWrapper<TenantDept> dtoQuery = new QueryWrapper<>();
        dtoQuery.eq("tenant_id", tenantDept.getTenantId());
        this.remove(dtoQuery);
        this.save(tenantDept);
    }

    /**
     *   获取部门和pid的map
     * @return
     */
    private Map<String, String> getDeptList() {
        List<Map<String, Object>> deptMapList = this.baseMapper.getDeptList();
        Map<String, String> deptMap = deptMapList.stream()
                .collect(Collectors.toMap(e -> String.valueOf(e.get("id")), e -> String.valueOf(e.get("pid"))));
        return deptMap;
    }

    /**
     *   获取tenant、Deptid的map
     * @return
     */
    private Map<String, String> getTenantDeptList() {
        List<Map<String, Object>> tenantDeptList = this.baseMapper.getTenantDeptList();
        Map<String, String> tenantDeptMap = tenantDeptList.stream()
                .collect(Collectors.toMap(e -> String.valueOf(e.get("tentantId")), e -> String.valueOf(e.get("deptId"))));
        return tenantDeptMap;
    }

    /**
     *  根据部门过滤tenant
     * @param tenant
     * @param tenantDeptMap
     * @param deptId
     * @param deptMap
     * @return
     */
    private Boolean filterByDept(Tenant tenant, Map<String, String> tenantDeptMap, Long deptId, Map<String, String> deptMap) {
        Boolean flag = false;
        String tempDeptId = tenantDeptMap.get(String.valueOf(tenant.getId()));
        while (!StringUtils.isEmpty(tempDeptId)&&!tempDeptId.equals("-1")) {
            if (tempDeptId.equals(String.valueOf(deptId))) {
                flag = true;
                break;
            }
            tempDeptId = deptMap.get(tempDeptId);
        }
        return flag;
    }

    /**
     *  增加部门信息
     * @param tenant
     * @param tenantDeptMap
     * @return
     */
    private TenantDTO appendDeptInfo(Tenant tenant, Map<String, String> tenantDeptMap) {
        TenantDTO dto = new TenantDTO();
        BeanUtils.copyProperties(tenant, dto);
        if (tenantDeptMap.containsKey(String.valueOf(dto.getId()))) {
            dto.setDeptId(Long.valueOf(tenantDeptMap.get(String.valueOf(dto.getId()))));
            dto.setDeptName(abstractDeptService.getDeptName(dto.getDeptId()));
        }
        return dto;
    }
}
