package com.competition.modules.pub.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.competition.common.exception.BusinessException;
import com.competition.modules.pub.dto.CreateChildDto;
import com.competition.modules.sys.entity.SysUser;
import com.competition.modules.sys.entity.SysTenant;
import com.competition.modules.sys.mapper.SysUserMapper;
import com.competition.modules.sys.mapper.SysTenantMapper;
import com.competition.modules.user.entity.UserChild;
import com.competition.modules.user.entity.UserParentChild;
import com.competition.modules.user.mapper.UserChildMapper;
import com.competition.modules.user.mapper.UserParentChildMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class PublicProfileService {

    private final SysUserMapper sysUserMapper;
    private final SysTenantMapper sysTenantMapper;
    private final UserChildMapper userChildMapper;
    private final UserParentChildMapper userParentChildMapper;
    private final PasswordEncoder passwordEncoder;

    /**
     * 获取个人资料
     */
    public Map<String, Object> getProfile(Long userId) {
        SysUser user = sysUserMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(404, "用户不存在");
        }
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("id", user.getId());
        result.put("username", user.getUsername());
        result.put("nickname", user.getNickname());
        result.put("avatar", user.getAvatar());
        result.put("phone", user.getPhone());
        result.put("city", user.getCity());
        result.put("gender", user.getGender());
        result.put("email", user.getEmail());
        result.put("userType", user.getUserType());
        result.put("birthday", user.getBirthday());
        result.put("createTime", user.getCreateTime());
        return result;
    }

    /**
     * 更新个人资料
     */
    public void updateProfile(Long userId, String nickname, String city, String avatar, String gender) {
        LambdaUpdateWrapper<SysUser> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(SysUser::getId, userId);
        if (nickname != null) wrapper.set(SysUser::getNickname, nickname);
        if (city != null) wrapper.set(SysUser::getCity, city);
        if (avatar != null) wrapper.set(SysUser::getAvatar, avatar);
        if (gender != null) wrapper.set(SysUser::getGender, gender);
        sysUserMapper.update(null, wrapper);
    }

    /**
     * 获取子女列表（旧版 UserChild 表）
     */
    public List<UserChild> getChildren(Long userId) {
        return userChildMapper.selectList(
                new LambdaQueryWrapper<UserChild>()
                        .eq(UserChild::getParentId, userId)
                        .eq(UserChild::getIsDeleted, 0)
                        .orderByDesc(UserChild::getCreateTime));
    }

    /**
     * 创建子女信息
     */
    public UserChild createChild(Long userId, CreateChildDto dto) {
        UserChild child = new UserChild();
        child.setParentId(userId);
        child.setName(dto.getName());
        child.setGender(dto.getGender());
        if (dto.getBirthday() != null) {
            child.setBirthday(LocalDate.parse(dto.getBirthday()));
        }
        child.setGrade(dto.getGrade());
        child.setCity(dto.getCity());
        child.setSchoolName(dto.getSchoolName());
        child.setAvatar(dto.getAvatar());
        child.setIsDeleted(0);
        child.setCreateTime(LocalDateTime.now());
        child.setModifyTime(LocalDateTime.now());
        userChildMapper.insert(child);
        return child;
    }

    /**
     * 获取单个子女信息
     */
    public UserChild getChild(Long id, Long userId) {
        UserChild child = userChildMapper.selectById(id);
        if (child == null || !child.getParentId().equals(userId) || child.getIsDeleted() == 1) {
            throw new BusinessException(404, "子女信息不存在");
        }
        return child;
    }

    /**
     * 更新子女信息
     */
    public void updateChild(Long id, Long userId, CreateChildDto dto) {
        UserChild child = getChild(id, userId);
        if (dto.getName() != null) child.setName(dto.getName());
        if (dto.getGender() != null) child.setGender(dto.getGender());
        if (dto.getBirthday() != null) child.setBirthday(LocalDate.parse(dto.getBirthday()));
        if (dto.getGrade() != null) child.setGrade(dto.getGrade());
        if (dto.getCity() != null) child.setCity(dto.getCity());
        if (dto.getSchoolName() != null) child.setSchoolName(dto.getSchoolName());
        if (dto.getAvatar() != null) child.setAvatar(dto.getAvatar());
        child.setModifyTime(LocalDateTime.now());
        userChildMapper.updateById(child);
    }

    /**
     * 删除子女信息（软删除）
     */
    public void deleteChild(Long id, Long userId) {
        UserChild child = getChild(id, userId);
        child.setIsDeleted(1);
        child.setModifyTime(LocalDateTime.now());
        userChildMapper.updateById(child);
    }

    /**
     * 创建子女独立账号
     */
    @Transactional
    public Map<String, Object> createChildAccount(Long parentUserId, String username, String password,
                                                   String nickname, String gender, String city, String avatar) {
        // 找公众租户
        SysTenant publicTenant = sysTenantMapper.selectOne(
                new LambdaQueryWrapper<SysTenant>().eq(SysTenant::getCode, "public"));
        if (publicTenant == null) {
            throw new BusinessException(500, "公众租户未配置");
        }

        // 检查用户名是否已存在
        Long existCount = sysUserMapper.selectCount(
                new LambdaQueryWrapper<SysUser>()
                        .eq(SysUser::getUsername, username)
                        .eq(SysUser::getTenantId, publicTenant.getId()));
        if (existCount > 0) {
            throw new BusinessException(400, "用户名已存在");
        }

        // 创建子女用户
        SysUser childUser = new SysUser();
        childUser.setTenantId(publicTenant.getId());
        childUser.setUsername(username);
        childUser.setPassword(passwordEncoder.encode(password));
        childUser.setNickname(nickname);
        childUser.setGender(gender);
        childUser.setCity(city);
        childUser.setAvatar(avatar);
        childUser.setUserSource("admin_created");
        childUser.setUserType("child");
        childUser.setStatus("enabled");
        sysUserMapper.insert(childUser);

        // 创建亲子关系
        UserParentChild relation = new UserParentChild();
        relation.setParentUserId(parentUserId);
        relation.setChildUserId(childUser.getId());
        relation.setRelationship("parent");
        relation.setControlMode("full");
        relation.setCreateTime(LocalDateTime.now());
        userParentChildMapper.insert(relation);

        Map<String, Object> result = new LinkedHashMap<>();
        result.put("id", childUser.getId());
        result.put("username", childUser.getUsername());
        result.put("nickname", childUser.getNickname());
        result.put("userType", childUser.getUserType());
        return result;
    }

    /**
     * 获取子女账号列表
     */
    public List<Map<String, Object>> getChildAccounts(Long parentUserId) {
        List<UserParentChild> relations = userParentChildMapper.selectList(
                new LambdaQueryWrapper<UserParentChild>()
                        .eq(UserParentChild::getParentUserId, parentUserId));
        if (relations.isEmpty()) {
            return Collections.emptyList();
        }

        List<Long> childUserIds = relations.stream()
                .map(UserParentChild::getChildUserId)
                .collect(Collectors.toList());
        List<SysUser> children = sysUserMapper.selectBatchIds(childUserIds);

        return children.stream().map(child -> {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("id", child.getId());
            map.put("username", child.getUsername());
            map.put("nickname", child.getNickname());
            map.put("avatar", child.getAvatar());
            map.put("gender", child.getGender());
            map.put("city", child.getCity());
            map.put("userType", child.getUserType());
            map.put("status", child.getStatus());
            return map;
        }).collect(Collectors.toList());
    }

    /**
     * 更新子女账号
     */
    public void updateChildAccount(Long childUserId, Long parentUserId, Map<String, Object> dto) {
        // 验证亲子关系
        Long count = userParentChildMapper.selectCount(
                new LambdaQueryWrapper<UserParentChild>()
                        .eq(UserParentChild::getParentUserId, parentUserId)
                        .eq(UserParentChild::getChildUserId, childUserId));
        if (count == 0) {
            throw new BusinessException(403, "无权操作该子女账号");
        }

        LambdaUpdateWrapper<SysUser> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(SysUser::getId, childUserId);
        if (dto.containsKey("nickname")) wrapper.set(SysUser::getNickname, (String) dto.get("nickname"));
        if (dto.containsKey("avatar")) wrapper.set(SysUser::getAvatar, (String) dto.get("avatar"));
        if (dto.containsKey("gender")) wrapper.set(SysUser::getGender, (String) dto.get("gender"));
        if (dto.containsKey("city")) wrapper.set(SysUser::getCity, (String) dto.get("city"));
        if (dto.containsKey("password")) {
            wrapper.set(SysUser::getPassword, passwordEncoder.encode((String) dto.get("password")));
        }
        sysUserMapper.update(null, wrapper);
    }

    /**
     * 获取家长信息（子女视角）
     */
    public Map<String, Object> getParentInfo(Long childUserId) {
        UserParentChild relation = userParentChildMapper.selectOne(
                new LambdaQueryWrapper<UserParentChild>()
                        .eq(UserParentChild::getChildUserId, childUserId)
                        .last("LIMIT 1"));
        if (relation == null) {
            return null;
        }

        SysUser parent = sysUserMapper.selectById(relation.getParentUserId());
        if (parent == null) {
            return null;
        }

        Map<String, Object> result = new LinkedHashMap<>();
        result.put("id", parent.getId());
        result.put("username", parent.getUsername());
        result.put("nickname", parent.getNickname());
        result.put("avatar", parent.getAvatar());
        result.put("phone", parent.getPhone());
        result.put("relationship", relation.getRelationship());
        return result;
    }
}
