package com.agileboot.system.post.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.agileboot.common.core.exception.BizException;
import com.agileboot.common.core.exception.error.ErrorCode;
import com.agileboot.common.mybatis.core.page.PageR;
import com.agileboot.system.post.dto.AddPostDTO;
import com.agileboot.system.post.dto.PostQuery;
import com.agileboot.system.post.dto.PostVO;
import com.agileboot.system.post.dto.UpdatePostDTO;
import com.agileboot.system.post.entity.SysPost;
import com.agileboot.system.post.mapper.SysPostMapper;
import com.agileboot.system.post.service.ISysPostService;
import com.agileboot.system.user.service.ISysUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysPostServiceImpl extends ServiceImpl<SysPostMapper, SysPost> implements ISysPostService {

    @Resource
    private ISysUserService sysUserService;

    @Override
    public PostVO getPostInfo(Long postId) {
//        sysUserMapper.getPostInfo();
        return null;
    }

    /**
     * 条件查询
     *
     * @param query
     * @return
     */
    @Override
    public PageR<PostVO> getPostList(PostQuery query) {
        Page<SysPost> page = super.page(query.toPage(), query.toQueryWrapper());
        IPage<PostVO> convert = page.convert(PostVO::new);
        return new PageR<>(convert);
    }

    /**
     * 查询满足条件的所有岗位，不分页
     *
     * @param query 查询条件
     * @return 满足查询条件的岗位列表
     * @author Kevin Zhang
     */
    @Override
    public List<PostVO> getPostListAll(PostQuery query) {
        List<SysPost> all = super.list(query.toQueryWrapper());
        List<PostVO> records = all.stream().map(PostVO::new).collect(Collectors.toList());
        return records;
    }

    @Override
    public void addPost(AddPostDTO addDTO) {
        SysPost sysPost = new SysPost();
        BeanUtil.copyProperties(addDTO, sysPost);

        if (this.isPostNameDuplicated(null, sysPost.getPostName())) {
            throw new BizException(ErrorCode.Business.POST_NAME_IS_NOT_UNIQUE, sysPost.getPostName());
        }
        if (this.isPostCodeDuplicated(null, sysPost.getPostCode())) {
            throw new BizException(ErrorCode.Business.POST_CODE_IS_NOT_UNIQUE, sysPost.getPostCode());
        }
        super.save(sysPost);
    }

    @Override
    public void updatePost(UpdatePostDTO updateDTO) {
        Long postId = updateDTO.getPostId();
        SysPost sysPost = super.getById(postId);
        if (sysPost == null) {
            throw new BizException(ErrorCode.Business.COMMON_OBJECT_NOT_FOUND, postId, "职位");
        }
        BeanUtil.copyProperties(updateDTO, sysPost, "postId");
        if (this.isPostNameDuplicated(postId, sysPost.getPostName())) {
            throw new BizException(ErrorCode.Business.POST_NAME_IS_NOT_UNIQUE, sysPost.getPostName());
        }
        if (this.isPostCodeDuplicated(postId, sysPost.getPostCode())) {
            throw new BizException(ErrorCode.Business.POST_CODE_IS_NOT_UNIQUE, sysPost.getPostCode());
        }
        super.updateById(sysPost);
    }

    @Override
    public void deletePost(List<Long> ids) {
        // 检测职位是否分配给用户
        sysUserService.checkAnyPostIsAssignedToUser(ids);
        super.removeBatchByIds(ids);
    }

    // ---------------------------------------------------------------

    private boolean isPostNameDuplicated(Long postId, String postName) {
        LambdaQueryWrapper<SysPost> queryWrapper = Wrappers.lambdaQuery(SysPost.class)
                .ne(postId != null, SysPost::getPostId, postId)
                .eq(SysPost::getPostName, postName);
        return baseMapper.exists(queryWrapper);
    }

    private boolean isPostCodeDuplicated(Long postId, String postCode) {
        LambdaQueryWrapper<SysPost> queryWrapper = Wrappers.lambdaQuery(SysPost.class)
                .ne(postId != null, SysPost::getPostId, postId)
                .eq(SysPost::getPostCode, postCode);
        return baseMapper.exists(queryWrapper);
    }
}
