package cn.axzo.msg.center.dal;

import cn.axzo.im.center.api.vo.resp.MessageTaskResp;
import cn.axzo.im.center.api.vo.resp.UpdatableMessageSendResult;
import cn.axzo.msg.center.dal.mapper.CardMapper;
import cn.axzo.msg.center.domain.entity.Card;
import cn.axzo.msg.center.domain.persistence.BaseEntityExt;
import cn.axzo.msg.center.service.pending.request.CardStateInfo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * @author yanglin
 */
@Slf4j
@Component
public class CardDao extends ServiceImpl<CardMapper, Card> {

    public void updateStates(List<Card> cards, CardStateInfo stateInfo) {
        List<Long> cardIds = cards.stream()
                .map(BaseEntityExt::getId)
                .collect(Collectors.toList());
        lambdaUpdate()
                .in(Card::getId, cardIds)
                .set(stateInfo.getBizState() != null, Card::getBizState, stateInfo.getBizState())
                .set(stateInfo.getCardState() != null, Card::getCardState, stateInfo.getCardState())
                .update();
    }

    public List<Card> collectPersonCards(String oneOfBizMessageId) {
        Card card = findCardByBizMessageId(oneOfBizMessageId).orElse(null);
        if (card == null) return Collections.emptyList();
        return lambdaQuery()
                .eq(Card::getAppCode, card.getAppCode())
                .eq(Card::getTemplateCode, card.getTemplateCode())
                .eq(Card::getBizCode, card.getBizCode())
                .eq(Card::getSubBizCode, card.getSubBizCode())
                .eq(Card::getReceiverOuId, card.getReceiverOuId())
                .eq(Card::getReceiverWorkspaceId, card.getReceiverWorkspaceId())
                .eq(Card::getReceiverPersonId, card.getReceiverPersonId())
                .list();
    }

    public Optional<Card> findCardByBizMessageId(String bizMessageId) {
        return Optional.ofNullable(lambdaQuery()
                .eq(Card::getBizMessageId, bizMessageId)
                .one());
    }

    @Transactional
    public void setSendSuccess(List<Card> cards, MessageTaskResp imResponse) {
        ArrayList<Card> updates = new ArrayList<>();
        List<UpdatableMessageSendResult> sendResults = imResponse.getUpdatableMessageSendResults();
        for (int i = 0; i < cards.size(); i++) {
            Card card = cards.get(i);
            Card update = new Card();
            update.setId(card.getId());
            update.setImTaskId(imResponse.getId());
            if (sendResults != null && i < sendResults.size()) {
                UpdatableMessageSendResult sendResult = sendResults.get(i);
                update.setBizMessageId(sendResult.getBizMessageId());
            }
            updates.add(update);
        }
        updateBatchById(updates);
    }

    public List<Card> reloadCards(List<Card> cards) {
        if (CollectionUtils.isEmpty(cards))
            return Collections.emptyList();
        return getBaseMapper().getByIds(collectCardIds(cards));
    }

    public void deleteCards(List<Card> cards) {
        if (CollectionUtils.isEmpty(cards))
            return;
        removeByIds(collectCardIds(cards));
    }

    private static List<Long> collectCardIds(List<Card> cards) {
        return cards.stream().map(BaseEntityExt::getId).collect(toList());
    }
}