package cn.iocoder.yudao.module.order.service.approval;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.bpm.api.BpmCreateServiceFactory;
import cn.iocoder.yudao.module.bpm.enums.WorkFlowEmus;
import cn.iocoder.yudao.module.bpm.resp.TaskResp;
import cn.iocoder.yudao.module.order.convert.approval.OrderApprovalConvert;
import cn.iocoder.yudao.module.order.dal.dataobject.approval.OrderApprovalDO;
import cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.order.dal.mysql.approval.OrderApprovalMapper;
import cn.iocoder.yudao.module.order.dal.mysql.order.OrderMapper;
import cn.iocoder.yudao.module.order.enums.ApprovalResultStatusEnum;
import cn.iocoder.yudao.module.order.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.order.enums.OrderApprovalTypeEnum;
import cn.iocoder.yudao.module.order.vo.approval.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.order.enums.ErrorCodeConstants.APPROVAL_NOT_EXISTS;

/**
 * 订单审核 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class OrderApprovalServiceImpl extends AbstractService<OrderApprovalMapper, OrderApprovalDO> implements OrderApprovalService {

    @Autowired
    private OrderApprovalMapper approvalMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Resource
    private BpmCreateServiceFactory bpmCreateServiceFactory;


    @Override
    public Long applyAndCreate(OrderApprovalDO orderApprovalDO, WorkFlowEmus workFlowEmus, String[] copyUserId) {
        orderApprovalDO.setStatus(ApprovalResultStatusEnum.processing.getValue());

        approvalMapper.insert(orderApprovalDO);

        //查询编号
        String orderNo = null;
        try {
            OrderDO orderDO = orderMapper.selectById(orderApprovalDO.getOrderId());
            orderNo = orderDO.getOrderNo();
        } catch (Exception e) {
        }
        //发起流程
        String formId = bpmCreateServiceFactory.createBmp(SecurityFrameworkUtils.getLoginUserId(),
                orderApprovalDO.getOrderApprovalId(), workFlowEmus.getKey(), orderNo, copyUserId);

        orderApprovalDO.setFormId(formId);
        approvalMapper.updateById(orderApprovalDO);

        return orderApprovalDO.getOrderApprovalId();
    }

    @Override
    public void callbackUpdate(OrderApprovalDO orderApprovalDO, String formId, Integer result) {
        if (orderApprovalDO == null) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.APPROVAL_NOT_EXISTS);
        }

        if (ApprovalResultStatusEnum.processing.getValue().equals(result)) {
            //do nothing
        } else {
            //设置状态
            orderApprovalDO.setStatus(result);

            TaskResp taskResp = bpmCreateServiceFactory.getLastTaskByProcessInstanceId(formId);
            if (taskResp != null) {
                if (taskResp.getAssigneeUser() != null) {
                    orderApprovalDO.setFinishBy(taskResp.getAssigneeUser().getId().toString());
                }
                //设置结束时间
                orderApprovalDO.setFinishTime(taskResp.getEndTime() == null ? taskResp.getEndTime() : new Date());
                //设置原因
                orderApprovalDO.setProcessingResults(taskResp.getComment());
            }
            approvalMapper.updateById(orderApprovalDO);
        }
    }

    @Override
    public void cancelApplyAndUpdate(OrderApprovalDO orderApprovalDO, String reason) {
        if (orderApprovalDO == null) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.ORDER_APPROVAL_INFO_NOT_FIND);
        }

        bpmCreateServiceFactory.cancelBmpById(SecurityFrameworkUtils.getLoginUserId(), orderApprovalDO.getFormId(), reason);

        //更新状态
        orderApprovalDO.setStatus(ApprovalResultStatusEnum.cancel.getValue());
        approvalMapper.updateById(orderApprovalDO);
    }

    @Override
    public OrderApprovalDO selectOne(LambdaQueryWrapperX<OrderApprovalDO> lambdaQueryWrapperX) {
        return approvalMapper.selectOne(lambdaQueryWrapperX);
    }

    @Override
    public Long createApproval(OrderApprovalCreateReqVO createReqVO) {
        // 插入
        OrderApprovalDO approval = OrderApprovalConvert.INSTANCE.convert(createReqVO);
        approvalMapper.insert(approval);
        // 返回
        return approval.getOrderApprovalId();
    }

    @Override
    public void updateApproval(OrderApprovalUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateApprovalExists(updateReqVO.getOrderApprovalId());
        // 更新
        OrderApprovalDO updateObj = OrderApprovalConvert.INSTANCE.convert(updateReqVO);
        approvalMapper.updateById(updateObj);
    }

    @Override
    public void deleteApproval(Long id) {
        // 校验存在
        this.validateApprovalExists(id);
        // 删除
        approvalMapper.deleteById(id);
    }

    private void validateApprovalExists(Long id) {
        if (approvalMapper.selectById(id) == null) {
            throw exception(APPROVAL_NOT_EXISTS);
        }
    }

    @Override
    public OrderApprovalDO getApproval(Long id) {
        return approvalMapper.selectById(id);
    }

    @Override
    public List<OrderApprovalDO> getApprovalList(Collection<Long> ids) {
        return approvalMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<OrderApprovalDO> getApprovalPage(OrderApprovalQueryVO query, PageVO page) {
        return approvalMapper.selectPage(page, query);
    }

    @Override
    public List<OrderApprovalDO> getApprovalList(OrderApprovalQueryVO query) {
        return approvalMapper.selectList(query);
    }

    @Override
    public OrderApprovalDO getLast(Long orderId, OrderApprovalTypeEnum orderApprovalTypeEnum) {
        return approvalMapper.selectOne(new LambdaQueryWrapperX<OrderApprovalDO>().eq(OrderApprovalDO::getOrderId, orderId)
                .eq(OrderApprovalDO::getType, orderApprovalTypeEnum.getValue()).orderByDesc(OrderApprovalDO::getOrderApprovalId).last("limit 1"));
    }

    @Override
    public OrderApprovalDO getProcessingItemBatchApproval(Long orderId, Long orderItemId) {

        OrderApprovalDO orderApprovalDO = approvalMapper.selectProcessingApproval(orderId, Arrays.asList(OrderApprovalTypeEnum.DISCOUNT_APPLY_BATCH.getValue(), OrderApprovalTypeEnum.ADMIN_DISCOUNT_BATCH.getValue()));

        if (orderApprovalDO != null && StringUtils.isNotEmpty(orderApprovalDO.getDetails())) {
            OrderSpecialBatchApplyVO orderSpecialBatchApplyVO = JSONObject.parseObject(orderApprovalDO.getDetails(), OrderSpecialBatchApplyVO.class);
            List<OrderSpecialBatchApplyOrderItemDetailVO> batchApplyOrderItemDetailVOList = orderSpecialBatchApplyVO.getBatchApplyOrderItemDetailVOList();
            if (CollectionUtil.isNotEmpty(batchApplyOrderItemDetailVOList)) {
                if (batchApplyOrderItemDetailVOList.stream().anyMatch(t -> Objects.equals(t.getOrderItemId(), orderItemId))) {
                    return orderApprovalDO;
                }
            }
        }
        return null;
    }
}
