package com.lesingle.creation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lesingle.creation.common.exception.BusinessException;
import com.lesingle.creation.common.util.JwtTokenUtil;
import com.lesingle.creation.dto.child.CreateChildDTO;
import com.lesingle.creation.dto.child.UpdateChildDTO;
import com.lesingle.creation.dto.publicuser.PublicLoginDTO;
import com.lesingle.creation.dto.publicuser.PublicRegisterDTO;
import com.lesingle.creation.dto.publicuser.PublicUserUpdateDTO;
import com.lesingle.creation.entity.Contest;
import com.lesingle.creation.entity.User;
import com.lesingle.creation.entity.UserChild;
import com.lesingle.creation.mapper.ContestMapper;
import com.lesingle.creation.mapper.UserChildMapper;
import com.lesingle.creation.mapper.UserMapper;
import com.lesingle.creation.service.PublicService;
import com.lesingle.creation.vo.child.ChildVO;
import com.lesingle.creation.vo.publicuser.LoginResponseVO;
import com.lesingle.creation.vo.publicuser.PublicUserVO;
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.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 公众用户服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PublicServiceImpl implements PublicService {

    private final UserMapper userMapper;
    private final UserChildMapper userChildMapper;
    private final ContestMapper contestMapper;
    private final PasswordEncoder passwordEncoder;
    private final JwtTokenUtil jwtTokenUtil;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LoginResponseVO register(PublicRegisterDTO dto) {
        // 检查用户名是否已存在
        User existingUser = userMapper.selectByUsername(dto.getUsername());
        if (existingUser != null) {
            throw new BusinessException("用户名已存在");
        }

        // 创建用户
        User user = new User();
        user.setTenantId(1L);
        user.setUsername(dto.getUsername());
        user.setPassword(passwordEncoder.encode(dto.getPassword()));
        user.setNickname(dto.getNickname());
        user.setPhone(dto.getPhone());
        user.setEmail(dto.getEmail());
        user.setAvatar(dto.getAvatar());
        user.setGender(dto.getGender());
        user.setCity(dto.getCity());
        user.setUserType("adult");
        user.setUserSource("self_registered");
        user.setStatus("active");

        userMapper.insert(user);
        log.info("用户注册成功，ID={}, 用户名={}", user.getId(), dto.getUsername());

        return generateLoginResponse(user);
    }

    @Override
    public LoginResponseVO login(PublicLoginDTO dto) {
        // 根据用户名或手机号查询用户
        User user = userMapper.selectByUsername(dto.getUsername());
        if (user == null) {
            throw new BusinessException("用户名或密码错误");
        }

        // 验证密码
        if (!passwordEncoder.matches(dto.getPassword(), user.getPassword())) {
            throw new BusinessException("用户名或密码错误");
        }

        // 检查用户状态
        if (!"active".equals(user.getStatus())) {
            throw new BusinessException("账号已被禁用");
        }

        log.info("用户登录成功，ID={}, 用户名={}", user.getId(), user.getUsername());

        return generateLoginResponse(user);
    }

    @Override
    public PublicUserVO getUserInfo(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        return convertToPublicUserVO(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PublicUserVO updateProfile(Long userId, PublicUserUpdateDTO dto) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        if (dto.getNickname() != null) {
            user.setNickname(dto.getNickname());
        }
        if (dto.getCity() != null) {
            user.setCity(dto.getCity());
        }
        if (dto.getAvatar() != null) {
            user.setAvatar(dto.getAvatar());
        }
        if (dto.getGender() != null) {
            user.setGender(dto.getGender());
        }

        userMapper.updateById(user);
        log.info("更新用户信息成功，ID={}", userId);

        return convertToPublicUserVO(user);
    }

    @Override
    public List<ChildVO> getChildren(Long userId) {
        LambdaQueryWrapper<UserChild> wrapper = new LambdaQueryWrapper<UserChild>()
                .eq(UserChild::getParentId, userId);

        List<UserChild> userChildren = userChildMapper.selectList(wrapper);
        return userChildren.stream()
                .map(this::convertToChildVO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChildVO createChild(Long userId, CreateChildDTO dto) {
        // 检查子女用户名是否已存在
        User existingUser = userMapper.selectByUsername(dto.getUsername());
        if (existingUser != null) {
            throw new BusinessException("子女用户名已存在");
        }

        // 创建子女用户账号
        User childUser = new User();
        childUser.setTenantId(1L);
        childUser.setUsername(dto.getUsername());
        childUser.setPassword(passwordEncoder.encode(dto.getPassword()));
        childUser.setNickname(dto.getNickname());
        childUser.setGender(dto.getGender());
        childUser.setBirthday(dto.getBirthday());
        childUser.setCity(dto.getCity());
        childUser.setAvatar(dto.getAvatar());
        childUser.setUserType("child");
        childUser.setUserSource("parent_created");
        childUser.setStatus("active");

        userMapper.insert(childUser);

        // 创建亲子关系
        UserChild userChild = new UserChild();
        userChild.setParentId(userId);
        userChild.setChildUserId(childUser.getId());
        userChild.setRelationship(dto.getRelationship());
        userChild.setControlMode("full");

        userChildMapper.insert(userChild);
        log.info("创建子女成功，子女 ID={}, 父母 ID={}", childUser.getId(), userId);

        return convertToChildVO(userChild);
    }

    @Override
    public ChildVO getChild(Long userId, Long childId) {
        UserChild userChild = userChildMapper.selectById(childId);
        if (userChild == null || !userChild.getParentId().equals(userId)) {
            throw new BusinessException("子女不存在");
        }
        return convertToChildVO(userChild);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChildVO updateChild(Long userId, Long childId, UpdateChildDTO dto) {
        UserChild userChild = userChildMapper.selectById(childId);
        if (userChild == null || !userChild.getParentId().equals(userId)) {
            throw new BusinessException("子女不存在");
        }

        // 更新子女用户信息
        User childUser = userMapper.selectById(userChild.getChildUserId());
        if (childUser != null) {
            if (dto.getNickname() != null) {
                childUser.setNickname(dto.getNickname());
            }
            if (dto.getPassword() != null && !dto.getPassword().isEmpty()) {
                childUser.setPassword(passwordEncoder.encode(dto.getPassword()));
            }
            if (dto.getGender() != null) {
                childUser.setGender(dto.getGender());
            }
            if (dto.getBirthday() != null) {
                childUser.setBirthday(dto.getBirthday());
            }
            if (dto.getCity() != null) {
                childUser.setCity(dto.getCity());
            }
            if (dto.getAvatar() != null) {
                childUser.setAvatar(dto.getAvatar());
            }
            userMapper.updateById(childUser);
        }

        // 更新亲子关系信息
        if (dto.getControlMode() != null) {
            userChild.setControlMode(dto.getControlMode());
        }
        userChildMapper.updateById(userChild);

        log.info("更新子女信息成功，ID={}", childId);

        return convertToChildVO(userChild);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteChild(Long userId, Long childId) {
        UserChild userChild = userChildMapper.selectById(childId);
        if (userChild == null || !userChild.getParentId().equals(userId)) {
            throw new BusinessException("子女不存在");
        }

        // 物理删除亲子关系
        userChildMapper.deleteById(userChild);

        // 禁用子女账号
        User childUser = userMapper.selectById(userChild.getChildUserId());
        if (childUser != null) {
            childUser.setStatus("disabled");
            userMapper.updateById(childUser);
        }

        log.info("删除子女成功，ID={}", childId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChildVO createChildAccount(Long userId, CreateChildDTO dto) {
        // 这个方法与 createChild 类似，但专门用于创建独立账号
        return createChild(userId, dto);
    }

    @Override
    public List<ChildVO> getChildAccounts(Long userId) {
        return getChildren(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChildVO updateChildAccount(Long userId, Long childId, UpdateChildDTO dto) {
        return updateChild(userId, childId, dto);
    }

    @Override
    public PublicUserVO getParentInfo(Long userId) {
        return getUserInfo(userId);
    }

    @Override
    public Object getPublicActivities(Integer page, Integer pageSize, String keyword, String contestType, Long userId) {
        LambdaQueryWrapper<Contest> wrapper = new LambdaQueryWrapper<Contest>()
                .eq(Contest::getValidState, 1)
                .eq(Contest::getContestState, "published")
                .orderByDesc(Contest::getCreateTime);

        if (keyword != null && !keyword.isEmpty()) {
            wrapper.and(w -> w.like(Contest::getContestName, keyword)
                    .or().like(Contest::getContent, keyword));
        }

        if (contestType != null && !contestType.isEmpty()) {
            wrapper.eq(Contest::getContestType, contestType);
        }

        List<Contest> contests = contestMapper.selectList(wrapper);
        return contests.stream()
                .map(this::convertToActivityVO)
                .collect(Collectors.toList());
    }

    @Override
    public Object getActivityDetail(Long id) {
        Contest contest = contestMapper.selectById(id);
        if (contest == null) {
            throw new BusinessException("活动不存在");
        }
        return convertToActivityVO(contest);
    }

    // ========== 转换方法 ==========

    private LoginResponseVO generateLoginResponse(User user) {
        LoginResponseVO response = new LoginResponseVO();
        String token = jwtTokenUtil.generateToken(user.getId(), user.getUsername());
        response.setAccessToken(token);
        response.setTokenType("Bearer");
        response.setExpiresIn(7200L); // 2 小时
        response.setUser(convertToPublicUserVO(user));
        return response;
    }

    private PublicUserVO convertToPublicUserVO(User user) {
        PublicUserVO vo = new PublicUserVO();
        vo.setId(user.getId());
        vo.setUsername(user.getUsername());
        vo.setNickname(user.getNickname());
        vo.setPhone(user.getPhone());
        vo.setEmail(user.getEmail());
        vo.setAvatar(user.getAvatar());
        vo.setGender(user.getGender());
        vo.setCity(user.getCity());
        vo.setUserType(user.getUserType());
        return vo;
    }

    private ChildVO convertToChildVO(UserChild userChild) {
        ChildVO vo = new ChildVO();
        vo.setId(userChild.getChildUserId());
        vo.setParentId(userChild.getParentId());
        vo.setRelationship(userChild.getRelationship());
        vo.setControlMode(userChild.getControlMode());

        // 关联查询子女用户信息
        User childUser = userMapper.selectById(userChild.getChildUserId());
        if (childUser != null) {
            vo.setUsername(childUser.getUsername());
            vo.setNickname(childUser.getNickname());
            vo.setGender(childUser.getGender());
            vo.setBirthday(childUser.getBirthday());
            vo.setCity(childUser.getCity());
            vo.setAvatar(childUser.getAvatar());
        }

        return vo;
    }

    private Object convertToActivityVO(Contest contest) {
        // 这里简单返回 Contest 对象，实际应该转换为 ActivityVO
        return contest;
    }
}
