package com.auth.module.security.service.impl;


import com.auth.common.model.common.result.ResultCodeEnum;
import com.auth.common.model.enums.LoginEnums;
import com.auth.dao.base.entity.PermissionEntity;
import com.auth.dao.base.entity.RoleEntity;
import com.auth.dao.base.entity.UserEntity;
import com.auth.dao.base.mapper.v1.UserMapper;
import com.auth.model.base.dto.LoginDto;
import com.auth.model.base.vo.LoginVo;
import com.auth.module.security.provider.JwtTokenProvider;
import com.auth.module.security.service.LoginService;
import com.auth.module.security.service.strategy.DefaultLoginStrategy;
import com.auth.module.security.service.strategy.LoginContext;
import com.auth.module.security.service.strategy.LoginStrategy;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service
@RequiredArgsConstructor
public class LoginServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements LoginService {

    private final JwtTokenProvider jwtTokenProvider;
    private final DbUserDetailServiceImpl dbUserDetailServiceImpl;
    private final UserMapper userMapper;
    private final PasswordEncoder passwordEncoder;

    /**
     * 用户登录
     *
     * @param loginDto LoginRequest登录参数
     * @return 登录成功返回内容
     */
    @Override
    public LoginVo login(LoginDto loginDto) {
        // 初始化所有策略（可扩展）
        HashMap<String, LoginStrategy> loginStrategyHashMap = new HashMap<>();
        // 默认的登录方式
        loginStrategyHashMap.put(LoginEnums.default_STRATEGY.getValue(), new DefaultLoginStrategy(userMapper));

        // 使用登录上下文调用登录策略
        LoginContext loginContext = new LoginContext(loginStrategyHashMap);
        UserEntity user = loginContext.executeStrategy(loginDto);

        // 验证登录逻辑
        if (user == null) throw new UsernameNotFoundException(ResultCodeEnum.USER_IS_EMPTY.getMessage());

        // 数据库密码
        String dbPassword = user.getPassword();
        String password = loginDto.getPassword();
        if (!passwordEncoder.matches(password, dbPassword)) {
            throw new UsernameNotFoundException(ResultCodeEnum.LOGIN_ERROR.getMessage());
        }

        // 登录结束后的操作
        loginContext.loginAfter(loginDto, user);

        // 设置用户创建用户id 和 更新用户id
        Long userId = user.getId();
        user.setCreateUser(userId);
        user.setUpdateUser(userId);
        updateById(user);

        List<String> roles = baseMapper.selectRolesByUserId(userId).stream().map(RoleEntity::getRoleCode).toList();
        List<String> permission = baseMapper.selectPermissionByUserId(userId).stream().map(PermissionEntity::getPermissionCode).toList();
        String token = jwtTokenProvider.createToken(userId, user.getUsername(), roles, permission);

        // 过期时间
        Long expiresInSeconds = jwtTokenProvider.expired;
        long expirationMillis = System.currentTimeMillis() + (expiresInSeconds * 1000);
        Date date = new Date(expirationMillis);

        // 构建用户返回对象
        LoginVo loginVo = new LoginVo();
        BeanUtils.copyProperties(user, loginVo);
        loginVo.setToken(token);
        loginVo.setReadMeDay(expirationMillis);
        loginVo.setExpires(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));

        return loginVo;
    }
}
