package com.gxwebsoft.common.system.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.common.system.param.LoginParam;
import com.gxwebsoft.common.system.param.UserParam;
import org.springframework.security.core.userdetails.UserDetailsService;

import java.util.List;

/**
 * 用户Service
 *
 * @author WebSoft
 * @since 2018-12-24 16:10:52
 */
public interface UserService extends IService<User>, UserDetailsService {

    /**
     * 关联分页查询用户
     *
     * @param param 查询参数
     * @return PageResult<User>
     */
    PageResult<User> pageRel(UserParam param);

    /**
     * 关联查询全部用户
     *
     * @param param 查询参数
     * @return List<User>
     */
    List<User> listRel(UserParam param);

    /**
     * 根据id查询用户
     *
     * @param userId 用户id
     * @return User
     */
    User getByIdRel(Integer userId);

    /**
     * 根据账号查询用户
     *
     * @param username 账号
     * @return User
     */
    User getByUsername(String username);

    /**
     * 根据账号查询用户
     *
     * @param username 账号
     * @param tenantId 租户id
     * @return User
     */
    User getByUsername(String username, Integer tenantId);

    User getByUsernamePhone(String username, Integer tenantId);

    /**
     * 添加用户
     *
     * @param user 用户信息
     * @return boolean
     */
    boolean saveUser(User user);

    /**
     * 修改用户
     *
     * @param user 用户信息
     * @return boolean
     */
    boolean updateUser(User user);

    /**
     * 将用户标记为开发者（审核通过时调用，直接更新用户标记位，不新增角色）
     *
     * @param userId 用户id
     * @return boolean
     */
    boolean markAsDeveloper(Integer userId);

    /**
     * 比较用户密码
     *
     * @param dbPassword    数据库存储的密码
     * @param inputPassword 用户输入的密码
     * @return boolean
     */
    boolean comparePassword(String dbPassword, String inputPassword);

    /**
     * md5加密用户密码
     *
     * @param password 密码明文
     * @return 密文
     */
    String encodePassword(String password);

    /**
     * 跟进手机号码查询用户
     * @param phone 手机号码
     * @return 用户信息
     */
    User getByPhone(String phone);

    User getByPhone(String phone,Integer tenantId);

    User getByUnionId(UserParam userParam);

    User getByOauthId(UserParam userParam);

    List<User> listStatisticsRel(UserParam param);

    /**
     * 更新会员不限租户
     * @param user 用户信息
     */
    void updateByUserId(User user);

    User addUser(UserParam userParam);

    User getAdminByPhone(UserParam param);

    User getAdminByPhone(UserParam param,Integer tenantId);

    User getAllByUserId(String userId);

    Integer userNumInPark(UserParam param);

    Integer orgNumInPark(UserParam param);

    List<User> getAdminsByPhone(LoginParam param);

    /**
     * 根据手机号查询最近登录的超级管理员账号（忽略租户隔离）
     *
     * @param phone 手机号
     * @return 用户信息
     */
    User getLastLoginSuperAdminByPhone(String phone);

    /**
     * 根据手机号查询最近登录的开发者账号（忽略租户隔离）
     *
     * @param phone 手机号
     * @return 用户信息
     */
    User getLastLoginDeveloperByPhone(String phone);

    /**
     * 根据手机号查询管理员账号（跨租户：超级管理员或普通管理员均可，忽略租户隔离）
     *
     * @param phone 手机号
     * @return 用户信息
     */
    User getByPhoneAndAdmin(String phone);

    /**
     * 根据手机号查询所有超级管理员账号（跨租户，忽略租户隔离）
     * 用于多租户登录：手机号关联多个租户时返回列表供用户选择
     *
     * @param phone 手机号
     * @return List<User>
     */
    List<User> getSuperAdminsByPhone(String phone);

    /**
     * 根据手机号和租户ID查询超级管理员账号（跨租户，忽略租户隔离）
     * 用于多租户登录：用户选择租户后，查询该租户下的超级管理员
     *
     * @param phone 手机号
     * @param tenantId 租户ID
     * @return User
     */
    User getSuperAdminByPhoneAndTenantId(String phone, Integer tenantId);

    List<User> pageAll(UserParam param);

    User getByUserId(String userId);

    /**
     * 根据手机号查询所有账号（忽略租户隔离）
     *
     * @param phone 手机号
     * @return List<User>
     */
    List<User> findAccountsByPhone(String phone);

    /**
     * 根据邮箱查询所有账号（忽略租户隔离，用于跨租户登录）
     *
     * @param email 邮箱
     * @return List<User>
     */
    List<User> findAccountsByEmail(String email);

    /**
     * 根据手机号统计账号数量
     *
     * @param phone 手机号
     * @return Integer
     */
    Integer countAccountsByPhone(String phone);

    /**
     * 重置用户密码
     *
     * @param userId      用户ID
     * @param tenantId    租户ID
     * @param newPassword 新密码（明文）
     * @return boolean
     */
    boolean resetUserPassword(String userId, Integer tenantId, String newPassword);
}
