package com.sikey.wa04.business.infrastructure.adapter.dao;

import com.sikey.wa04.business.domain.adapter.ChildQueryAdapter;
import com.sikey.wa04.business.domain.entity.*;
import com.sikey.wa04.business.infrastructure.convert.ChildRefConvert;
import com.sikey.wa04.business.infrastructure.dto.model.ChildModel;
import com.sikey.wa04.business.infrastructure.dto.model.ChildRefModel;
import com.sikey.wa04.business.infrastructure.dto.model.UserModel;
import com.sikey.wa04.business.infrastructure.repository.ChildRefRepository;
import com.sikey.wa04.business.infrastructure.repository.ChildRepository;
import com.sikey.wa04.business.infrastructure.repository.UserRepository;
import com.sikey.wa04.common.enums.Gender;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Component
public class ChildQueryAdapterImpl implements ChildQueryAdapter {

    @Resource
    private UserRepository userRepository;

    @Resource
    private ChildRepository childRepository;

    @Resource
    private ChildRefRepository childRefRepository;

    @Override
    public List<Child> findChildren(UserId uid) {
        // 儿童
        List<ChildRefModel> childRefs = childRefRepository.findByUserIdOrderByIdAsc(uid.getId());
        // 使用Set（自动去重）
        Set<String> idSet = childRefs.stream()
                .map(ChildRefModel::getChildId)
                .collect(Collectors.toSet());

        List<ChildModel> childModels = childRepository.findAllById(idSet);
        // 批量查询ChildModel并转换为Map
        Map<String, ChildModel> childModelMap = childModels.stream()
                .collect(Collectors.toMap(ChildModel::getId, Function.identity()));

        List<Child> childList = new ArrayList<>(childModels.size());
        childRefs.forEach(childRef -> {
            ChildModel childModel = childModelMap.get(childRef.getChildId());
            if (childModel != null) {
                Child child = new Child().setId(childModel.getId())
                        .setUserId(childRef.getUserId())
                        .setName(childModel.getChildName())
                        .setPhoneNumber(new PhoneNumber(childModel.getPhoneNumber(), childModel.getAreaCode()))
                        .setAvatar(childModel.getAvatar())
                        .setGender(Gender.valueOf(childModel.getGender()))
                        .setBirthday(childModel.getBirthday())
                        .setHeight(childModel.getHeight())
                        .setWeight(childModel.getWeight())
                        .setIsEnableBlockUnknownCall(childModel.getIsEnableBlockUnknownCall())
                        .setIsEnableFence(childModel.getIsEnableFence());
                childList.add(child);
            }
        });

        return childList;
    }

    @Override
    public List<User> findParent(ChildId cid) {
        return childRefRepository.findByChildId(cid.getId()).stream().map(model -> {
            Optional<UserModel> optional = userRepository.findById(model.getUserId());
            UserModel userModel = optional.orElseThrow();
            return new User()
                    .setId(new UserId(userModel.getId()))
                    .setPhoneNumber(new PhoneNumber(userModel.getPhoneNumber(), userModel.getAreaCode()))
                    .setEmail(userModel.getEmail())
                    .setPassword(userModel.getPassword())
                    .setIsRegistered(userModel.getIsRegistered())
                    .setCreateAt(userModel.getCreatedAt())
                    .setUpdateAt(userModel.getUpdatedAt());
        }).toList();
    }

    @Override
    public Child findByChildId(ChildId childId) {
        Optional<ChildModel> optional = childRepository.findById(childId.getId());
        if (optional.isPresent()) {
            ChildModel childModel = optional.get();
            return new Child().setId(childModel.getId())
                    .setName(childModel.getChildName())
                    .setPhoneNumber(new PhoneNumber(childModel.getPhoneNumber(), childModel.getAreaCode()))
                    .setAvatar(childModel.getAvatar())
                    .setGender(Gender.valueOf(childModel.getGender()))
                    .setBirthday(childModel.getBirthday())
                    .setHeight(childModel.getHeight())
                    .setWeight(childModel.getWeight())
                    .setIsEnableBlockUnknownCall(childModel.getIsEnableBlockUnknownCall())
                    .setIsEnableFence(childModel.getIsEnableFence());
        }
        return new Child();
    }

    /**
     * 查询儿童
     *
     * @param childId 儿童id
     * @return
     */
    @Override
    public List<ChildRef> queryChildRefByChildId(String childId) {
        List<ChildRefModel> childRefModels = childRefRepository.findByChildId(childId);
        return ChildRefConvert.INSTANCE.convert(childRefModels);
    }

    /**
     * 查询孩子
     *
     * @param uidList 孩子ID
     * @return 孩子
     */
    @Override
    public List<Child> findByChildId(List<String> uidList) {
        List<ChildModel> childList = childRepository.findAllById(uidList);
        List<Child> children = new ArrayList<>(childList.size());
        childList.forEach(child -> {
            Child childModel = new Child()
                    .setId(child.getId())
                    .setPhoneNumber(new PhoneNumber(child.getPhoneNumber(), child.getAreaCode()))
                    .setGender(Gender.valueOf(child.getGender()))
                    .setHeight(child.getHeight())
                    .setBirthday(child.getBirthday())
                    .setWeight(child.getWeight())
                    .setIsEnableBlockUnknownCall(child.getIsEnableBlockUnknownCall())
                    .setIsEnableFence(child.getIsEnableFence())
                    .setAreaCode(child.getAreaCode())
                    .setAvatar(child.getAvatar())
                    .setName(child.getChildName());
            children.add(childModel);
        });

        return children;
    }
}
