package com.yaoai.api.controller;

import cn.hutool.crypto.digest.BCrypt;
import com.yaoai.api.dto.team.TeamGroupDTO;
import com.yaoai.api.dto.team.TeamMemberDTO;
import com.yaoai.common.exception.BizException;
import com.yaoai.common.exception.ErrorCode;
import com.yaoai.common.response.ApiResponse;
import com.yaoai.domain.entity.TeamGroup;
import com.yaoai.domain.entity.TenantMember;
import com.yaoai.domain.entity.User;
import com.yaoai.domain.mapper.TeamGroupMapper;
import com.yaoai.domain.mapper.TenantMemberMapper;
import com.yaoai.domain.mapper.UserMapper;
import com.yaoai.security.context.TenantContext;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Tag(name = "团队管理")
@RestController
@RequestMapping("/team")
@RequiredArgsConstructor
public class TeamController {

    private final UserMapper userMapper;
    private final TenantMemberMapper tenantMemberMapper;
    private final TeamGroupMapper teamGroupMapper;

    // ---- Members ----

    @Operation(summary = "获取团队成员列表")
    @GetMapping("/members")
    public ApiResponse<List<TeamMemberDTO>> listMembers() {
        Long tenantId = TenantContext.get();
        List<TenantMember> members = tenantMemberMapper.findByTenant(tenantId);
        List<TeamMemberDTO> result = members.stream().map(m -> {
            User user = userMapper.selectById(m.getUserId());
            return user != null ? TeamMemberDTO.from(user, m) : null;
        }).filter(java.util.Objects::nonNull).toList();
        return ApiResponse.success(result);
    }

    @Operation(summary = "添加成员（管理员创建账号）")
    @PostMapping("/members")
    public ApiResponse<TeamMemberDTO> addMember(@RequestBody Map<String, String> body) {
        Long tenantId = TenantContext.get();
        String username = body.get("username");
        String email = body.get("email");
        String password = body.get("password");
        String role = body.getOrDefault("role", "member");
        String position = body.get("position");

        if (username == null || email == null || password == null) {
            throw new BizException(ErrorCode.INVALID_PARAM, "username/email/password 必填");
        }
        if (userMapper.existsByEmail(email)) {
            throw new BizException(ErrorCode.INVALID_PARAM, "该邮箱已被使用");
        }

        User user = new User();
        user.setTenantId(tenantId);
        user.setUsername(username);
        user.setEmail(email);
        user.setPasswordHash(BCrypt.hashpw(password, BCrypt.gensalt()));
        user.setRole(role);
        user.setStatus(1);
        userMapper.insert(user);

        TenantMember member = new TenantMember();
        member.setTenantId(tenantId);
        member.setUserId(user.getId());
        member.setRole(role);
        member.setPosition(position);
        member.setJoinedAt(LocalDateTime.now());
        tenantMemberMapper.insert(member);

        return ApiResponse.success(TeamMemberDTO.from(user, member));
    }

    @Operation(summary = "更新成员角色/职位")
    @PutMapping("/members/{userId}")
    public ApiResponse<TeamMemberDTO> updateMember(@PathVariable Long userId,
                                                    @RequestBody Map<String, String> body) {
        Long tenantId = TenantContext.get();
        TenantMember member = tenantMemberMapper.findByTenantAndUser(tenantId, userId)
                .orElseThrow(() -> new BizException(ErrorCode.NOT_FOUND, "成员不存在"));

        if (body.containsKey("role")) member.setRole(body.get("role"));
        if (body.containsKey("position")) member.setPosition(body.get("position"));
        tenantMemberMapper.updateById(member);

        User user = userMapper.selectById(userId);
        return ApiResponse.success(TeamMemberDTO.from(user, member));
    }

    @Operation(summary = "移除成员")
    @DeleteMapping("/members/{userId}")
    public ApiResponse<Void> removeMember(@PathVariable Long userId) {
        Long tenantId = TenantContext.get();
        TenantMember member = tenantMemberMapper.findByTenantAndUser(tenantId, userId)
                .orElseThrow(() -> new BizException(ErrorCode.NOT_FOUND, "成员不存在"));
        if ("owner".equals(member.getRole())) {
            throw new BizException(ErrorCode.INVALID_PARAM, "不能移除 owner");
        }
        tenantMemberMapper.deleteById(member.getId());
        return ApiResponse.success();
    }

    // ---- Groups ----

    @Operation(summary = "获取小组列表")
    @GetMapping("/groups")
    public ApiResponse<List<TeamGroupDTO>> listGroups() {
        Long tenantId = TenantContext.get();
        List<TeamGroup> groups = teamGroupMapper.findByTenant(tenantId);
        List<TeamGroupDTO> result = groups.stream()
                .map(g -> TeamGroupDTO.from(g, teamGroupMapper.findMemberIds(g.getId())))
                .toList();
        return ApiResponse.success(result);
    }

    @Operation(summary = "创建小组")
    @PostMapping("/groups")
    public ApiResponse<TeamGroupDTO> createGroup(@RequestBody Map<String, String> body) {
        Long tenantId = TenantContext.get();
        TeamGroup group = new TeamGroup();
        group.setTenantId(tenantId);
        group.setName(body.getOrDefault("name", "未命名小组"));
        group.setDescription(body.get("description"));
        teamGroupMapper.insert(group);
        return ApiResponse.success(TeamGroupDTO.from(group, List.of()));
    }

    @Operation(summary = "更新小组")
    @PutMapping("/groups/{groupId}")
    public ApiResponse<TeamGroupDTO> updateGroup(@PathVariable Long groupId,
                                                  @RequestBody Map<String, String> body) {
        Long tenantId = TenantContext.get();
        TeamGroup group = teamGroupMapper.selectById(groupId);
        if (group == null || !tenantId.equals(group.getTenantId())) {
            throw new BizException(ErrorCode.NOT_FOUND, "小组不存在");
        }
        if (body.containsKey("name")) group.setName(body.get("name"));
        if (body.containsKey("description")) group.setDescription(body.get("description"));
        teamGroupMapper.updateById(group);
        return ApiResponse.success(TeamGroupDTO.from(group, teamGroupMapper.findMemberIds(groupId)));
    }

    @Operation(summary = "删除小组")
    @DeleteMapping("/groups/{groupId}")
    public ApiResponse<Void> deleteGroup(@PathVariable Long groupId) {
        Long tenantId = TenantContext.get();
        TeamGroup group = teamGroupMapper.selectById(groupId);
        if (group == null || !tenantId.equals(group.getTenantId())) {
            throw new BizException(ErrorCode.NOT_FOUND, "小组不存在");
        }
        teamGroupMapper.removeAllMembers(groupId);
        teamGroupMapper.deleteById(groupId);
        return ApiResponse.success();
    }

    @Operation(summary = "添加小组成员")
    @PostMapping("/groups/{groupId}/members/{userId}")
    public ApiResponse<Void> addGroupMember(@PathVariable Long groupId, @PathVariable Long userId) {
        Long tenantId = TenantContext.get();
        TeamGroup group = teamGroupMapper.selectById(groupId);
        if (group == null || !tenantId.equals(group.getTenantId())) {
            throw new BizException(ErrorCode.NOT_FOUND, "小组不存在");
        }
        teamGroupMapper.addMember(groupId, userId);
        return ApiResponse.success();
    }

    @Operation(summary = "移除小组成员")
    @DeleteMapping("/groups/{groupId}/members/{userId}")
    public ApiResponse<Void> removeGroupMember(@PathVariable Long groupId, @PathVariable Long userId) {
        Long tenantId = TenantContext.get();
        TeamGroup group = teamGroupMapper.selectById(groupId);
        if (group == null || !tenantId.equals(group.getTenantId())) {
            throw new BizException(ErrorCode.NOT_FOUND, "小组不存在");
        }
        teamGroupMapper.removeMember(groupId, userId);
        return ApiResponse.success();
    }
}
