package com.fuyuanshen.mp.service;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fuyuanshen.app.domain.vo.AppUserVo;
import com.fuyuanshen.app.service.IAppRoleService;
import com.fuyuanshen.common.core.constant.Constants;
import com.fuyuanshen.common.core.constant.SystemConstants;
import com.fuyuanshen.common.core.constant.TenantConstants;
import com.fuyuanshen.common.core.domain.dto.PostDTO;
import com.fuyuanshen.common.core.domain.dto.RoleDTO;
import com.fuyuanshen.common.core.domain.model.AppLoginUser;
import com.fuyuanshen.common.core.domain.model.LoginUser;
import com.fuyuanshen.common.core.domain.model.PasswordLoginBody;
import com.fuyuanshen.common.core.domain.model.RegisterBody;
import com.fuyuanshen.common.core.enums.LoginType;
import com.fuyuanshen.common.core.enums.UserType;
import com.fuyuanshen.common.core.exception.user.UserException;
import com.fuyuanshen.common.core.utils.*;
import com.fuyuanshen.common.json.utils.JsonUtils;
import com.fuyuanshen.common.log.event.LogininforEvent;
import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.common.tenant.exception.TenantException;
import com.fuyuanshen.common.tenant.helper.TenantHelper;
import com.fuyuanshen.equipment.domain.Device;
import com.fuyuanshen.equipment.domain.UserApp;
import com.fuyuanshen.equipment.service.AppUserService;
import com.fuyuanshen.system.domain.SysUser;
import com.fuyuanshen.system.domain.bo.SysUserBo;
import com.fuyuanshen.system.domain.vo.*;
import com.fuyuanshen.system.service.ISysTenantService;
import com.fuyuanshen.system.service.ISysUserService;
import com.fuyuanshen.web.domain.vo.LoginVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.*;
import java.util.function.Supplier;

/**
 * 登录校验方法
 *
 * @author Lion Li
 */

@RequiredArgsConstructor
@Slf4j
@Service
public class MPAuthService {

    private final ISysUserService userService;
    private final AppUserService appUserService;

    /**
     * 小程序注册
     */
    public void register(RegisterBody registerBody) {
        String tenantId = registerBody.getTenantId();
        String username = registerBody.getUsername();
        String password = registerBody.getPassword();
        // 校验用户类型是否存在
        String userType = UserType.getUserType(registerBody.getUserType()).getUserType();

        UserApp sysUser = new UserApp();
        sysUser.setUserName(username);
        sysUser.setNickName(username);
        sysUser.setPhonenumber(username);
        sysUser.setTenantId(tenantId);
        sysUser.setUserType(registerBody.getUserType());
        sysUser.setPassword(BCrypt.hashpw(password));
        sysUser.setUserType(userType);

        appUserService.saveMpUser(sysUser);

    }


    /**
     * 记录登录信息
     *
     * @param tenantId 租户ID
     * @param username 用户名
     * @param status   状态
     * @param message  消息内容
     * @return
     */
    private void recordLogininfor(String tenantId, String username, String status, String message) {
        LogininforEvent logininforEvent = new LogininforEvent();
        logininforEvent.setTenantId(tenantId);
        logininforEvent.setUsername(username);
        logininforEvent.setStatus(status);
        logininforEvent.setMessage(message);
        logininforEvent.setRequest(ServletUtils.getRequest());
        // com.fuyuanshen.web.listener.UserActionListener
        SpringUtils.context().publishEvent(logininforEvent);
    }


    public LoginVo login(LoginUser loginUser, SysClientVo client) {
        loginUser.setClientKey(client.getClientKey());
        loginUser.setDeviceType(client.getDeviceType());
        SaLoginParameter model = new SaLoginParameter();
        model.setDeviceType(client.getDeviceType());
        // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
        // 例如: 后台用户30分钟过期 app用户1天过期
        model.setTimeout(client.getTimeout());
        model.setActiveTimeout(client.getActiveTimeout());
        model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
        // 生成token
        LoginHelper.login(loginUser, model);

        LoginVo loginVo = new LoginVo();
        loginVo.setAccessToken(StpUtil.getTokenValue());
        loginVo.setExpireIn(StpUtil.getTokenTimeout());
        loginVo.setClientId(client.getClientId());
        return loginVo;
    }

    /**
     * 构建登录用户
     */
    public LoginUser buildLoginUser(UserApp user) {
        LoginUser loginUser = new LoginUser();
        Long userId = user.getUserId();
        loginUser.setTenantId(user.getTenantId());
        loginUser.setUserId(userId);
        loginUser.setDeptId(user.getDeptId());
        loginUser.setUsername(user.getUserName());
        loginUser.setNickname(user.getNickName());
        loginUser.setUserType(user.getUserType());
        // 用户级别
        // loginUser.setUserLevel(user.getUserLevel());
        // pid
        // loginUser.setPid(user.getPid());

        // loginUser.setMenuPermission(permissionService.getMenuPermission(userId));
        // loginUser.setRolePermission(permissionService.getRolePermission(userId));
        // if (ObjectUtil.isNotNull(user.getDeptId())) {
        //     Opt<SysDeptVo> deptOpt = Opt.of(user.getDeptId()).map(deptService::selectDeptById);
        //     loginUser.setDeptName(deptOpt.map(SysDeptVo::getDeptName).orElse(StringUtils.EMPTY));
        //     loginUser.setDeptCategory(deptOpt.map(SysDeptVo::getDeptCategory).orElse(StringUtils.EMPTY));
        // }
        // List<SysRoleVo> roles = roleService.selectRolesByUserId(userId);
        // // List<SysPostVo> posts = postService.selectPostsByUserId(userId);
        // loginUser.setRoles(BeanUtil.copyToList(roles, RoleDTO.class));
        // loginUser.setPosts(BeanUtil.copyToList(posts, PostDTO.class));
        return loginUser;
    }



}
