package com.seer.teach.user.app.convert;

import cn.hutool.core.collection.CollectionUtil;
import com.seer.teach.common.dto.mq.im.MqUserInfoDTO;
import com.seer.teach.common.entity.CityEntity;
import com.seer.teach.common.entity.ProvinceEntity;
import com.seer.teach.user.app.user.controller.req.AppUserInfoReq;
import com.seer.teach.user.app.user.controller.req.ChildrenInfoUpdateReq;
import com.seer.teach.user.app.user.controller.req.UpdateUserInfoReq;
import com.seer.teach.user.app.user.controller.resp.AppGetUserInfoResp;
import com.seer.teach.user.app.user.controller.resp.AppUserInfoResp;
import com.seer.teach.user.entity.GradeEntity;
import com.seer.teach.user.entity.LevelEntity;
import com.seer.teach.user.entity.UserEntity;
import com.seer.teach.user.entity.UserExtendEntity;
import com.seer.teach.user.entity.UserFamilyEntity;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.CollectionMappingStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
public interface UserInfoConvert {

    UserInfoConvert INSTANCE = Mappers.getMapper(UserInfoConvert.class);

    String DEFAULT_AVATAR = "https://static.seerteach.net/seerteach/avatar/17585213470454ed99b14.png";

    String DEFAULT_NICK_NAME = "微信用户";

    @Mapping(source = "level.name", target = "currentLevelName")
    @Mapping(source = "userInfoEntity.id", target = "id")
    @Mapping(source = "userExtendEntity.gradeId", target = "gradeId")
    AppUserInfoResp toUserInfoResp(UserEntity userInfoEntity, UserExtendEntity userExtendEntity, LevelEntity level, ProvinceEntity province, CityEntity city);

    UserEntity toUserInfoEntity(ChildrenInfoUpdateReq req);


    @Mapping(source = "level.imageUrl", target = "levelImageUrl")
    @Mapping(source = "level.name", target = "currentLevel")
    @Mapping(source = "children.id", target = "id")
    MqUserInfoDTO toMqUserInfoDTO(UserEntity children, UserExtendEntity userExtendEntity,GradeEntity grade, LevelEntity level, String device);

    @Mapping(source = "id", target = "id")
    @Mapping(source = "userId", target = "userId")
    UserExtendEntity convertUserExtendOne(ChildrenInfoUpdateReq updateReq, Integer id, Integer userId);

    @Mapping(source = "userEntity.id", target = "id")
    AppUserInfoResp toUserInfoResp(UserEntity userEntity, UserExtendEntity userExtendEntity);

    default AppUserInfoResp toUserInfoRespWithDefaultValue(UserEntity userEntity, UserExtendEntity userExtendEntity){
        AppUserInfoResp appUserInfoResp = toUserInfoResp(userEntity, userExtendEntity);
        if(Objects.isNull(appUserInfoResp)){
            return null;
        }
        if(StringUtils.isEmpty(appUserInfoResp.getAvatar())){
            appUserInfoResp.setAvatar(DEFAULT_AVATAR);
        }
        if(StringUtils.isEmpty(appUserInfoResp.getNickName())){
            appUserInfoResp.setNickName(DEFAULT_NICK_NAME);
        }
        return appUserInfoResp;
    }

    @Mapping(source = "userEntity.id", target = "id")
    @Mapping(source = "level.name", target = "currentLevelName")
    AppUserInfoResp toUserInfoResp(UserEntity userEntity, UserExtendEntity userExtendEntity, LevelEntity level);

    List<AppUserInfoResp> toUserInfoListResp(List<UserEntity> users);

    default List<AppUserInfoResp> toUserInfoListRespWithDefaultValue(List<UserEntity> users, UserFamilyEntity family){
        List<AppUserInfoResp> userInfoListResp = toUserInfoListResp(users);
        if(CollectionUtil.isEmpty(userInfoListResp)){
            return Collections.emptyList();
        }
        for (AppUserInfoResp resp : userInfoListResp) {
            if (Objects.nonNull(family)) {
                resp.setFamilyId(family.getId());
                resp.setPrimaryGuardian(family.getPrimaryGuardianUserId().intValue() == resp.getId());
            }
            if(StringUtils.isEmpty(resp.getAvatar())){
                resp.setAvatar(DEFAULT_AVATAR);
            }
            if(StringUtils.isEmpty(resp.getNickName())){
                resp.setNickName(DEFAULT_NICK_NAME);
            }
        }
        return userInfoListResp;
    }

    default List<AppUserInfoResp> toUserInfoListResp(List<UserEntity> users, List<UserExtendEntity> userExtends, List<LevelEntity> userLevels){
        Map<Integer, UserExtendEntity> userExtendMap = userExtends.stream().collect(Collectors.toMap(UserExtendEntity::getUserId, Function.identity(), (userExtend, userExtend2) -> userExtend));
        Map<Integer, LevelEntity> userLevelMap = userLevels.stream().collect(Collectors.toMap(LevelEntity::getId, Function.identity(), (level, level2) -> level));
        return users.stream().map(user -> {
            UserExtendEntity userExtendEntity = userExtendMap.get(user.getId());
            LevelEntity level = userLevelMap.get(userExtendEntity.getLevelId());
            return toUserInfoResp(user, userExtendEntity, level);
        }).collect(Collectors.toList());
    }

    @Mapping(source = "userId", target = "id")
    UserEntity convertAppUserInfo2Entity(AppUserInfoReq appUserInfoReq,Integer userId);

    @Mapping(source = "userId", target = "id")
    @Mapping(source = "params.birthDate", target = "birthDate")
    UserEntity convertAppUserInfo2Entity(UpdateUserInfoReq params, Integer userId);

    AppGetUserInfoResp toGetUserInfoResp(Integer userId, String avatar, Integer gender, LocalDate birthDate, String nickName,
                                         Integer experience, Integer gradeId, String levelName, String school, String joinDaysText,String location);
}