package cn.iocoder.byzs.module.system.service.userwebexpiretime;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.byzs.framework.common.pojo.PageParam;
import cn.iocoder.byzs.framework.common.pojo.PageResult;
import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
import cn.iocoder.byzs.module.system.controller.admin.userwebexpiretime.vo.UserWebExpireTimePageReqVO;
import cn.iocoder.byzs.module.system.controller.admin.userwebexpiretime.vo.UserWebExpireTimeRespVO;
import cn.iocoder.byzs.module.system.controller.admin.userwebexpiretime.vo.UserWebExpireTimeSaveReqVO;
import cn.iocoder.byzs.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.byzs.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.byzs.module.system.dal.dataobject.userwebexpiretime.UserWebExpireTimeDO;
import cn.iocoder.byzs.module.system.dal.mysql.tenant.TenantMapper;
import cn.iocoder.byzs.module.system.dal.mysql.user.AdminUserMapper;
import cn.iocoder.byzs.module.system.dal.mysql.userwebexpiretime.UserWebExpireTimeMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.byzs.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.byzs.module.system.enums.ErrorCodeConstants.USER_WEB_EXPIRE_TIME_NOT_EXISTS;

/**
 * 用户平台权限有效期 Service 实现类
 *
 * @author lyb
 */
@Service
@Validated
public class UserWebExpireTimeServiceImpl implements UserWebExpireTimeService {

    @Resource
    private UserWebExpireTimeMapper userWebExpireTimeMapper;

    @Resource
    private AdminUserMapper userMapper;

    @Resource
    private TenantMapper tenantMapper;

    @Override
    public Long createUserWebExpireTime(UserWebExpireTimeSaveReqVO createReqVO) {
        // 插入
        UserWebExpireTimeDO userWebExpireTime = BeanUtils.toBean(createReqVO, UserWebExpireTimeDO.class);
        userWebExpireTimeMapper.insert(userWebExpireTime);
        // 返回
        return userWebExpireTime.getUserId();
    }

    @Override
    public void updateUserWebExpireTime(UserWebExpireTimeSaveReqVO updateReqVO) {
        // 校验存在
        validateUserWebExpireTimeExists(updateReqVO.getUserId());
        // 更新
        UserWebExpireTimeDO updateObj = BeanUtils.toBean(updateReqVO, UserWebExpireTimeDO.class);
        userWebExpireTimeMapper.updateById(updateObj);
    }

    @Override
    public void deleteUserWebExpireTime(Long id) {
        // 校验存在
        validateUserWebExpireTimeExists(id);
        // 删除
        userWebExpireTimeMapper.deleteById(id);
    }

    @Override
        public void deleteUserWebExpireTimeListByIds(List<Long> ids) {
        // 校验存在
        validateUserWebExpireTimeExists(ids);
        // 删除
        userWebExpireTimeMapper.deleteByIds(ids);
        }

    private void validateUserWebExpireTimeExists(List<Long> ids) {
        List<UserWebExpireTimeDO> list = userWebExpireTimeMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(USER_WEB_EXPIRE_TIME_NOT_EXISTS);
        }
    }

    private void validateUserWebExpireTimeExists(Long id) {
        if (userWebExpireTimeMapper.selectById(id) == null) {
            throw exception(USER_WEB_EXPIRE_TIME_NOT_EXISTS);
        }
    }

    @Override
    public UserWebExpireTimeDO getUserWebExpireTime(Long id) {
        return userWebExpireTimeMapper.selectById(id);
    }

    @Override
    public PageResult<UserWebExpireTimeRespVO> getUserWebExpireTimePage(UserWebExpireTimePageReqVO pageReqVO) {
        // 1. 首先查询所有符合条件的数据（不分页），因为需要进行内存筛选
        // 临时保存分页参数，查询完后恢复
        Integer originalPageSize = pageReqVO.getPageSize();
        Integer originalPageNo = pageReqVO.getPageNo();
        
        // 设置不分页，查询所有数据
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        PageResult<UserWebExpireTimeDO> userWebExpireTimeDOPageResult = userWebExpireTimeMapper.selectPage(pageReqVO);
        List<UserWebExpireTimeDO> list = userWebExpireTimeDOPageResult.getList();
        
        // 恢复分页参数
        pageReqVO.setPageSize(originalPageSize);
        pageReqVO.setPageNo(originalPageNo);

        // 2. 转换为RespVO并填充关联数据
        // 取所有用户ID
        Set<Long> userIdSet = list.stream().map(UserWebExpireTimeDO::getUserId).filter(Objects::nonNull).collect(Collectors.toSet());
        List<AdminUserDO> userList = userIdSet.isEmpty() ? Collections.emptyList() : userMapper.selectBatchIds(userIdSet);
        Map<Long, String> userMap = userList.stream().collect(Collectors.toMap(AdminUserDO::getId, AdminUserDO::getNickname));

        // 取所有租户ID
        Set<Long> tenantIdSet = userList.stream().map(AdminUserDO::getTenantId).filter(Objects::nonNull).collect(Collectors.toSet());
        List<TenantDO> tenantList = tenantIdSet.isEmpty() ? Collections.emptyList() : tenantMapper.selectBatchIds(tenantIdSet);
        Map<Long, String> tenantMap = tenantList.stream().collect(Collectors.toMap(TenantDO::getId, TenantDO::getName));

        // 转换为RespVO
        List<UserWebExpireTimeRespVO> respVOList = list.stream().map(userWebExpireTime -> {
            UserWebExpireTimeRespVO respVO = BeanUtils.toBean(userWebExpireTime, UserWebExpireTimeRespVO.class);

            // 填充用户名
            if (userWebExpireTime.getUserId() != null) {
                respVO.setUserName(userMap.get(userWebExpireTime.getUserId()));
                // 填充租户名称
                AdminUserDO user = userList.stream().filter(u -> u.getId().equals(userWebExpireTime.getUserId())).findFirst().orElse(null);
                if (user != null && user.getTenantId() != null) {
                    respVO.setTenantName(tenantMap.get(user.getTenantId()));
                }
            }

            return respVO;
        }).collect(Collectors.toList());

        // 3. 进行内存筛选
        List<UserWebExpireTimeRespVO> filteredRespVOList = respVOList;

        // 按用户名筛选
        if (pageReqVO.getUserName() != null && !pageReqVO.getUserName().isEmpty()) {
            filteredRespVOList = filteredRespVOList.stream()
                    .filter(respVO -> {
                        if (respVO.getUserName() == null) {
                            return false;
                        }
                        return respVO.getUserName().contains(pageReqVO.getUserName());
                    })
                    .collect(Collectors.toList());
        }

        // 按租户名称筛选
        if (pageReqVO.getTenantName() != null && !pageReqVO.getTenantName().isEmpty()) {
            filteredRespVOList = filteredRespVOList.stream()
                    .filter(respVO -> {
                        if (respVO.getTenantName() == null) {
                            return false;
                        }
                        return respVO.getTenantName().contains(pageReqVO.getTenantName());
                    })
                    .collect(Collectors.toList());
        }

        // 4. 对筛选后的结果进行分页
        int pageNo = pageReqVO.getPageNo();
        int pageSize = pageReqVO.getPageSize();
        int total = filteredRespVOList.size();
        
        // 计算分页起始位置
        int start = (pageNo - 1) * pageSize;
        int end = Math.min(start + pageSize, total);
        
        // 截取当前页数据
        List<UserWebExpireTimeRespVO> pagedList = (start < end) ? filteredRespVOList.subList(start, end) : Collections.emptyList();

        // 5. 返回正确的分页结果
        return new PageResult<>(pagedList, (long) total);
    }

}