package com.yaoai.admin.user;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yaoai.admin.common.PageResult;
import com.yaoai.admin.user.dto.ResetPasswordResponse;
import com.yaoai.admin.user.dto.UserQuery;
import com.yaoai.admin.user.dto.UserStatusRequest;
import com.yaoai.common.exception.BizException;
import com.yaoai.common.exception.ErrorCode;
import com.yaoai.domain.entity.User;
import com.yaoai.domain.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

@Service
@RequiredArgsConstructor
public class UserAdminService {

    private final UserMapper userMapper;

    public PageResult<User> list(UserQuery query) {
        long page = Math.max(1, query.getPage());
        long size = Math.max(1, Math.min(query.getSize(), 100));
        long offset = (page - 1) * size;
        long total = userMapper.selectCount(buildQuery(query));
        return new PageResult<>(
                userMapper.selectList(buildQuery(query)
                        .orderByDesc(User::getCreatedAt)
                        .last("LIMIT " + size + " OFFSET " + offset)),
                total,
                page,
                size);
    }

    public User detail(Long id) {
        return requireUser(id);
    }

    @Transactional
    public User updateStatus(Long id, UserStatusRequest request) {
        User user = requireUser(id);
        if (request.getStatus() == null || (request.getStatus() != 0 && request.getStatus() != 1)) {
            throw new BizException(ErrorCode.INVALID_PARAM, "用户状态必须为 0 或 1");
        }
        user.setStatus(request.getStatus());
        user.setUpdatedAt(LocalDateTime.now());
        userMapper.updateById(user);
        if (request.getStatus() == 0) {
            StpUtil.kickout(id);
        }
        return userMapper.selectById(id);
    }

    public void kickout(Long id) {
        requireUser(id);
        StpUtil.kickout(id);
    }

    @Transactional
    public ResetPasswordResponse resetPassword(Long id) {
        User user = requireUser(id);
        String password = "YaoAI-" + RandomUtil.randomString(10);
        user.setPasswordHash(BCrypt.hashpw(password, BCrypt.gensalt()));
        user.setUpdatedAt(LocalDateTime.now());
        userMapper.updateById(user);
        StpUtil.kickout(id);
        return new ResetPasswordResponse(password);
    }

    private LambdaQueryWrapper<User> buildQuery(UserQuery query) {
        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery()
                .isNull(User::getDeletedAt);
        if (query.getTenantId() != null) {
            wrapper.eq(User::getTenantId, query.getTenantId());
        }
        if (query.getStatus() != null) {
            wrapper.eq(User::getStatus, query.getStatus());
        }
        if (StringUtils.hasText(query.getKeyword())) {
            wrapper.and(w -> w.like(User::getEmail, query.getKeyword())
                    .or()
                    .like(User::getUsername, query.getKeyword())
                    .or()
                    .like(User::getPhone, query.getKeyword()));
        }
        return wrapper;
    }

    private User requireUser(Long id) {
        User user = userMapper.selectOne(Wrappers.<User>lambdaQuery()
                .eq(User::getId, id)
                .isNull(User::getDeletedAt));
        if (user == null) {
            throw new BizException(ErrorCode.NOT_FOUND, "用户不存在");
        }
        return user;
    }
}
