package com.storlead.message.service.impl;

import cn.hutool.core.util.StrUtil;
import com.storlead.framework.common.result.Result;
import com.storlead.framework.common.enums.ErrorMsgCode;
import com.storlead.framework.common.util.HtmlUtils;
import com.storlead.framework.mybatis.service.impl.MyBaseServiceImpl;
import com.storlead.framework.util.LoginUserUtil;
import com.storlead.message.pojo.dto.MessageSendDTO;
import com.storlead.message.pojo.entity.InsideMessageRecordEntity;
import com.storlead.message.mapper.InsideMessageRecordMapper;
import com.storlead.message.pojo.entity.InsideMessageSendLogEntity;
import com.storlead.message.pojo.entity.MessageTemplateEventDetailEntity;
import com.storlead.message.pojo.entity.MessageTemplateEventGroupEntity;
import com.storlead.message.service.InsideMessageRecordService;
import com.storlead.message.service.InsideMessageSendLogService;
import com.storlead.message.service.MessageTemplateEventGroupService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 系统内部消息 服务实现类
 * </p>
 *
 * @author chenkq
 * @since 2024-04-19
 */
@Log4j2
@Service
public class InsideMessageRecordServiceImpl extends MyBaseServiceImpl<InsideMessageRecordMapper, InsideMessageRecordEntity> implements InsideMessageRecordService {

    @Override
    public Map getOldMapDataById(String table,String fieldColumn,String id ) {
        return this.baseMapper.selectOldById(table,fieldColumn,Long.valueOf(id));
    }

    @Value("${domainname}")
    private  String domainname;

    @Resource
    private MessageTemplateEventGroupService templateService;

    @Resource
    private InsideMessageSendLogService insideMessageSendLogService;

    @Override
    public Result sendInsideMessage(MessageTemplateEventGroupEntity eventGroup,MessageTemplateEventDetailEntity templateEventDetail, Map map, Long receiverUserId, String callbackParam, Long sendUserId) {
        return sendInsideMessage(eventGroup,templateEventDetail,map, Arrays.asList(receiverUserId),callbackParam,sendUserId);
    }

    @Override
    public Result sendInsideMessage(MessageTemplateEventGroupEntity eventGroup,MessageTemplateEventDetailEntity templateEventDetail, Map map, Collection<Long> receiverUserIds, String callbackParam, Long sendUserId) {

        String domain = this.domainname;

        MessageTemplateEventDetailEntity templateEntity = templateEventDetail;
        if (Objects.isNull(templateEntity)) {
            return Result.error(ErrorMsgCode.WECHAT_SMS_100006);
        }
        if (CollectionUtils.isEmpty(receiverUserIds)) {
            return Result.error(ErrorMsgCode.WECHAT_SMS_100008);
        }
        String title = templateEntity.getMessageTitle();
        title = title.replace("<br>","\n");
        String content = templateEntity.getMessageCentent();
        if (Objects.isNull(content)) {
            content = templateEntity.getMessageTitle();
        }
        Iterator<Map.Entry< Integer, String >> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry< Integer, String > entry = iterator.next();
            if (Objects.nonNull(entry)) {
                String value =  HtmlUtils.userContent(entry.getValue());
                content = content.replace("${"+entry.getKey()+"}$",value);
                title = title.replace("${"+entry.getKey()+"}$",value);
            }
        }
        content = content.replace("<br>","\n");
        String router = domain +""+ (StrUtil.isNotBlank(templateEntity.getCallbackUrl()) ? templateEntity.getCallbackUrl() : map.get("callbackUrl"));
        if (Objects.nonNull(router)) {
            Object jump = Objects.nonNull(map) ? map.get("jump") : null;
            Object id = Objects.nonNull(map) ? map.get("id") : null;
            if (Objects.nonNull(id)) {
                router = router.replace("${id}$",id.toString());
            } else {
                router = router.replace("${id}$","");
            }
            if (Objects.nonNull(jump)) {
                router = router.replace("${jump}$",jump.toString());
            } else {
                router = router.replace("${jump}$","");
            }
        }

        log.error("asynSendWechatMessage - senderUserId3------------"+sendUserId);
        if (Objects.isNull(sendUserId)) {
            sendUserId = 0L;
        }

        InsideMessageRecordEntity entity = new InsideMessageRecordEntity(title,content,templateEntity.getTemplateIcon(),templateEntity.getTemplateTag(),router,sendUserId,1,eventGroup.getTemplateServiceType());
        entity.setAppId(eventGroup.getAppId());
        entity.setCreateBy(sendUserId);
        entity.setUpdateBy(sendUserId);
        saveOrUpdate(entity);

        List<InsideMessageSendLogEntity> messageSendLogs = new ArrayList<>();
        for (Long receiverUserId : receiverUserIds) {
            InsideMessageSendLogEntity messageSendLog = new InsideMessageSendLogEntity(entity.getId(),receiverUserId,0,1,entity.getMessageType());
            messageSendLog.setCreateBy(sendUserId);
            messageSendLog.setUpdateBy(sendUserId);
            messageSendLogs.add(messageSendLog);
        }
        insideMessageSendLogService.saveOrUpdateBatch(messageSendLogs);
        return Result.ok();
    }

    @Override
    public void asynSendInsideMessage(MessageTemplateEventGroupEntity eventGroup,MessageTemplateEventDetailEntity templateEventDetail, Map map, Long receiverUserId, String callbackParam,Long sendUserId) {
        sendInsideMessage(eventGroup,templateEventDetail,map,Arrays.asList(receiverUserId),callbackParam,sendUserId);
    }

    @Override
    public void asynSendInsideMessage(MessageTemplateEventGroupEntity eventGroup,MessageTemplateEventDetailEntity templateEventDetail, Map map, Collection<Long> receiverUserIds, String callbackParam,Long sendUserId) {
        sendInsideMessage(eventGroup,templateEventDetail,map,receiverUserIds,callbackParam,sendUserId);
    }

    @Override
    public Result<Long> sendDirectMessage(MessageSendDTO dto) {
        if (dto == null || StrUtil.isBlank(dto.getTitle())) {
            return Result.result(null);
        }
        List<Long> receiverUserIds = resolveReceiverUserIds(dto);
        if (CollectionUtils.isEmpty(receiverUserIds)) {
            return Result.result(null);
        }

        Long sendUserId = dto.getSendUserId();
        if (sendUserId == null) {
            sendUserId = LoginUserUtil.getCurrentUserId();
        }
        if (sendUserId == null) {
            sendUserId = 0L;
        }

        String content = StrUtil.blankToDefault(dto.getContent(), dto.getTitle());
        Integer messageType = dto.getMessageType() == null ? 999 : dto.getMessageType();

        InsideMessageRecordEntity entity = new InsideMessageRecordEntity(
                dto.getTitle(),
                content,
                dto.getMessageIcon(),
                dto.getMessageTag(),
                dto.getCallbackUrl(),
                sendUserId,
                1,
                messageType
        );
        entity.setAppId(dto.getAppId());
        entity.setCreateBy(sendUserId);
        entity.setUpdateBy(sendUserId);
        saveOrUpdate(entity);

        List<InsideMessageSendLogEntity> messageSendLogs = new ArrayList<>();
        for (Long receiverUserId : receiverUserIds) {
            InsideMessageSendLogEntity messageSendLog = new InsideMessageSendLogEntity(
                    entity.getId(), receiverUserId, 0, 1, messageType);
            messageSendLog.setCreateBy(sendUserId);
            messageSendLog.setUpdateBy(sendUserId);
            messageSendLogs.add(messageSendLog);
        }
        insideMessageSendLogService.saveOrUpdateBatch(messageSendLogs);
        return Result.result(entity.getId());
    }

    private List<Long> resolveReceiverUserIds(MessageSendDTO dto) {
        List<Long> receiverUserIds = new ArrayList<>();
        if (dto.getToUserIds() != null) {
            for (Long userId : dto.getToUserIds()) {
                if (userId != null) {
                    receiverUserIds.add(userId);
                }
            }
        }
        if (receiverUserIds.isEmpty() && dto.getReceiverUserId() != null) {
            receiverUserIds.add(dto.getReceiverUserId());
        }
        return receiverUserIds;
    }
}
