package com.xjrsoft.module.system.service.impl;


import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.enums.EnabledMark;
import com.xjrsoft.common.enums.StampEnum;
import com.xjrsoft.common.enums.YesOrNoEnum;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.organization.entity.User;
import com.xjrsoft.module.organization.mapper.UserMapper;
import com.xjrsoft.module.system.dto.AddMemberDto;
import com.xjrsoft.module.system.dto.UpdateStampDto;
import com.xjrsoft.module.system.entity.Stamp;
import com.xjrsoft.module.system.mapper.StampMapper;
import com.xjrsoft.module.system.service.IStampService;
import com.xjrsoft.module.system.vo.StampMemberVo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

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

/**
 * <p>
 * 印章表 服务实现类
 * </p>
 *
 * @author zjq
 * @since 2022-10-24
 */
@Service
@AllArgsConstructor
public class StampServiceImpl extends MPJBaseServiceImpl<StampMapper, Stamp> implements IStampService {


    private final UserMapper userMapper;


    @Override
    public List<StampMemberVo> selectMember(Long id) {
        Stamp stamp = getById(id);
        if (ObjectUtil.isNull(stamp)) {
            throw new MyException("找不到当前签章！");
        }
        List<StampMemberVo> vo = new ArrayList<>();
        if (StrUtil.isNotBlank(stamp.getMember())) {
            List<Long> userIds = Arrays.stream(stamp.getMember().split(StringPool.COMMA)).map(Convert::toLong).collect(Collectors.toList());
            LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>query().lambda()
                    .in(User::getId, userIds)
                    .select(User.class, x -> VoToColumnUtil.fieldsToColumns(StampMemberVo.class).contains(x.getProperty()));
            List<User> users = userMapper.selectList(queryWrapper);
            vo = BeanUtil.copyToList(users, StampMemberVo.class);
        }
        return vo;
    }

    @Override
    public boolean addMember(AddMemberDto dto) {
        Stamp stamp = getById(dto.getId());

        if (ObjectUtil.isNull(stamp)) {
            throw new MyException("找不到当前签章！");
        }

        stamp.setMember(StrUtil.join(StringPool.COMMA, dto.getUserIds()));
        return updateById(stamp);
    }

    @Override
    public List<StampMemberVo> selectMaintain(Long id) {
        Stamp stamp = this.getById(id);

        if (ObjectUtil.isNull(stamp)) {
            throw new MyException("找不到当前签章！");
        }
        List<StampMemberVo> vo = new ArrayList<>();

        if (StrUtil.isNotBlank(stamp.getMaintain())) {
            List<String> userIds = ListUtil.toList(stamp.getMaintain().split(StringPool.COMMA));
            LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>query().lambda()
                    .in(User::getId, userIds)
                    .select(User.class, x -> VoToColumnUtil.fieldsToColumns(StampMemberVo.class).contains(x.getProperty()));
            List<User> users = userMapper.selectList(queryWrapper);
            vo = BeanUtil.copyToList(users, StampMemberVo.class);
        }

        return vo;
    }

    @Override
    public boolean addMaintain(AddMemberDto dto) {
        Stamp stamp = getById(dto.getId());
        if (ObjectUtil.isNull(stamp)) {
            throw new MyException("找不到当前签章！");
        }
        stamp.setMaintain(StrUtil.join(StringPool.COMMA, dto.getUserIds()));
        return updateById(stamp);
    }

    @Override
    public boolean updateStamp(UpdateStampDto dto) {

        Stamp stamp = getById(dto.getId());
        if (ObjectUtil.isNull(stamp)) {
            throw new MyException("找不到当前签章！");
        }

        //如果是私人签章  直接更新  如果是公共签章 需要判断是否为管理员 或者超级管理员
        List<Long> roleIds = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_ROLE_ID_KEY, new ArrayList<>());

        if (stamp.getStampType() == StampEnum.PRIVATE.getCode()
                || (StrUtil.isNotBlank(stamp.getMaintain()) && stamp.getMaintain().contains(StpUtil.getLoginIdAsString()))
                || roleIds.contains(GlobalConstant.SUPER_ADMIN_ROLE_ID)
        ) {
            Stamp updateStamp = BeanUtil.toBean(dto, Stamp.class);
            updateById(updateStamp);
        } else {
            throw new MyException("非签章管理员账号不能操作公共签章");
        }

        return true;
    }

    @Override
    public boolean deleteStamp(List<Long> ids) {
        List<Stamp> stamps = listByIds(ids);
        List<Long> roleIds = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_ROLE_ID_KEY, new ArrayList<>());
        for (Stamp stamp : stamps) {
            //如果是私人签章  直接删除  如果是公共签章 需要判断是否为管理员
            if (
                    (stamp.getStampType() != StampEnum.PRIVATE.getCode() &&
                            (StrUtil.isNotBlank(stamp.getMaintain()) && !stamp.getMaintain().contains(StpUtil.getLoginIdAsString())))
                            && !roleIds.contains(GlobalConstant.SUPER_ADMIN_ROLE_ID)

            ) {
                throw new MyException("非签章管理员账号不能操作公共签章");
            }
        }

        removeBatchByIds(ids);
        return true;
    }

    @Override
    public boolean enabled(Long id) {
        Stamp stamp = getById(id);

        if (ObjectUtil.isNull(stamp)) {
            throw new MyException("找不到当前签章！");
        }

        //如果是私人签章  直接更新  如果是公共签章 需要判断是否为管理员
        List<Long> roleIds = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_ROLE_ID_KEY, new ArrayList<>());
        if (
                stamp.getStampType() == StampEnum.PRIVATE.getCode()
                        ||
                        ((StrUtil.isNotBlank(stamp.getMaintain()) && !stamp.getMaintain().contains(StpUtil.getLoginIdAsString())))
                        || roleIds.contains(GlobalConstant.SUPER_ADMIN_ROLE_ID)
        ) {
            Stamp updateStamp = new Stamp();
            updateStamp.setId(id);
            if (stamp.getEnabledMark() == EnabledMark.ENABLED.getCode()) {
                updateStamp.setEnabledMark(EnabledMark.DISABLED.getCode());
            } else {
                updateStamp.setEnabledMark(EnabledMark.ENABLED.getCode());
            }
            updateById(updateStamp);
        } else {
            throw new MyException("非管理员账号不能操作公共签章");
        }
        return true;
    }


    @Override
    public boolean setDefaultStamp(Long id) {
        Stamp stamp = getById(id);
        if (ObjectUtil.isNull(stamp)) {
            throw new MyException("找不到当前签章！");
        }
        if (stamp.getIsDefault() == YesOrNoEnum.YES.getCode()) {
            throw new MyException("当前签章就是默认签章！");
        }

        if (stamp.getStampType() == StampEnum.PRIVATE.getCode()) {
            //先将原有默认 修改为 非默认
            Stamp updateStamp = new Stamp();
            updateStamp.setIsDefault(YesOrNoEnum.NO.getCode());
            update(updateStamp, Wrappers.lambdaQuery(Stamp.class).eq(Stamp::getIsDefault, YesOrNoEnum.YES.getCode()));

            stamp.setIsDefault(YesOrNoEnum.YES.getCode());
            updateById(stamp);
        } else {
            throw new MyException("当前操作不能操作公共签章！");
        }
        return true;
    }


}
