package shop.alien.util.type;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import shop.alien.entity.store.LifeMessage;

import java.util.List;

/**
 * LifeMessage 发送人/接收人 userType、refId 回填与查询工具。
 */
@Component
@RequiredArgsConstructor
public class LifeMessageUtil {

    private final TypeUtil typeUtil;

    public void fillUserTypeAndRefId(LifeMessage message) {
        if (message == null) {
            return;
        }
        fillSender(message);
        fillReceiver(message);
        fillDeletePhone(message);
    }

    private void fillSender(LifeMessage message) {
        String senderId = message.getSenderId();
        if (!StringUtils.hasText(senderId)) {
            return;
        }
        if (message.getSenderUserType() != null && message.getSenderRefId() != null) {
            return;
        }
        if (typeUtil.containsUnderscore(senderId)) {
            applyTypeId(message, typeUtil.resolveTypeAndId(senderId), true);
        }
    }

    private void fillReceiver(LifeMessage message) {
        String receiverId = message.getReceiverId();
        if (!StringUtils.hasText(receiverId)) {
            return;
        }
        if (message.getReceiverUserType() != null && message.getReceiverRefId() != null) {
            return;
        }
        if (typeUtil.containsUnderscore(receiverId)) {
            applyTypeId(message, typeUtil.resolveTypeAndId(receiverId), false);
        }
    }

    private void fillDeletePhone(LifeMessage message) {
        String deletePhoneId = message.getDeletePhoneId();
        if (!StringUtils.hasText(deletePhoneId)) {
            return;
        }
        if (message.getDeletePhoneUserType() != null && message.getDeletePhoneRefId() != null) {
            return;
        }
        PhoneTypeIdResult result = typeUtil.resolveTypeAndId(deletePhoneId);
        if (result != null) {
            message.setDeletePhoneUserType(result.getType());
            message.setDeletePhoneRefId(result.getId());
        }
    }

    private void applyTypeId(LifeMessage message, PhoneTypeIdResult result, boolean sender) {
        if (result == null) {
            return;
        }
        if (sender) {
            message.setSenderUserType(result.getType());
            message.setSenderRefId(result.getId());
        } else {
            message.setReceiverUserType(result.getType());
            message.setReceiverRefId(result.getId());
        }
    }

    public PhoneTypeIdResult resolveIdentity(String phoneId) {
        if (!StringUtils.hasText(phoneId)) {
            return null;
        }
        return typeUtil.resolveTypeAndId(phoneId);
    }

    public void applyReceiverQuery(LambdaQueryWrapper<LifeMessage> wrapper, String receiverId) {
        applyReceiverIdentity(wrapper, receiverId);
    }

    public void applyReceiverUpdate(LambdaUpdateWrapper<LifeMessage> wrapper, String receiverId) {
        applyReceiverIdentity(wrapper, receiverId);
    }

    public void applySenderQuery(LambdaQueryWrapper<LifeMessage> wrapper, String senderId) {
        applySenderIdentity(wrapper, senderId);
    }

    public void applySenderReceiverPairQuery(LambdaQueryWrapper<LifeMessage> wrapper, String senderId, String receiverId) {
        PhoneTypeIdResult sender = resolveIdentity(senderId);
        PhoneTypeIdResult receiver = resolveIdentity(receiverId);
        if (sender == null || receiver == null) {
            wrapper.apply("1 = 0");
            return;
        }
        wrapper.eq(LifeMessage::getSenderUserType, sender.getType())
                .eq(LifeMessage::getSenderRefId, sender.getId())
                .eq(LifeMessage::getReceiverUserType, receiver.getType())
                .eq(LifeMessage::getReceiverRefId, receiver.getId());
    }

    public void applySenderReceiverPairUpdate(LambdaUpdateWrapper<LifeMessage> wrapper, String senderId, String receiverId) {
        PhoneTypeIdResult sender = resolveIdentity(senderId);
        PhoneTypeIdResult receiver = resolveIdentity(receiverId);
        if (sender == null || receiver == null) {
            wrapper.apply("1 = 0");
            return;
        }
        wrapper.eq(LifeMessage::getSenderUserType, sender.getType())
                .eq(LifeMessage::getSenderRefId, sender.getId())
                .eq(LifeMessage::getReceiverUserType, receiver.getType())
                .eq(LifeMessage::getReceiverRefId, receiver.getId());
    }

    public void applyConversationQuery(LambdaQueryWrapper<LifeMessage> wrapper, String phoneId1, String phoneId2) {
        PhoneTypeIdResult first = resolveIdentity(phoneId1);
        PhoneTypeIdResult second = resolveIdentity(phoneId2);
        if (first == null || second == null) {
            wrapper.apply("1 = 0");
            return;
        }
        wrapper.and(w -> w.nested(n -> n.eq(LifeMessage::getSenderUserType, first.getType())
                        .eq(LifeMessage::getSenderRefId, first.getId())
                        .eq(LifeMessage::getReceiverUserType, second.getType())
                        .eq(LifeMessage::getReceiverRefId, second.getId()))
                .or()
                .nested(n -> n.eq(LifeMessage::getSenderUserType, second.getType())
                        .eq(LifeMessage::getSenderRefId, second.getId())
                        .eq(LifeMessage::getReceiverUserType, first.getType())
                        .eq(LifeMessage::getReceiverRefId, first.getId())));
    }

    public void applySenderInQuery(LambdaQueryWrapper<LifeMessage> wrapper, List<String> senderPhoneIds) {
        if (senderPhoneIds == null || senderPhoneIds.isEmpty()) {
            wrapper.apply("1 = 0");
            return;
        }
        wrapper.and(w -> {
            boolean added = false;
            for (String senderPhoneId : senderPhoneIds) {
                PhoneTypeIdResult sender = resolveIdentity(senderPhoneId);
                if (sender == null) {
                    continue;
                }
                if (added) {
                    w.or();
                }
                w.nested(n -> n.eq(LifeMessage::getSenderUserType, sender.getType())
                        .eq(LifeMessage::getSenderRefId, sender.getId()));
                added = true;
            }
            if (!added) {
                w.apply("1 = 0");
            }
        });
    }

    /**
     * 子查询：当前用户作为发送方时，聊过的对方 receiver_id 列表。
     */
    public String sqlDistinctReceiverIdsBySender(String senderId) {
        PhoneTypeIdResult sender = resolveIdentity(senderId);
        if (sender == null) {
            return "select null where 1 = 0";
        }
        return "select receiver_id from life_message where delete_flag = 0 "
                + "and sender_user_type = " + sender.getType()
                + " and sender_ref_id = " + sender.getId()
                + " group by receiver_id";
    }

    private void applyReceiverIdentity(LambdaQueryWrapper<LifeMessage> wrapper, String receiverId) {
        PhoneTypeIdResult resolved = resolveIdentity(receiverId);
        if (resolved != null && resolved.getType() != null && resolved.getId() != null) {
            wrapper.eq(LifeMessage::getReceiverUserType, resolved.getType())
                    .eq(LifeMessage::getReceiverRefId, resolved.getId());
        } else {
            wrapper.apply("1 = 0");
        }
    }

    private void applySenderIdentity(LambdaQueryWrapper<LifeMessage> wrapper, String senderId) {
        PhoneTypeIdResult resolved = resolveIdentity(senderId);
        if (resolved != null && resolved.getType() != null && resolved.getId() != null) {
            wrapper.eq(LifeMessage::getSenderUserType, resolved.getType())
                    .eq(LifeMessage::getSenderRefId, resolved.getId());
        } else {
            wrapper.apply("1 = 0");
        }
    }

    private void applyReceiverIdentity(LambdaUpdateWrapper<LifeMessage> wrapper, String receiverId) {
        PhoneTypeIdResult resolved = resolveIdentity(receiverId);
        if (resolved != null && resolved.getType() != null && resolved.getId() != null) {
            wrapper.eq(LifeMessage::getReceiverUserType, resolved.getType())
                    .eq(LifeMessage::getReceiverRefId, resolved.getId());
        } else {
            wrapper.apply("1 = 0");
        }
    }
}
