package com.casic.missiles.modular.system.controller;

import cn.hutool.core.lang.Assert;
import com.casic.missiles.core.application.enums.LoginEventTypeEnum;
import com.casic.missiles.core.application.event.UserLoginEvent;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.base.language.I18nFactory;
import com.casic.missiles.core.cache.CacheUtil;
import com.casic.missiles.core.common.exception.BizExceptionEnum;
import com.casic.missiles.core.model.auth.AuthUser;
import com.casic.missiles.core.shiro.ShiroKit;
import com.casic.missiles.core.shiro.ShiroSessionCacheManager;
import com.casic.missiles.core.util.HttpContext;
import com.casic.missiles.model.application.event.core.EventPublisher;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.model.response.SuccessResponseData;
import com.casic.missiles.modular.interfaces.log.LogManager;
import com.casic.missiles.modular.interfaces.log.factory.LogTaskFactory;
import com.casic.missiles.modular.system.dto.LockAccountDTO;
import com.casic.missiles.modular.system.dto.LoginSuccessDTO;
import com.casic.missiles.modular.system.dto.UserVO;
import com.casic.missiles.modular.system.service.ILoginCheckService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;

/**
 * @author cz
 * @date 2023-09-14
 */
@RestController
@RequiredArgsConstructor
@Slf4j
public class ThirdUserController extends BaseController {

    private final ILoginCheckService loginCheckService;
    private final ShiroSessionCacheManager sessionCacheManager;
    private final EventPublisher publisher;

    /**
     * 第三方用户传入userCode，进行验证获取token信息
     */
    @RequestMapping("/user/login/token")
    public Object userLoginToken(@RequestBody UserVO userVO) {
        return loginIn(userVO.getUserCode());
    }


    private Object loginIn(String userCode) {
        String password = "111111";
        SuccessResponseData resultData = new SuccessResponseData();
        //去除用户登录锁
        LockAccountDTO lockAccountDTO = this.loginCheckService.invalidLockAccount(userCode);
        super.getSession().setAttribute("isApp", false);
        Subject currentUser = ShiroKit.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(userCode, password.toCharArray());
        token.setRememberMe(false);
        try {
            currentUser.login(token);
            CacheUtil.remove("CONSTANT_ADMIN", "lock_account_" + lockAccountDTO.getAccount());
        } catch (Exception var17) {
            resultData.setCode(BizExceptionEnum.USER_NOT_EXISTED.getCode());
            resultData.setMessage(I18nFactory.getMessage("admin.nouser.error"));
            return ResponseData.success();
        }
        AuthUser authUser = ShiroKit.getUser();
        super.getSession().setAttribute("shiroUser", authUser);
        super.getSession().setAttribute("username", authUser.getAccount());
        super.getSession().setAttribute("userId", authUser.getId());

        try {
            LogManager.me().executeLog(LogTaskFactory.loginLog(authUser.getId(), HttpContext.getIp()));
        } catch (Exception var16) {
            log.error("login log fail:{}", var16);
        }

        ShiroKit.getSession().setAttribute("sessionFlag", true);
        Session session = ShiroKit.getSession();
        Subject newUser = ShiroKit.getSubject();
        LinkedHashMap<Object, Object> attributes = new LinkedHashMap();
        Collection<Object> keys = session.getAttributeKeys();
        Iterator var13 = keys.iterator();

        Object key;
        while (var13.hasNext()) {
            key = var13.next();
            Object value = session.getAttribute(key);
            if (value != null) {
                attributes.put(key, value);
            }
        }

        session.stop();
        session = newUser.getSession(true);
        session.setAttribute("isApp", false);
        newUser.login(token);
        var13 = attributes.keySet().iterator();

        while (var13.hasNext()) {
            key = var13.next();
            session.setAttribute(key, attributes.get(key));
        }

        resultData.setData(new LoginSuccessDTO(session.getId().toString(), (String) null));
        resultData.setMessage(I18nFactory.getMessage("login.sucess"));
        this.publisher.publishEvent(new UserLoginEvent(LoginEventTypeEnum.LOGIN_ON, ShiroKit.getUser()));
//        this.sessionCacheManager.sessionCache(session, authUser.getAccount());
        return resultData;
    }

}
