package cn.stylefeng.workflow.instance.modular.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.workflow.instance.modular.business.entity.BusinessLink;
import cn.stylefeng.workflow.instance.modular.business.enums.BusinessLinkExceptionEnum;
import cn.stylefeng.workflow.instance.modular.business.mapper.BusinessLinkMapper;
import cn.stylefeng.workflow.instance.modular.business.pojo.request.BusinessLinkRequest;
import cn.stylefeng.workflow.instance.modular.business.service.BusinessLinkService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class BusinessLinkServiceImpl extends ServiceImpl<BusinessLinkMapper, BusinessLink> implements BusinessLinkService {

    @Override
    public void add(BusinessLinkRequest businessLinkRequest) {
        BusinessLink businessLink = new BusinessLink();
        BeanUtil.copyProperties(businessLinkRequest, businessLink);
        this.save(businessLink);
    }

    @Override
    public void del(BusinessLinkRequest businessLinkRequest) {
        BusinessLink businessLink = this.queryBusinessLink(businessLinkRequest);
        this.removeById(businessLink.getFlowBusinessId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDelete(BusinessLinkRequest businessLinkRequest) {
        this.removeByIds(businessLinkRequest.getBatchDeleteIdList());
    }

    @Override
    public void edit(BusinessLinkRequest businessLinkRequest) {
        BusinessLink businessLink = this.queryBusinessLink(businessLinkRequest);
        BeanUtil.copyProperties(businessLinkRequest, businessLink);
        this.updateById(businessLink);
    }

    @Override
    public BusinessLink detail(BusinessLinkRequest businessLinkRequest) {
        return this.queryBusinessLink(businessLinkRequest);
    }

    @Override
    public PageResult<BusinessLink> findPage(BusinessLinkRequest businessLinkRequest) {
        LambdaQueryWrapper<BusinessLink> wrapper = createWrapper(businessLinkRequest);
        Page<BusinessLink> pageList = this.page(PageFactory.defaultPage(), wrapper);
        return PageResultFactory.createPageResult(pageList);
    }

    @Override
    public Long getModelIdByBusinessCode(String businessCode) {
        LambdaQueryWrapper<BusinessLink> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BusinessLink::getBusinessCode, businessCode);
        queryWrapper.select(BusinessLink::getFlowModelId);
        BusinessLink businessLink = this.getOne(queryWrapper, false);
        if (businessLink != null) {
            return businessLink.getFlowModelId();
        }

        return null;
    }

    @Override
    public List<BusinessLink> findList(BusinessLinkRequest businessLinkRequest) {
        LambdaQueryWrapper<BusinessLink> wrapper = this.createWrapper(businessLinkRequest);
        return this.list(wrapper);
    }

    private BusinessLink queryBusinessLink(BusinessLinkRequest businessLinkRequest) {
        BusinessLink businessLink = this.getById(businessLinkRequest.getFlowBusinessId());
        if (ObjectUtil.isEmpty(businessLink)) {
            throw new ServiceException(BusinessLinkExceptionEnum.BUSINESS_LINK_NOT_EXISTED);
        }
        return businessLink;
    }

    private LambdaQueryWrapper<BusinessLink> createWrapper(BusinessLinkRequest businessLinkRequest) {
        LambdaQueryWrapper<BusinessLink> queryWrapper = new LambdaQueryWrapper<>();

        String searchText = businessLinkRequest.getSearchText();
        if (StrUtil.isNotBlank(searchText)) {
            queryWrapper.like(BusinessLink::getBusinessName, searchText);
            queryWrapper.or().like(BusinessLink::getBusinessCode, searchText);
        }

        queryWrapper.orderByAsc(BusinessLink::getFldSort);

        return queryWrapper;
    }

}
