package cn.axzo.msg.center.message.service.impl;

import cn.axzo.basics.common.util.AssertUtil;
import cn.axzo.core.domain.PageResult;
import cn.axzo.msg.center.api.enums.MsgStateEnum;
import cn.axzo.msg.center.api.enums.MsgTypeEnum;
import cn.axzo.msg.center.api.request.CmsMsgQueryReq;
import cn.axzo.msg.center.api.response.MessageNewRes;
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
import cn.axzo.msg.center.common.utils.PageHelperUtil;
import cn.axzo.msg.center.dal.MessageRecordDao;
import cn.axzo.msg.center.domain.entity.MessageRecord;
import cn.axzo.msg.center.domain.enums.ModuleBizTypeEnum;
import cn.axzo.msg.center.inside.notices.service.MessageCoreService;
import cn.axzo.msg.center.inside.notices.service.MessageModuleService;
import cn.axzo.msg.center.inside.notices.service.MessageRelationService;
import cn.axzo.msg.center.message.service.GeneralMessageOldService;
import cn.axzo.msg.center.message.service.MessageSendTwiceRecordService;
import cn.axzo.msg.center.message.service.impl.oldmsg.OldMsgStatCache;
import cn.axzo.msg.center.service.dto.IdentityDTO;
import cn.axzo.msg.center.service.dto.PersonDTO;
import cn.axzo.msg.center.service.general.request.GeneralMessageOldDataStatisticRequest;
import cn.axzo.msg.center.service.general.response.GeneralMessageOldDataStatisticResponse;
import cn.axzo.msg.center.utils.PersonIdentityUtil;
import cn.azxo.framework.common.model.Page;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

/**
 * @author cold_blade
 * @date 2023/10/24
 * @version 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GeneralMessageOldServiceImpl implements GeneralMessageOldService {

    private final MessageRecordDao messageRecordDao;
    private final MessageCoreService messageCoreService;
    private final MessageModuleService messageModuleService;
    private final MessageRelationService messageRelationService;
    private final MessageSendTwiceRecordService messageSendTwiceRecordService;
    private final OldMsgStatCache oldMsgStatCache;

    @Override
    public int countUnread(PersonDTO person) {
        AssertUtil.isTrue(Objects.nonNull(person) && person.isValid(),
                "session 异常, 无法执行消息统计查询!, person : " + person);
        List<Long> sendTwiceMsgIds = messageSendTwiceRecordService.listByPerson(person.getId());
        return countUnread(person, sendTwiceMsgIds);
    }

    @Override
    public int countUnreadWithIdentities(Long personId, List<IdentityDTO> identities) {
        log.info("GeneralMessageOldServiceImpl#countUnreadWithIdentities. personId={}, identifies={}",
                personId, JSON.toJSONString(identities));
        GeneralMessageOldDataStatisticRequest request = new GeneralMessageOldDataStatisticRequest();
        request.setPersonId(personId);
        request.setIdentities(identities);
        GeneralMessageOldDataStatisticResponse statResp = oldMsgStatCache.getCacheResponseOrReload(request);
        return statResp == null ? 0 : statResp.getUnreadCount();
    }

    public int countUnread(Long personId, List<IdentityDTO> identities, List<Long> excludeMsgIds) {
        if (CollectionUtils.isEmpty(identities)) {
            return 0;
        }
        int count = 0;
        for (IdentityDTO identity : identities) {
            PersonDTO person = PersonDTO.from(personId, identity.getId(), identity.getType());
            count += countUnread(person, excludeMsgIds);
        }
        return count;
    }

    @Override
    public int countUnread(PersonDTO person, List<Long> excludeMsgIds) {
        List<Long> moduleIds = messageModuleService.listModuleIdByBizType(ModuleBizTypeEnum.CONSTRUCTION);
        List<Long> relationIds = messageRelationService.listRelationIds(moduleIds);
        if (CollectionUtils.isEmpty(relationIds)) {
            log.info("the is not any valid relation id.");
            return 0;
        }
        return messageRecordDao.lambdaQuery()
                .eq(MessageRecord::getType, MsgTypeEnum.GENERAL_MESSAGE)
                .in(MessageRecord::getState, MsgStateEnum.unreadStates())
                .eq(MessageRecord::getIsDelete, TableIsDeleteEnum.NORMAL.value)
                .eq(MessageRecord::getToId, person.getIdentity().getId())
                .eq(MessageRecord::getReceiveType, PersonIdentityUtil.toReceiveType(person.getIdentity().getType()))
                .in(MessageRecord::getRelationId, relationIds)
                // 排除双发记录表中的数据
                .notIn(CollectionUtils.isNotEmpty(excludeMsgIds), MessageRecord::getId, excludeMsgIds)
                .count();
    }

    @Override
    public Page<MessageNewRes> pageMsgInfo(CmsMsgQueryReq request) {
        if (request.isLogRequest())
            log.info("GeneralMessageOldServiceImpl#pageMsgInfo. request:{}", request);
        if (CollectionUtils.isEmpty(request.determineIdentities())) {
            return Page.zero();
        }
        if (CollectionUtils.isEmpty(request.getExcludeMsgIds())) {
            request.setExcludeMsgIds(messageSendTwiceRecordService.listByPerson(request.getPersonId()));
        }
        // 为了和统计未读的接口保持一致的逻辑
        List<Long> moduleIds = messageModuleService.listModuleIdByBizType(ModuleBizTypeEnum.CONSTRUCTION);
        List<Long> relationIds = messageRelationService.listRelationIds(moduleIds);
        request.setStates(MsgStateEnum.unreadStates());
        request.setRelationIds(relationIds);

        PageResult<MessageNewRes> result = messageCoreService.listMsgInfo(request);
        if (CollectionUtils.isEmpty(result.getData())) {
            return PageHelperUtil.emptyPage(request.getPage(), request.getPageSize());
        }
        return Page.toPage(request.getPage(), request.getPageSize(), result.getTotalCount(), result.getData());
    }
}
