package com.yunzhupaas.permission.service.impl;

import com.yunzhupaas.base.Pagination;
import com.yunzhupaas.base.service.DictionaryDataService;
import com.yunzhupaas.base.service.SuperServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yunzhupaas.base.vo.ListVO;
import com.yunzhupaas.constant.PermissionConst;
import com.yunzhupaas.permission.entity.*;
import com.yunzhupaas.permission.model.permission.PermissionModel;
import com.yunzhupaas.permission.model.position.PaginationPosition;
import com.yunzhupaas.permission.mapper.PositionMapper;
import com.yunzhupaas.permission.service.*;
import com.yunzhupaas.util.*;
import com.yunzhupaas.util.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import org.springframework.web.bind.annotation.RequestBody;

import jakarta.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 岗位信息
 *
 * @copyright 深圳市乐程软件有限公司
 * @author 云筑产品开发平台组
 * @version V3.1.0
 * @date 2024-09-26 上午9:18
 */
@Service
public class PositionServiceImpl extends SuperServiceImpl<PositionMapper, PositionEntity> implements PositionService {

    @Autowired
    private AuthorizeService authorizeService;
    @Autowired
    private UserRelationService userRelationService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private CacheKeyUtil cacheKeyUtil;
    @Autowired
    private OrganizeRelationService organizeRelationService;
    @Autowired
    private OrganizeService organizeService;
    @Autowired
    private OrganizeAdministratorService organizeAdministratorService;
    @Autowired
    private DictionaryDataService dictionaryDataService;

    @Override
    public List<PositionEntity> getList(boolean filterEnabledMark) {
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        if (filterEnabledMark) {
            queryWrapper.lambda().eq(PositionEntity::getEnabledMark, 1);
        }
        queryWrapper.lambda().orderByAsc(PositionEntity::getSortCode).orderByDesc(PositionEntity::getCreatorTime);
        return this.list(queryWrapper);
    }

    @Override
    public List<PositionEntity> getPosList(List<String> idList) {
        if (idList.size()>0){
            QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(PositionEntity::getId,idList).select(PositionEntity::getId,PositionEntity::getFullName, PositionEntity::getEnabledMark);
            return this.list(queryWrapper);
        }
        return new ArrayList<>();
    }

    @Override
    public List<PositionEntity> getPosList(Set<String> idList) {
        if (idList.size()>0){
            QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().orderByAsc(PositionEntity::getSortCode).orderByDesc(PositionEntity::getCreatorTime);
            queryWrapper.lambda().select(PositionEntity::getId,PositionEntity::getFullName).in(PositionEntity::getId,idList);
            return this.list(queryWrapper);
        }
        return new ArrayList<>();
    }

    @Override
    public Map<String, Object> getPosMap() {
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(PositionEntity::getId,PositionEntity::getFullName);
        return this.list(queryWrapper).stream().collect(Collectors.toMap(PositionEntity::getId,PositionEntity::getFullName,(p1, p2) -> p1));
    }

    @Override
    public Map<String, Object> getPosEncodeAndName() {
        return getPosEncodeAndName(false);
    }

    @Override
    public Map<String, Object> getPosEncodeAndName(boolean enabledMark) {
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        if(enabledMark){
            queryWrapper.lambda().eq(PositionEntity::getEnabledMark,1);
        }
        queryWrapper.lambda().select(PositionEntity::getId,PositionEntity::getFullName,PositionEntity::getEnCode);
        return this.list(queryWrapper).stream().collect(Collectors.toMap(p->p.getFullName() + "/" + p.getEnCode(),PositionEntity::getId,(p1, p2) -> p1));
    }


    @Override
    public List<PositionEntity> getPosRedisList() {
        if(redisUtil.exists(cacheKeyUtil.getPositionList())){
            return JsonUtil.getJsonToList(redisUtil.getString(cacheKeyUtil.getPositionList()).toString(),PositionEntity.class);
        }
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PositionEntity::getEnabledMark,1);

        List<PositionEntity> list=this.list(queryWrapper);
        if(list.size()>0){
            redisUtil.insert(cacheKeyUtil.getPositionList(), JsonUtil.getObjectToString(list),300);
        }
        return list;
    }

    @Override
    public List<PositionEntity> getList(PaginationPosition paginationPosition) {
        // 需要查询哪些组织
        List<String> orgIds = new ArrayList<>();
        // 所有有权限的组织
        Set<String> orgId = new HashSet<>(16);
        if (!UserProvider.getUser().getIsAdministrator()) {
            // 通过权限转树
            List<OrganizeAdministratorEntity> listss = organizeAdministratorService.getOrganizeAdministratorEntity(UserProvider.getUser().getUserId());
            // 判断自己是哪些组织的管理员
            listss.forEach(t -> {
                if (t != null) {
                    if (t.getThisLayerSelect() != null && t.getThisLayerSelect() == 1) {
                        orgId.add(t.getOrganizeId());
                    }
                    if (t.getSubLayerSelect() != null && t.getSubLayerSelect() == 1) {
                        List<String> underOrganizations = organizeService.getUnderOrganizations(t.getOrganizeId(), false);
                        orgId.addAll(underOrganizations);
                    }
                }
            });
        } else {
            orgId.addAll(organizeService.getOrgMapsAll(OrganizeEntity::getId).keySet());
        }
        if (orgId.size() == 0) {
            return new ArrayList<>();
        }
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtil.isNotEmpty(paginationPosition.getKeyword())) {
            queryWrapper.lambda().and(
                    t -> t.like(PositionEntity::getFullName, paginationPosition.getKeyword())
                            .or().like(PositionEntity::getEnCode, paginationPosition.getKeyword())
            );
        }
        if (paginationPosition.getEnabledMark() != null) {
            queryWrapper.lambda().eq(PositionEntity::getEnabledMark, paginationPosition.getEnabledMark());
        }
        if (StringUtil.isNotEmpty(paginationPosition.getEnCode())) {
            queryWrapper.lambda().eq(PositionEntity::getType, paginationPosition.getEnCode());
        }
        if (StringUtil.isNotEmpty(paginationPosition.getOrganizeId())) {
            List<String> underOrganizations = organizeService.getUnderOrganizations(paginationPosition.getOrganizeId(), false);
            // 判断哪些组织时有权限的
            List<String> collect = underOrganizations.stream().filter(orgId::contains).collect(Collectors.toList());
            orgIds.add(paginationPosition.getOrganizeId());
            orgIds.addAll(collect);
            orgIds.add(paginationPosition.getOrganizeId());
            queryWrapper.lambda().in(PositionEntity::getOrganizeId, orgIds);
        } else {
            queryWrapper.lambda().in(PositionEntity::getOrganizeId, orgId);
        }
        long count = this.count(queryWrapper);
        queryWrapper.lambda().select(PositionEntity::getId, PositionEntity::getEnCode, PositionEntity::getCreatorTime,
                PositionEntity::getOrganizeId, PositionEntity::getEnabledMark, PositionEntity::getFullName,
                PositionEntity::getSortCode, PositionEntity::getType, PositionEntity::getDescription);
        queryWrapper.lambda().orderByAsc(PositionEntity::getSortCode).orderByDesc(PositionEntity::getCreatorTime);

        if(Objects.equals(paginationPosition.getDataType(),1)){
            return list(queryWrapper);
        }
        Page<PositionEntity> page = new Page<>(paginationPosition.getCurrentPage(), paginationPosition.getPageSize(), count, false);
        page.setOptimizeCountSql(false);
        IPage<PositionEntity> iPage = this.page(page, queryWrapper);
        return paginationPosition.setData(iPage.getRecords(), page.getTotal());
    }

    @Override
    public List<PositionEntity> getListByUserId(String userId) {
        QueryWrapper<PositionEntity> query = new QueryWrapper<>();
        List<String> ids = new ArrayList<>();
        userRelationService.getListByObjectType(userId, PermissionConst.POSITION).forEach(r->{
            ids.add(r.getObjectId());
        });
        if(ids.size() > 0){
            query.lambda().in(PositionEntity::getId, ids);
            return this.list(query);
        }else {
            return new ArrayList<>();
        }
    }

    @Override
    public PositionEntity getInfo(String id) {
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PositionEntity::getId,id);
        return this.getOne(queryWrapper);
    }

    @Override
    public PositionEntity getByFullName(String fullName) {
        PositionEntity positionEntity = new PositionEntity();
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PositionEntity::getFullName, fullName);
        queryWrapper.lambda().select(PositionEntity::getId);
        List<PositionEntity> list = this.list(queryWrapper);
        if (list.size() > 0) {
            positionEntity = list.get(0);
        }
        return positionEntity;
    }

    @Override
    public PositionEntity getByFullName(String fullName,String encode) {
        PositionEntity positionEntity = new PositionEntity();
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PositionEntity::getFullName, fullName);
        queryWrapper.lambda().eq(PositionEntity::getEnCode, encode);
        queryWrapper.lambda().select(PositionEntity::getId);
        List<PositionEntity> list = this.list(queryWrapper);
        if (list.size() > 0) {
            positionEntity = list.get(0);
        }
        return positionEntity;
    }

    @Override
    public boolean isExistByFullName(PositionEntity entity, boolean isFilter) {
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        if(entity != null) {
            queryWrapper.lambda().eq(PositionEntity::getFullName, entity.getFullName());
        }
        //是否需要过滤
        if (isFilter) {
            queryWrapper.lambda().ne(PositionEntity::getId, entity.getId());
        }
        List<PositionEntity> entityList = this.list(queryWrapper);
        for (PositionEntity positionEntity : entityList) {
            //如果组织id相同则代表已存在
            if (entity != null && entity.getOrganizeId().equals(positionEntity.getOrganizeId())){
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean isExistByEnCode(PositionEntity entity, boolean isFilter) {
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        if(entity != null){
            queryWrapper.lambda().eq(PositionEntity::getEnCode, entity.getEnCode());
            if (isFilter) {
                queryWrapper.lambda().ne(PositionEntity::getId, entity.getId());
            }
        }
        List<PositionEntity> entityList = this.list(queryWrapper);
//        for (PositionEntity positionEntity : entityList) {
//            //如果组织id相同则代表已存在
//            if (entity != null && entity.getOrganizeId().equals(positionEntity.getOrganizeId())){
//                return true;
//            }
//        }
        return entityList.size() > 0;
    }

    @Override
    public void create(PositionEntity entity) {
        if (StringUtil.isEmpty(entity.getId())) {
            entity.setId(RandomUtil.uuId());
        }
        entity.setCreatorUserId(UserProvider.getUser().getUserId());
        this.save(entity);
    }

    @Override
    public boolean update(String id, PositionEntity entity) {
        entity.setId(id);
        entity.setLastModifyTime(new Date());
        entity.setLastModifyUserId(UserProvider.getUser().getUserId());
        return this.updateById(entity);
    }

    @Override
    @DSTransactional
    public void delete(PositionEntity entity) {
        this.removeById(entity.getId());
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getObjectId,entity.getId());
        userRelationService.remove(queryWrapper);
        QueryWrapper<AuthorizeEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(AuthorizeEntity::getObjectId,entity.getId());
        authorizeService.remove(wrapper);
    }

    @Override
    @DSTransactional
    public boolean first(String id) {
        boolean isOk = false;
        //获取要上移的那条数据的信息
        PositionEntity upEntity = this.getById(id);
        Long upSortCode = upEntity.getSortCode() == null ? 0 : upEntity.getSortCode();
        //查询上几条记录
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .lt(PositionEntity::getSortCode, upSortCode)
                .eq(PositionEntity::getOrganizeId,upEntity.getOrganizeId())
                .orderByDesc(PositionEntity::getSortCode);
        List<PositionEntity> downEntity = this.list(queryWrapper);
        if(downEntity.size()>0){
            //交换两条记录的sort值
            Long temp = upEntity.getSortCode();
            upEntity.setSortCode(downEntity.get(0).getSortCode());
            downEntity.get(0).setSortCode(temp);
            this.updateById(downEntity.get(0));
            this.updateById(upEntity);
            isOk = true;
        }
        return isOk;
    }

    @Override
    @DSTransactional
    public boolean next(String id) {
        boolean isOk = false;
        //获取要下移的那条数据的信息
        PositionEntity downEntity = this.getById(id);
        Long upSortCode = downEntity.getSortCode() == null ? 0 : downEntity.getSortCode();
        //查询下几条记录
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .gt(PositionEntity::getSortCode, upSortCode)
                .eq(PositionEntity::getOrganizeId,downEntity.getOrganizeId())
                .orderByAsc(PositionEntity::getSortCode);
        List<PositionEntity> upEntity = this.list(queryWrapper);
        if(upEntity.size()>0){
            //交换两条记录的sort值
            Long temp = downEntity.getSortCode();
            downEntity.setSortCode(upEntity.get(0).getSortCode());
            upEntity.get(0).setSortCode(temp);
            this.updateById(upEntity.get(0));
            this.updateById(downEntity);
            isOk = true;
        }
        return isOk;
    }

    @Override
    public List<PositionEntity> getPositionName(List<String> id, boolean filterEnabledMark) {
        List<PositionEntity> roleList = new ArrayList<>();
        if (id.size() > 0) {
            QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(PositionEntity::getId, id);
            roleList = this.list(queryWrapper);
        }
        return roleList;
    }

    @Override
    public List<PositionEntity> getPositionName(List<String> id, String keyword) {
        List<PositionEntity> roleList = new ArrayList<>();
        if (id.size() > 0) {
            QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(PositionEntity::getId, id);
            //关键字（名称、编码）
            if (!StringUtil.isEmpty(keyword)) {
                queryWrapper.lambda().and(
                        t->t.like(PositionEntity::getFullName,keyword)
                                .or().like(PositionEntity::getEnCode,keyword)
                );
            }
            roleList = this.list(queryWrapper);
        }
        return roleList;
    }

    @Override
    public List<PositionEntity> getListByOrganizeId(List<String> organizeIds, boolean enabledMark) {
        if (organizeIds.size() == 0) {
            return new ArrayList<>();
        }
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(PositionEntity::getOrganizeId, organizeIds);
        if (enabledMark) {
            queryWrapper.lambda().eq(PositionEntity::getEnabledMark, 1);
        }
        queryWrapper.lambda().orderByAsc(PositionEntity::getSortCode).orderByDesc(PositionEntity::getCreatorTime);
//        queryWrapper.lambda().select(PositionEntity::getId, PositionEntity::getFullName);
        return this.list(queryWrapper);
    }

    @Override
    public List<PositionEntity> getListByOrgIdAndUserId(String organizeId, String userId) {
        // 用户绑定的所有岗位
        List<String> positionIds = userRelationService.getListByUserIdAndObjType(userId, PermissionConst.POSITION).stream()
                .map(UserRelationEntity::getObjectId).collect(Collectors.toList());
        if(positionIds.size() > 0){
            List<PositionEntity> positionEntities = this.listByIds(positionIds);
            return positionEntities.stream().filter(p-> p.getOrganizeId().equals(organizeId)).collect(Collectors.toList());
        }else {
            return new ArrayList<>();
        }
    }

    @Override
    public List<PositionEntity> getListByFullName(String fullName, String enCode) {
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PositionEntity::getFullName, fullName).eq(PositionEntity::getEnCode, enCode);
        return this.list(queryWrapper);
    }

    @Override
    public List<PositionEntity> getCurPositionsByOrgId(String orgId) {
        String userId = UserProvider.getUser().getUserId();
        List<UserRelationEntity> userRelations = userRelationService.getListByObjectType(userId, PermissionConst.POSITION);
        List<PositionEntity> positions = new ArrayList<>();
        userRelations.forEach(ur->{
            PositionEntity entity = this.getInfo(ur.getObjectId());
            if(entity.getOrganizeId().equals(orgId)){
                positions.add(entity);
            }
        });
        return positions;
    }

    @Override
    public List<PositionEntity> getList(List<String> idList, Pagination pagination, boolean isPage) {
        if (idList.size() > 0) {
            QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(PositionEntity::getId, idList);
            queryWrapper.lambda().eq(PositionEntity::getEnabledMark, 1);
            if (StringUtil.isNotEmpty(pagination.getKeyword())) {
                queryWrapper.lambda().and(
                        t -> t.like(PositionEntity::getFullName, pagination.getKeyword())
                                .or().like(PositionEntity::getEnCode, pagination.getKeyword())
                );
            }
            if(isPage) {
                Page<PositionEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
                IPage<PositionEntity> iPage = this.page(page, queryWrapper);
                return pagination.setData(iPage.getRecords(), iPage.getTotal());
            }else {
                return list(queryWrapper);
            }
        }
        return Collections.emptyList();
    }

    @Override
    public List<PermissionModel> getListByOrganizeIds(List<String> organizeIds, boolean needCode, boolean enabledMark) {
        List<PermissionModel> permissionList = new LinkedList<>();
        for (String organizeId : organizeIds) {
            OrganizeEntity info = organizeService.getInfo(organizeId);
            if (info != null) {
                PermissionModel parentModel = new PermissionModel();
                List<PositionEntity> list = this.getListByOrganizeId(Collections.singletonList(organizeId), enabledMark);
                list.stream().forEach(t->{
                    if(needCode){
                        t.setFullName(t.getFullName()+"/"+t.getEnCode());
                    }
                });
                List<PermissionModel> positionModels = JsonUtil.getJsonToList(list, PermissionModel.class);
                parentModel.setChildren(positionModels);
                parentModel.setHasChildren(true);
                parentModel.setFullName(info.getFullName());
                parentModel.setId(info.getId());
                permissionList.add(parentModel);
            }
        }
        return permissionList;
    }
}

