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

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.seer.teach.common.entity.CityEntity;
import com.seer.teach.common.entity.ProvinceEntity;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.enums.UserRelationEnum;
import com.seer.teach.common.service.RegionAddressService;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.common.utils.DateUtils;
import com.seer.teach.iot.api.DeviceInfoServiceApi;
import com.seer.teach.iot.api.DeviceLocationInfoServiceApi;
import com.seer.teach.iot.api.UserDeviceServiceApi;
import com.seer.teach.iot.api.resp.DeviceRespDTO;
import com.seer.teach.user.app.convert.CityConvert;
import com.seer.teach.user.app.convert.UserInfoConvert;
import com.seer.teach.user.app.user.controller.req.AppUserInfoReq;
import com.seer.teach.user.app.user.controller.req.JudgeAreaReq;
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.AppProvinceCityResp;
import com.seer.teach.user.app.user.controller.resp.AppUserInfoResp;
import com.seer.teach.user.app.user.controller.resp.CityResp;
import com.seer.teach.user.convert.UserExtendConvert;
import com.seer.teach.user.entity.*;
import com.seer.teach.user.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Service
public class AppUserInfoService {

    private final static String WELCOME_TEXT = "来到这里已经%d天啦~";

    private final IUserService userService;

    private final IUserExtendService userExtendService;

    private final UserDeviceServiceApi userDeviceServiceApi;

    private final RegionAddressService regionAddressService;

    private final IUserRelationService userRelationService;

    private final IUserFamilyService userFamilyService;

    private final ILevelService levelService;

    private final DeviceInfoServiceApi deviceInfoServiceApi;

    private final DeviceLocationInfoServiceApi deviceLocationInfoServiceApi;

    /**
     * 判断省市是否一致
     *
     * @param judgeAreaReq 判断省市请求参数
     * @return 0:一致 1:不一致
     */
    public int judgeArea(JudgeAreaReq judgeAreaReq) {
        // 根据token获取userid
        Integer userId = StpUtil.getLoginIdAsInt();
        UserEntity children = userService.getChildrenByUserId(userId, judgeAreaReq.getChildId());
        log.info("登录用户:{} 获取孩子信息:{},", userId, children);
        // 根据userId查询数据库中的省份和城市
        DeviceRespDTO devices = userDeviceServiceApi.getDeviceDTOByUserId(children.getId());

        AssertUtils.notNull(devices, ResultCodeEnum.USER_NOT_BIND_DEVICE);

        log.info("用户[{}]获取孩子[{}]设备信息:[{}]", userId, children.getId(), devices);
        ProvinceEntity province = regionAddressService.getProvinceByCityId(devices.getCityId());
        CityEntity city = regionAddressService.getCityById(devices.getCityId());
        if (judgeAreaReq.getProvince().equals(province.getProvince()) && judgeAreaReq.getCity().equals(city.getCity())) {
            return 0;
        } else {
            return 1;
        }
    }

    /**
     * 获取用户详情
     *
     * @return 用户详情
     */
    public AppUserInfoResp getUserDetail() {
        Integer userId = StpUtil.getLoginIdAsInt();

        UserEntity children = userService.getById(userId);

        UserExtendEntity userExtendEntity = userExtendService.getUserExtendByUserId(userId);

        AppUserInfoResp appUserInfoResp = UserInfoConvert.INSTANCE.toUserInfoRespWithDefaultValue(children, userExtendEntity);

        List<UserRelationEntity> userRelations = userRelationService.getUserRelationByUserIdAndType(userId, UserRelationEnum.PARENT_CHILD);

        if (CollectionUtil.isNotEmpty(userRelations)) {
            UserRelationEntity childRelation = userRelations.stream().filter(relation -> Objects.nonNull(relation.getFamilyId())).findAny().orElse(null);

            if (Objects.nonNull(childRelation) && Objects.nonNull(childRelation.getFamilyId())) {
                UserFamilyEntity family = userFamilyService.getById(childRelation.getFamilyId());
                appUserInfoResp.setPrimaryGuardian(family.getPrimaryGuardianUserId().intValue() == userId.intValue());
                appUserInfoResp.setFamilyId(childRelation.getFamilyId());
            }
        }
        log.info("用户[{}]获取用户详情:[{}]", userId, appUserInfoResp);
        return appUserInfoResp;
    }

    /**
     * 更新用户信息，仅更新用户的头像和昵称
     *
     * @param appUserInfoReq 用户信息
     * @return 是否更新成功
     */
    public boolean updateUserSimpleInfo(AppUserInfoReq appUserInfoReq) {
        Integer userId = StpUtil.getLoginIdAsInt();
        log.info("用户[{}]更新用户信息:[{}]", userId, appUserInfoReq);
        UserEntity userEntity = UserInfoConvert.INSTANCE.convertAppUserInfo2Entity(appUserInfoReq, userId);
        boolean updated = userService.updateById(userEntity);
        log.info("更新用户信息:{}", updated);
        return updated;
    }

    /**
     * 更新用户信息
     *
     * @param params 用户信息更新请求参数，包含城市ID、年级ID、学校等信息
     * @return 是否更新成功
     */
    public Boolean updateUserInfo(UpdateUserInfoReq params) {
        Integer userId = StpUtil.getLoginIdAsInt();
        log.info("用户[{}]更新用户信息:[{}]", userId, params);
        // 更新设备表中的城市信息
        deviceInfoServiceApi.updateDeviceCityByUserId(userId, params.getCityId());
        UserEntity userEntity = UserInfoConvert.INSTANCE.convertAppUserInfo2Entity(params, userId);
        boolean updated = userService.updateById(userEntity);
        // 查询用户扩展信息是否存在
        UserExtendEntity byUserId = userExtendService.getByUserId(userId);
        if (Objects.isNull(byUserId)) {
            log.info("初始化用户[{}] 年级 等级 经验值 信息", userId);
            // 若不存在则创建默认的用户扩展信息
            LevelEntity defaultLevel = levelService.getDefaultLevel();
            UserExtendEntity extend = UserExtendConvert.INSTANCE.toUserExtendEntity(userId, params.getGradeId(), defaultLevel.getId(), 0, params.getSchool());
            userExtendService.save(extend);
            return updated;
        }
        // 存在则更新年级和学校信息
        byUserId.setGradeId(params.getGradeId());
        byUserId.setSchool(params.getSchool());
        userExtendService.updateById(byUserId);
        return updated;
    }

    /**
     * 获取用户信息
     *
     * @return 用户详细信息响应对象，包括头像、性别、昵称、等级、学校、注册天数、所在地区等
     */
    public AppGetUserInfoResp getUserInfo() {
        Integer userId = StpUtil.getLoginIdAsInt();
        log.info("用户[{}]获取用户信息", userId);
        // 获取基础用户信息
        UserEntity user = userService.getById(userId);
        Integer cityId = deviceInfoServiceApi.getCityIdByUserId(user.getId());
        // 获取省份和城市名称
        ProvinceEntity province = regionAddressService.getProvinceByCityId(cityId);
        String city = deviceLocationInfoServiceApi.getCityNameByCityId(cityId);
        // 获取用户所在地区
        String location = String.join(" ", province.getProvince(), city);
        // 计算用户入驻天数并格式化欢迎语
        long days = DateUtils.calculateDaysFromNow(user.getCreateTime());
        String joinDaysText = String.format(WELCOME_TEXT, days);
        // 获取用户扩展信息
        UserExtendEntity userExtend = userExtendService.getUserExtendByUserId(userId);
        AssertUtils.notNull(userExtend, ResultCodeEnum.USER_NOT_FOUND);
        log.info("用户[{}]获取用户扩展信息:[{}]", userId, userExtend);
        // 获取用户的等级信息
        LevelEntity level = levelService.getById(userExtend.getLevelId());
        // 转换为返回结果对象
        return UserInfoConvert.INSTANCE.toGetUserInfoResp(
                userId,
                user.getAvatar(),
                user.getGender(),
                user.getBirthDate(),
                user.getNickName(),
                userExtend.getExperience(),
                userExtend.getGradeId(),
                level.getName(),
                userExtend.getSchool(),
                joinDaysText,
                location);
    }

    /**
     * 获取省份和城市信息
     *
     * @return 省份和城市信息
     */
    public List<AppProvinceCityResp> getProvinceAndCity() {
        // 查询所有省份
        List<ProvinceEntity> provinces = regionAddressService.getAllProvinces();
        // 查询所有城市
        List<CityEntity> citys = regionAddressService.getAllCitys();
        Map<Integer, List<CityEntity>> map = citys.stream()
                .collect(Collectors.groupingBy(CityEntity::getProvinceId));
        // 构建返回结果对象
        return provinces.stream().map(province -> {
            List<CityEntity> cities = map.get(province.getId());
            return new AppProvinceCityResp(province.getId(), province.getProvince(), CityConvert.INSTANCE.toCityRespList(cities));
        }).collect(Collectors.toList());
    }
}