package cn.iocoder.yudao.module.system.service.user;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.system.controller.admin.user.dto.UserPageDTO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.factoryUser.FactoryUserPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.*;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import com.baomidou.mybatisplus.core.metadata.IPage;

import javax.validation.Valid;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 后台用户 Service 接口
 */
public interface AdminUserService {

    /**
     * 创建用户
     *
     * @param createReqVO 用户信息
     * @return 用户编号
     */
    Long createUser(@Valid UserSaveReqVO createReqVO);

    /**
     * 绑定用户微信小程序openId
     *
     * @param openId
     */
    void updateUserOpenId(Long id, String openId);

    /**
     * 修改用户
     *
     * @param updateReqVO 用户信息
     */
    void updateUser(@Valid UserSaveReqVO updateReqVO);

    /**
     * 更新用户的最后登陆信息
     *
     * @param id      用户编号
     * @param loginIp 登陆 IP
     */
    void updateUserLogin(Long id, String loginIp);

    /**
     * 修改用户个人信息
     *
     * @param id    用户编号
     * @param reqVO 用户个人信息
     */
    void updateUserProfile(Long id, @Valid UserProfileUpdateReqVO reqVO);

    /**
     * 修改用户个人密码
     *
     * @param id    用户编号
     * @param reqVO 更新用户个人密码
     */
    void updateUserPassword(Long id, @Valid UserProfileUpdatePasswordReqVO reqVO);

    /**
     * 更新用户头像
     *
     * @param id         用户 id
     * @param name       文件名
     * @param avatarFile 头像文件
     */
    String updateUserAvatar(Long id, String name, InputStream avatarFile) throws Exception;

    /**
     * 修改密码
     *
     * @param id       用户编号
     * @param password 密码
     */
    void updateUserPassword(Long id, String password);

    /**
     * 修改状态
     *
     * @param id     用户编号
     * @param status 状态
     */
    void updateUserStatus(Long id, Integer status);

    /**
     * 修改外勤打卡状态
     *
     * @param id            用户编号
     * @param fieldworkFlag 状态
     */
    void updateFieldwork(Long id, Integer fieldworkFlag);

    /**
     * 修改用户编制
     *
     * @param id            用户编号
     * @param userStaffing  编制
     */
    void updateUserStaffing(Long id, Integer userStaffing);

    /**
     * 修改外勤打卡状态
     * 用于临时开启外勤打卡
     *
     * @param id            用户编号
     * @param fieldworkFlag 状态
     */
    void updateFieldworkType(Long id, Integer fieldworkFlag);

    /**
     * 删除用户
     *
     * @param id 用户编号
     */
    void deleteUser(Long id);

    /**
     * 通过用户名查询用户
     *
     * @param username 用户名
     * @return 用户对象信息
     */
    AdminUserDO getUserByUsername(String username);

    /**
     * 通过手机号获取用户
     *
     * @param mobile 手机号
     * @return 用户对象信息
     */
    AdminUserDO getUserByMobile(String mobile);

    /**
     * 根据opneId获取用户
     *
     * @param openId 微信小程序用户唯一id
     * @return 用户对象信息
     */
    AdminUserDO getUserByOpenId(String openId);

    /**
     * 获得用户分页列表
     *
     * @param reqVO 分页条件
     * @return 分页列表
     */
    PageResult<AdminUserDO> getUserPage(UserPageReqVO reqVO);

    /**
     * gps用户全量更新
     */
    void gpsFullUserUpdate();

    /**
     * 获取工厂用户列表
     *
     * @param factoryId
     * @return
     */
    List<AdminUserDO> getFactoryUsers(Long factoryId);

    /**
     * gps用户增量更新
     *
     * @param adminUserDO
     */
    void gpsIncrementalSynchronizationOfUsers(AdminUserDO adminUserDO);

    /**
     * 获得工厂用户分页列表
     *
     * @param reqVO 分页条件
     * @return 分页列表
     */
    PageResult<AdminUserDO> getFactoryUserPage(FactoryUserPageReqVO reqVO);

    /**
     * 通过用户 ID 查询用户
     *
     * @param id 用户ID
     * @return 用户对象信息
     */
    AdminUserDO getUser(Long id);

    /**
     * 获得指定部门的用户数组
     *
     * @param deptIds 部门数组
     * @return 用户数组
     */
    List<AdminUserDO> getUserListByDeptIds(Collection<Long> deptIds, Integer status);

    /**
     * 获得指定部门组的用户数组
     *
     * @param deptIds 部门数组
     * @return 用户数组
     */
    List<UserRespVO> getUserByDeptIds(Collection<Long> deptIds);

    /**
     * 获取部门下人员过滤掉考勤组内有的
     *
     * @param deptIds
     * @param groupId
     * @return
     */
    List<UserRespVO> selectByDeptIdsFilterGroupUser(Collection<Long> deptIds, Long groupId);

    /**
     * 获得指定部门开启状态的用户数组（除去当前登录者用户）
     *
     * @param deptId 部门编号
     * @return 用户数组
     */
    List<AdminUserDO> getListUserByDeptId(Long deptId);

    /**
     * 获得指定岗位的用户数组
     *
     * @param postIds 岗位数组
     * @return 用户数组
     */
    List<AdminUserDO> getUserListByPostIds(Collection<Long> postIds);

    /**
     * 获得用户列表
     *
     * @param ids 用户编号数组
     * @return 用户列表
     */
    List<AdminUserDO> getUserList(Collection<Long> ids);

    /**
     * 校验用户们是否有效。如下情况，视为无效：
     * 1. 用户编号不存在
     * 2. 用户被禁用
     *
     * @param ids 用户编号数组
     */
    void validateUserList(Collection<Long> ids);

    /**
     * 获得用户 Map
     *
     * @param ids 用户编号数组
     * @return 用户 Map
     */
    default Map<Long, AdminUserDO> getUserMap(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return new HashMap<>();
        }
        return CollectionUtils.convertMap(getUserList(ids), AdminUserDO::getId);
    }

    Map<Long, AdminUserDO> getUserListByIds(Collection<Long> ids);

    /**
     * 获得用户列表，基于昵称模糊匹配
     *
     * @param nickname 昵称
     * @return 用户列表
     */
    List<AdminUserDO> getUserListByNickname(String nickname);

    /**
     * 批量导入用户
     *
     * @param importUsers     导入用户列表
     * @param isUpdateSupport 是否支持更新
     * @return 导入结果
     */
    UserImportRespVO importUserList(List<UserImportExcelVO> importUsers, boolean isUpdateSupport);

    /**
     * 获得指定状态的用户们
     *
     * @param userType   用户类型 1：公司用户  2：工厂用户
     * @param status
     * @return 用户们
     */
    List<AdminUserDO> getUserListByStatus(Integer userType, Integer status);

    /**
     * 判断密码是否匹配
     *
     * @param rawPassword     未加密的密码
     * @param encodedPassword 加密后的密码
     * @return 是否匹配
     */
    boolean isPasswordMatch(String rawPassword, String encodedPassword);

    /**
     * 根据部门id获取用户ids
     *
     * @param deptId
     * @return
     */
    List<Long> getUserIdsByDeptId(Long deptId);

    /**
     * 清空openId
     *
     * @param openId
     */
    void emptyOpenId(String openId);

    /**
     * 获取用户的签名图片地址
     *
     * @param userId
     * @return
     */
    String getSignImgPath(Long userId);

    /**
     * 获取 岗位为总监或副总裁 以及部门层级为2级或3级的负责人的用户编号
     *
     * @return 用户编号
     */
    List<Long> getUserByBoss();

    /**
     * 根据用户ids搜索用户列表
     *
     * @param userIds
     * @return
     */
    List<AdminUserDO> selectByUserIds(Collection<Long> userIds);

    /**
     * 获取所有用户
     *
     * @return
     */
    List<AdminUserDO> getAllList(Integer status, Integer type, List<Long> userIds);

    /**
     * 获取所有人员列表根据考勤组
     *
     * @param dto
     * @return
     */
    IPage<UserSimpleRespVO> getAllUserListByGroupIds(UserPageDTO dto);

    /**
     * 获取指令性质得用户列表
     *
     * @param userNature 用户性质
     * @return 用户列表
     */
    List<AdminUserDO> getListByNature(Integer userNature);

    /**
     * 获取指定用户编制列表
     * @param userStaffing 编制
     * @return 用户列表
     */
    List<AdminUserDO> getUserListByUserStaffing(Integer userStaffing);

    /**
     * 获得指定日期过生日的用户信息分页
     *
     * @param pageReqVO 分页信息
     * @return 用户信息分页
     */
    PageResult<UserBirthdayRespVO> getUserListByBirthday(UserBirthdayPageReqVO pageReqVO);
}
