package cn.stylefeng.workflow.design.modular.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseEntity;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.sys.api.SysUserServiceApi;
import cn.stylefeng.workflow.design.modular.entity.UserCommonWorkflow;
import cn.stylefeng.workflow.design.modular.enums.ModelExceptionEnum;
import cn.stylefeng.workflow.design.modular.mapper.UserCommonWorkflowMapper;
import cn.stylefeng.workflow.design.modular.pojo.request.UserCommonWorkflowRequest;
import cn.stylefeng.workflow.design.modular.service.UserCommonWorkflowService;
import cn.stylefeng.workflow.instance.api.FlowAuthServiceApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class UserCommonWorkflowServiceImpl extends ServiceImpl<UserCommonWorkflowMapper, UserCommonWorkflow> implements UserCommonWorkflowService {

    @Resource
    private SysUserServiceApi sysUserServiceApi;

    @Resource
    private FlowAuthServiceApi flowAuthServiceApi;

    @Override
    public void add(UserCommonWorkflowRequest userCommonWorkflowRequest) {

        LoginUser loginUser = LoginContext.me().getLoginUser();
        Long userId = loginUser.getUserId();

        Set<Long> userComprehensiveIdentitySummary = sysUserServiceApi.getUserComprehensiveIdentitySummary();
        if (ObjectUtil.isEmpty(userComprehensiveIdentitySummary)) {
            throw new ServiceException(ModelExceptionEnum.USER_NOT_PERMISSION);
        }
        Set<Long> userTotalFlowModelIdList = flowAuthServiceApi.getUserTotalFlowModelIdList(userComprehensiveIdentitySummary);
        if (ObjectUtil.isEmpty(userTotalFlowModelIdList) || !userTotalFlowModelIdList.contains(userCommonWorkflowRequest.getFlowModelId())) {
            throw new ServiceException(ModelExceptionEnum.USER_NOT_PERMISSION);
        }

        LambdaQueryWrapper<UserCommonWorkflow> userCommonWorkflowLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userCommonWorkflowLambdaQueryWrapper.eq(UserCommonWorkflow::getUserId, userId);
        userCommonWorkflowLambdaQueryWrapper.eq(UserCommonWorkflow::getFlowModelId, userCommonWorkflowRequest.getFlowModelId());
        UserCommonWorkflow userCommonWorkflow = this.getOne(userCommonWorkflowLambdaQueryWrapper, false);

        if (ObjectUtil.isEmpty(userCommonWorkflow)) {
            UserCommonWorkflow temp = new UserCommonWorkflow();
            temp.setUserId(userId);
            temp.setFlowModelId(userCommonWorkflowRequest.getFlowModelId());
            this.save(temp);
        } else {

            userCommonWorkflow.setCreateTime(new Date());
            this.updateById(userCommonWorkflow);
        }
    }

    @Override
    public void del(UserCommonWorkflowRequest userCommonWorkflowRequest) {

        LoginUser loginUser = LoginContext.me().getLoginUser();

        LambdaUpdateWrapper<UserCommonWorkflow> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserCommonWorkflow::getUserId, loginUser.getUserId());
        wrapper.eq(UserCommonWorkflow::getFlowModelId, userCommonWorkflowRequest.getFlowModelId());
        this.remove(wrapper);
    }

    @Override
    public List<Long> findUserAuthedCommonFlow(Set<Long> userAuthedModelIdList) {

        LambdaQueryWrapper<UserCommonWorkflow> wrapper = this.createWrapper(new UserCommonWorkflowRequest());

        wrapper.in(UserCommonWorkflow::getFlowModelId, userAuthedModelIdList);

        wrapper.select(UserCommonWorkflow::getFlowModelId);

        List<UserCommonWorkflow> list = this.list(wrapper);
        if (ObjectUtil.isEmpty(list)) {
            return new ArrayList<>();
        }

        return list.stream().map(UserCommonWorkflow::getFlowModelId).collect(Collectors.toList());
    }

    private LambdaQueryWrapper<UserCommonWorkflow> createWrapper(UserCommonWorkflowRequest userCommonWorkflowRequest) {
        LambdaQueryWrapper<UserCommonWorkflow> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.orderByDesc(BaseEntity::getCreateTime);

        LoginUser loginUser = LoginContext.me().getLoginUser();
        queryWrapper.eq(UserCommonWorkflow::getUserId, loginUser.getUserId());

        return queryWrapper;
    }

}
