package com.lesingle.creation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lesingle.creation.common.enums.ContestTypeEnum;
import com.lesingle.creation.dto.team.*;
import com.lesingle.creation.entity.*;
import com.lesingle.creation.common.exception.BusinessException;
import com.lesingle.creation.mapper.*;
import com.lesingle.creation.service.ContestTeamService;
import com.lesingle.creation.vo.team.TeamMemberVO;
import com.lesingle.creation.vo.team.TeamVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 竞赛团队服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ContestTeamServiceImpl implements ContestTeamService {

    private final ContestTeamMapper teamMapper;
    private final ContestMapper contestMapper;
    private final UserMapper userMapper;
    private final ContestTeamMemberMapper memberMapper;
    private final ContestRegistrationMapper registrationMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TeamVO create(CreateTeamDTO dto, Long tenantId, Long creatorId) {
        // 验证活动是否存在
        Contest contest = contestMapper.selectById(dto.getContestId());
        if (contest == null) {
            throw new BusinessException("活动不存在");
        }

        // 检查活动类型
        if (!ContestTypeEnum.TEAM.getCode().equals(contest.getContestType())) {
            throw new BusinessException("该活动不是团队参与");
        }

        // 检查团队名称是否已存在（同一活动、同一租户内）
        ContestTeam existing = teamMapper.selectOne(new LambdaQueryWrapper<ContestTeam>()
                .eq(ContestTeam::getTenantId, tenantId)
                .eq(ContestTeam::getContestId, dto.getContestId())
                .eq(ContestTeam::getTeamName, dto.getTeamName())
                .eq(ContestTeam::getValidState, 1)
                .eq(ContestTeam::getDeleted, 0));
        if (existing != null) {
            throw new BusinessException("团队名称已存在");
        }

        // 验证队长用户是否存在
        User leader = userMapper.selectById(dto.getLeaderId());
        if (leader == null) {
            throw new BusinessException("队长用户不存在");
        }

        // 创建团队
        ContestTeam team = new ContestTeam();
        team.setTenantId(tenantId);
        team.setContestId(dto.getContestId());
        team.setTeamName(dto.getTeamName());
        team.setLeaderUserId(dto.getLeaderId());
        team.setMaxMembers(dto.getMaxMembers());
        team.setValidState(1);

        teamMapper.insert(team);

        // 自动添加队长为成员
        ContestTeamMember leaderMember = new ContestTeamMember();
        leaderMember.setTenantId(tenantId);
        leaderMember.setTeamId(team.getId());
        leaderMember.setUserId(dto.getLeaderId());
        leaderMember.setRole("leader");
        memberMapper.insert(leaderMember);

        // 添加其他队员（排除队长）
        if (dto.getMemberIds() != null && !dto.getMemberIds().isEmpty()) {
            for (Long memberId : dto.getMemberIds()) {
                if (!memberId.equals(dto.getLeaderId())) {
                    ContestTeamMember member = new ContestTeamMember();
                    member.setTenantId(tenantId);
                    member.setTeamId(team.getId());
                    member.setUserId(memberId);
                    member.setRole("member");
                    memberMapper.insert(member);
                }
            }
        }

        // 添加指导老师
        if (dto.getTeacherIds() != null && !dto.getTeacherIds().isEmpty()) {
            for (Long teacherId : dto.getTeacherIds()) {
                ContestTeamMember teacherMember = new ContestTeamMember();
                teacherMember.setTenantId(tenantId);
                teacherMember.setTeamId(team.getId());
                teacherMember.setUserId(teacherId);
                teacherMember.setRole("mentor");
                memberMapper.insert(teacherMember);
            }
        }

        // 自动创建团队报名记录
        String accountNo = leader.getUsername();
        String accountName = leader.getNickname();

        ContestRegistration registration = new ContestRegistration();
        registration.setContestId(dto.getContestId());
        registration.setTenantId(tenantId);
        registration.setRegistrationType("team");
        registration.setTeamId(team.getId());
        registration.setTeamName(dto.getTeamName());
        registration.setUserId(dto.getLeaderId());
        registration.setAccountNo(accountNo);
        registration.setAccountName(accountName);
        registration.setRegistrationState("pending");
        registration.setRegistrant(dto.getLeaderId());
        if (creatorId != null) {
            registration.setCreateBy(creatorId.toString());
        }

        registrationMapper.insert(registration);

        log.info("创建团队成功，ID={}, 名称={}", team.getId(), dto.getTeamName());

        return convertToVO(team, contest.getContestName());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TeamVO update(Long id, UpdateTeamDTO dto, Long tenantId) {
        ContestTeam team = teamMapper.selectById(id);
        if (team == null || !team.getTenantId().equals(tenantId)) {
            throw new BusinessException("团队不存在");
        }

        team.setTeamName(dto.getTeamName());
        team.setMaxMembers(dto.getMaxMembers());

        // 更新队员
        if (dto.getMemberIds() != null && !dto.getMemberIds().isEmpty()) {
            // 删除原有队员（保留队长和指导老师）
            memberMapper.delete(new LambdaQueryWrapper<ContestTeamMember>()
                    .eq(ContestTeamMember::getTeamId, id)
                    .eq(ContestTeamMember::getRole, "member"));

            // 添加新队员
            for (Long memberId : dto.getMemberIds()) {
                ContestTeamMember member = new ContestTeamMember();
                member.setTenantId(tenantId);
                member.setTeamId(id);
                member.setUserId(memberId);
                member.setRole("member");
                memberMapper.insert(member);
            }
        }

        // 更新指导老师
        if (dto.getTeacherIds() != null && !dto.getTeacherIds().isEmpty()) {
            // 删除原有指导老师
            memberMapper.delete(new LambdaQueryWrapper<ContestTeamMember>()
                    .eq(ContestTeamMember::getTeamId, id)
                    .eq(ContestTeamMember::getRole, "mentor"));

            // 添加新指导老师
            for (Long teacherId : dto.getTeacherIds()) {
                ContestTeamMember teacherMember = new ContestTeamMember();
                teacherMember.setTenantId(tenantId);
                teacherMember.setTeamId(id);
                teacherMember.setUserId(teacherId);
                teacherMember.setRole("mentor");
                memberMapper.insert(teacherMember);
            }
        }

        teamMapper.updateById(team);
        log.info("更新团队成功，ID={}", id);

        Contest contest = contestMapper.selectById(team.getContestId());
        return convertToVO(team, contest != null ? contest.getContestName() : null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id, Long tenantId) {
        ContestTeam team = teamMapper.selectById(id);
        if (team == null || !team.getTenantId().equals(tenantId)) {
            throw new BusinessException("团队不存在");
        }

        // 检查是否有作品
        // 简化处理，直接逻辑删除团队和成员

        team.setValidState(2);
        teamMapper.updateById(team);

        // 删除团队成员
        memberMapper.delete(new LambdaQueryWrapper<ContestTeamMember>()
                .eq(ContestTeamMember::getTeamId, id));

        log.info("删除团队成功，ID={}", id);
    }

    @Override
    public TeamVO getDetail(Long id, Long tenantId) {
        ContestTeam team = teamMapper.selectById(id);
        if (team == null || !team.getTenantId().equals(tenantId)) {
            throw new BusinessException("团队不存在");
        }

        Contest contest = contestMapper.selectById(team.getContestId());
        return convertToVO(team, contest != null ? contest.getContestName() : null);
    }

    @Override
    public List<TeamVO> list(Long contestId, Long tenantId) {
        List<ContestTeam> teams = teamMapper.selectList(new LambdaQueryWrapper<ContestTeam>()
                .eq(ContestTeam::getTenantId, tenantId)
                .eq(contestId != null, ContestTeam::getContestId, contestId)
                .eq(ContestTeam::getValidState, 1)
                .eq(ContestTeam::getDeleted, 0)
                .orderByDesc(ContestTeam::getCreateTime));

        return teams.stream()
                .map(team -> convertToVO(team, null))
                .collect(Collectors.toList());
    }

    @Override
    public List<TeamVO> listByContest(Long contestId, Long tenantId) {
        log.info("按竞赛查询团队列表，活动 ID: {}", contestId);

        List<ContestTeam> teams = teamMapper.selectList(new LambdaQueryWrapper<ContestTeam>()
                .eq(ContestTeam::getTenantId, tenantId)
                .eq(ContestTeam::getContestId, contestId)
                .eq(ContestTeam::getValidState, 1)
                .eq(ContestTeam::getDeleted, 0)
                .orderByDesc(ContestTeam::getCreateTime));

        return teams.stream()
                .map(team -> convertToVO(team, null))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void inviteMember(Long teamId, InviteMemberDTO dto, Long tenantId, Long creatorId) {
        ContestTeam team = teamMapper.selectById(teamId);
        if (team == null || !team.getTenantId().equals(tenantId)) {
            throw new BusinessException("团队不存在");
        }

        // 检查成员是否已满
        Long currentCount = memberMapper.selectCount(new LambdaQueryWrapper<ContestTeamMember>()
                .eq(ContestTeamMember::getTeamId, teamId)
                .in(ContestTeamMember::getRole, "leader", "member"));
        if (currentCount >= team.getMaxMembers()) {
            throw new BusinessException("团队成员已满");
        }

        // 检查用户是否已是成员
        ContestTeamMember existing = memberMapper.selectOne(new LambdaQueryWrapper<ContestTeamMember>()
                .eq(ContestTeamMember::getTeamId, teamId)
                .eq(ContestTeamMember::getUserId, dto.getUserId()));
        if (existing != null) {
            throw new BusinessException("该用户已是团队成员");
        }

        ContestTeamMember member = new ContestTeamMember();
        member.setTenantId(tenantId);
        member.setTeamId(teamId);
        member.setUserId(dto.getUserId());
        member.setRole(dto.getRole());

        memberMapper.insert(member);
        log.info("邀请成员成功，团队 ID={}, 用户 ID={}", teamId, dto.getUserId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeMember(Long teamId, Long userId, Long tenantId) {
        ContestTeamMember member = memberMapper.selectOne(new LambdaQueryWrapper<ContestTeamMember>()
                .eq(ContestTeamMember::getTeamId, teamId)
                .eq(ContestTeamMember::getUserId, userId));

        if (member == null) {
            throw new BusinessException("成员不在该团队中");
        }

        // 队长不能移除
        if ("leader".equals(member.getRole())) {
            throw new BusinessException("队长不能移除");
        }

        memberMapper.deleteById(member.getId());
        log.info("移除成员成功，团队 ID={}, 用户 ID={}", teamId, userId);
    }

    @Override
    public TeamVO getMyTeam(Long contestId, Long userId, Long tenantId) {
        // 查询用户所在的团队
        List<ContestTeamMember> memberships = memberMapper.selectList(new LambdaQueryWrapper<ContestTeamMember>()
                .eq(ContestTeamMember::getUserId, userId));

        for (ContestTeamMember membership : memberships) {
            ContestTeam team = teamMapper.selectById(membership.getTeamId());
            if (team != null && team.getContestId().equals(contestId) && team.getTenantId().equals(tenantId)) {
                Contest contest = contestMapper.selectById(team.getContestId());
                return convertToVO(team, contest != null ? contest.getContestName() : null);
            }
        }

        return null;
    }

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

    private TeamVO convertToVO(ContestTeam team, String contestName) {
        TeamVO vo = new TeamVO();
        vo.setId(team.getId());
        vo.setTenantId(team.getTenantId());
        vo.setContestId(team.getContestId());
        vo.setContestName(contestName);
        vo.setTeamName(team.getTeamName());
        vo.setLeaderUserId(team.getLeaderUserId());
        vo.setMaxMembers(team.getMaxMembers());
        vo.setValidState(team.getValidState());
        vo.setCreateTime(team.getCreateTime());

        // 获取队长姓名
        User leader = userMapper.selectById(team.getLeaderUserId());
        if (leader != null) {
            vo.setLeaderName(leader.getNickname());
        }

        // 获取成员列表
        List<ContestTeamMember> members = memberMapper.selectList(new LambdaQueryWrapper<ContestTeamMember>()
                .eq(ContestTeamMember::getTeamId, team.getId()));

        List<TeamMemberVO> memberVOs = new ArrayList<>();
        int currentCount = 0;
        for (ContestTeamMember member : members) {
            TeamMemberVO memberVO = new TeamMemberVO();
            memberVO.setId(member.getId());
            memberVO.setTeamId(team.getId());
            memberVO.setUserId(member.getUserId());
            memberVO.setRole(member.getRole());

            User memberUser = userMapper.selectById(member.getUserId());
            if (memberUser != null) {
                memberVO.setUserName(memberUser.getNickname());
            }

            memberVOs.add(memberVO);

            if ("leader".equals(member.getRole()) || "member".equals(member.getRole())) {
                currentCount++;
            }
        }
        vo.setCurrentMembers(currentCount);
        vo.setMembers(memberVOs);

        return vo;
    }
}
