package cn.qinys.platform.upms.api.service.impl;

import cn.qinys.platform.base.exceptions.BizException;
import cn.qinys.platform.base.utils.RedisUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import cn.qinys.platform.entity.upms.MarketMapDepartment;
import cn.qinys.platform.entity.upms.UpmsRoleDepartment;
import cn.qinys.platform.upms.api.mapper.MarketMapDepartmentMapper;
import cn.qinys.platform.upms.api.mapper.UpmsRoleDepartmentMapper;
import cn.qinys.platform.upms.api.req.RoleDepartmentAuthReq;
import cn.qinys.platform.upms.api.resp.DataScopeTreeResp;
import cn.qinys.platform.upms.api.service.IDataScopeService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * Description:
 *
 * @author tanlie
 * Date: 2024/6/3 9:26
 */
@Service
@Slf4j
@AllArgsConstructor
public class DataScopeServiceImpl implements IDataScopeService {

    private final MarketMapDepartmentMapper departmentMapper;
    private final UpmsRoleDepartmentMapper roleDepartmentMapper;
    private final RedisUtils redisUtils;

    @Override
    public List<DataScopeTreeResp> getTree() {
        List<MarketMapDepartment> departmentList = departmentMapper.selectList(null);
        List<MarketMapDepartment> firstLevel = new ArrayList<>();
        departmentList.forEach(department -> {
            if (department.getPid() == 0) {
                firstLevel.add(department);
            }
        });
        List<DataScopeTreeResp> resp = new ArrayList<>();
        for (MarketMapDepartment department : firstLevel) {
            DataScopeTreeResp root = new DataScopeTreeResp();
            root.setId(department.getId());
            root.setTitle(department.getName());
            root.setChildren(this.getDepartmentChildren(department.getId(), departmentList));
            resp.add(root);
        }
        return resp;
    }

    @Override
    public List<Integer> getDepartmentSelected(String roleId) {
        return roleDepartmentMapper.selectCheckedDepartment(roleId);

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createResource(RoleDepartmentAuthReq req) {
        String key = this.getClass() + ":createResource";
        String value = key + "is being used";
        if(!redisUtils.tryLock(key,value,60L)){
            throw new BizException("操作太快啦，请稍后再试");
        }
        try {
            if (req.getDepartmentIds() == null || req.getDepartmentIds().isEmpty()) {
                roleDepartmentMapper.deleteByRoleId(req.getRoleId());
                return;
            }
            for (Integer departmentId : req.getDepartmentIds()) {
                QueryWrapper<UpmsRoleDepartment> wrapper = new QueryWrapper<>();
                wrapper.eq("role_id", req.getRoleId());
                wrapper.eq("department_id", departmentId);
                wrapper.last("LIMIT 1");
                UpmsRoleDepartment exist = roleDepartmentMapper.selectOne(wrapper);
                if (exist == null) {
                    UpmsRoleDepartment department = new UpmsRoleDepartment();
                    department.setRoleId(req.getRoleId());
                    department.setDepartmentId(departmentId);
                    roleDepartmentMapper.insert(department);
                }
            }
            QueryWrapper<UpmsRoleDepartment> deleteQuery = new QueryWrapper<>();
            deleteQuery.eq("role_id", req.getRoleId());
            deleteQuery.notIn("department_id", req.getDepartmentIds());
            roleDepartmentMapper.delete(deleteQuery);
        } finally {
            redisUtils.unlock(key,value);
        }
    }

    /**
     * 支局下级
     *
     * @param parentId
     * @param departments
     * @return
     */
    private List<DataScopeTreeResp> getDepartmentChildren(Integer parentId, List<MarketMapDepartment> departments) {
        List<DataScopeTreeResp> children = new ArrayList<>();
        for (MarketMapDepartment department : departments) {
            if (parentId.equals(department.getPid())) {
                DataScopeTreeResp child = new DataScopeTreeResp();
                child.setId(department.getId());
                child.setTitle(department.getName());
                child.setChildren(this.getDepartmentChildren(child.getId(), departments));
                children.add(child);
            }
        }
        return children;
    }
}
