package com.my.web.controller.system;

import cn.gov.customs.casp.sdk.h4a.AccreditBeanReaderHelper;
import cn.gov.customs.casp.sdk.h4a.OguBeanReaderHelper;
import cn.gov.customs.casp.sdk.h4a.accredit.ws.OrganizationCategory;
import cn.gov.customs.casp.sdk.h4a.accredit.ws.UserCategory;
import cn.gov.customs.casp.sdk.h4a.entity.FunctionsOfUser;
import cn.gov.customs.casp.sdk.h4a.entity.UserIdentityInfos;
import cn.gov.customs.casp.sdk.h4a.enumdefines.AccreditCategory;
import cn.gov.customs.casp.sdk.h4a.enumdefines.DelegationCategories;
import cn.gov.customs.casp.sdk.h4a.enumdefines.FunctionCategories;
import cn.gov.customs.casp.sdk.h4a.sso.passport.PassportFilter;
import cn.gov.customs.casp.sdk.h4a.sso.passport.Ticket;
import cn.gov.customs.casp.sdk.h4a.sso.passport.util.CommonHelper;
import cn.gov.customs.casp.sdk.h4a.sso.passport.util.ParsTicketUtil;
import com.alibaba.fastjson2.JSON;
import com.my.constant.H4ABasicProperty;
import com.my.common.constant.Constants;
import com.my.common.core.domain.AjaxResult;
import com.my.common.core.domain.entity.SysDept;
import com.my.common.core.domain.entity.SysMenu;
import com.my.common.core.domain.entity.SysUser;
import com.my.common.core.domain.model.LoginBody;
import com.my.common.core.domain.model.LoginUser;
import com.my.common.exception.ServiceException;
import com.my.common.utils.SecurityUtils;
import com.my.common.utils.StringUtils;
import com.my.framework.web.service.SysLoginService;
import com.my.framework.web.service.SysPermissionService;
import com.my.framework.web.service.TokenService;
import com.my.system.domain.vo.RouterVo;
import com.my.system.service.ISysDeptService;
import com.my.system.service.ISysMenuService;
import com.my.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 登录验证
 *
 * @author ruoyi
 */
@RestController
@Slf4j
@Component
@RequiredArgsConstructor
public class SysLoginController
{
    private final SysLoginService loginService;

    private final ISysMenuService menuService;

    private final SysPermissionService permissionService;

    private final ISysDeptService deptService;
    private final ISysUserService userService;
    private final TokenService tokenService;

    // todo 正式环境部署 改为h4a
    private final static boolean h4a_login = false;
    /**
     * 登录方法
     * @return 结果
     */
    @PostMapping("/getH4aUrl")
    public AjaxResult getH4aUrl(@Value("${h4a.ui-ip-port}") String uiIp) {
        String ip = uiIp;
        String requestUrl = "http://"+uiIp+"/login/";
        String defaultMode = PassportFilter.daMode;

        String jumptourl = "";
        try {
            jumptourl = PassportFilter.authenticateUrl + "?aid=" + PassportFilter.appId + "&pm=" + defaultMode + "&apk=" + CommonHelper.getUrlPubKey() + "&t="
                    + PassportFilter.paramT + "&lou=" + URLEncoder.encode(requestUrl, "utf-8")
                    + "&ip="+ip+"&fciam=False" + "&iam=" + PassportFilter.idMode +
                    "&ru=" + URLEncoder.encode(requestUrl, "utf-8") + "&fc=&sid=" + PassportFilter.uuid;
        } catch (Exception e){
            e.printStackTrace();
        }
        log.debug("jumptourl:{}", jumptourl);


        AjaxResult ajax = AjaxResult.success();
        ajax.put("url",jumptourl );
        return ajax;
    }


    /**
     * 登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(HttpServletRequest request, @RequestBody LoginBody loginBody) {
        loginBody.setUserCode("admin123");
        log.debug("com.ruoyi.web.controller.system.SysLoginController.login  loginBody:{}", JSON.toJSONString(loginBody));
        AjaxResult ajax = AjaxResult.success();
        if("user".equals(loginBody.getLoginType())){ // 开发环境非H4A登录
            // 生成令牌
            String token = loginService.login(loginBody.getUsername(), loginBody.getUserCode(), loginBody.getCode(),
                    loginBody.getUuid());
            ajax.put(Constants.TOKEN, token);
        } else { // H4A登录
            try {
                String jumptourl = request.getHeader("token");// loginBody.getToken();
                String h4aToken = URLDecoder.decode(jumptourl, "utf-8").replaceAll(" ", "+");
                String fc = CommonHelper.decryptTicket(h4aToken);
                Ticket ticket = ParsTicketUtil.getTicketUtil(fc);
                log.debug("LoginH4aFilter ticket:" + ticket);
                String ln = ticket.getLn();// 用户账号
                String abm = ticket.getAbm();// 用户账号对应的基本认证方式
                String userGuid = "";
                // 查询用户信息,查询前
                UserIdentityInfos[] vu = new OguBeanReaderHelper().getBeanUserIdentityInfos(ln+"&"+abm, cn.gov.customs.casp.sdk.h4a.ogu.ws.UserCategory.USER_IDENTITY);
                userGuid = vu[0].getUser_guid();

                String token = loginService.login(userGuid, loginBody.getUserCode(), loginBody.getCode(),
                        loginBody.getUuid());
                ajax.put(Constants.TOKEN, token);
            }catch (Exception e){
                e.printStackTrace();
                log.error(e.getMessage());
                throw new ServiceException(e.getMessage());
            }
        }
        return ajax;
    }

    /**
     * 获取用户信息
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo() throws Exception {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        return getLoginUserDept(loginUser);
    }
    public AjaxResult getLoginUserDept(LoginUser loginUser)
    {
        AjaxResult ajax = AjaxResult.success();
        SysUser user = loginUser.getUser();
        // 权限集合
        Set<String> permissions = null;
        if(h4a_login){
            try {
                permissions = getRoles(user.getUserGuid(), user.getParentGuid());
            } catch (Exception e){
                log.error("获取权限报错：" + e.getMessage());
                e.printStackTrace();
            }
        } else {
            permissions = permissionService.getMenuPermission(user);
        }

        SysDept dept = deptService.selectDeptById(user.getDeptId());
        dept.setOrgName(dept.getDeptName());
        if("9".equals(dept.getOrgType())){
            SysDept org = deptService.selectOrgDeptById(dept.getParentId());
            dept.setCustomsCode(org.getCustomsCode());
            dept.setOrgType(org.getOrgType());
            dept.setOrgName(org.getDeptName());
        }
        ajax.put("roles", null);
        ajax.put("permissions", permissions);
        ajax.put("dept", dept);
        ajax.put("user", user);
        ajax.put("orgType", loginUser.getOrgType());
        ajax.put("orgId", loginUser.getOrgId());
        return ajax;
    }

    
    /**
     * 获取H4A功能权限
     */
    public Set<String> getRoles(String userGuid, String deptGuid) throws Exception {
        AccreditBeanReaderHelper abrh = new AccreditBeanReaderHelper();
        Set<String> functionSet = new HashSet<String>();
//			查询指定用户，在指定应用系统中指定视角下所具有的权限（功能）。
        FunctionsOfUser[] functionsOfUser = abrh.getBeanFunctionsOfUser(userGuid,
                UserCategory.USER_GUID, deptGuid,
                OrganizationCategory.ORG_GUID,
                H4ABasicProperty.APP_GUID, AccreditCategory.Code,
                H4ABasicProperty.VIEW_GUID, AccreditCategory.Code,
                FunctionCategories.All, DelegationCategories.All, "FUNC_NAME,CODE_NAME,PARENT_CODE");
        if(functionsOfUser != null ){
            for (FunctionsOfUser functions : functionsOfUser) {
//                log.info(functions.getFunc_name() + "---" + functions.getCode_name());
                functionSet.add(functions.getCode_name());
            }
        }
        return functionSet;
    }

    /**
     * 获取路由信息
     * 
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters() throws Exception {
        List<SysMenu> menus = null;
        if(h4a_login){
            try {
                LoginUser loginUser = SecurityUtils.getLoginUser();
                SysUser user = loginUser.getUser();
                Set<String> permissions = getRoles(user.getUserGuid(), user.getParentGuid());
                menus = menuService.selectMenuByCode(permissions);
            } catch ( Exception e){
                log.error("获取权限报错：" + e.getMessage());
                e.printStackTrace();
            }

        } else {
            Long userId = SecurityUtils.getUserId();
            menus = menuService.selectMenuTreeByUserId(userId);
        }

        List<RouterVo> routerVos = new ArrayList<>();
        if(menus != null && menus.size() > 0){
            routerVos = menuService.buildMenus(menus);
        }
        return AjaxResult.success(routerVos);
    }



    /**
     * 获取登录用户部门信息
     * @param userGuid
     * @return
     */
    @GetMapping("getLoginUserDept")
    public AjaxResult getLoginUserDept(String userGuid) {
        List<SysUser> sysUsers = userService.selectUserByUserGuid(userGuid);
        return AjaxResult.success(sysUsers);
    }

    /**
     * 切换用户部门
     * @param userId
     * @return
     */
    @GetMapping("changeLoginUser")
    public AjaxResult changeLoginUser(Long userId) {
        // 更新缓存用户权限
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (StringUtils.isNotNull(loginUser.getUser()) )
        {
            SysUser sysUser = userService.selectUserById(userId);

            Long orgId = null;
            String orgCategory = null;
            SysDept dept = sysUser.getDept();
            SysDept userOrg = deptService.getUserOrg(dept.getAncestors());
            if(userOrg != null ){
                orgId = userOrg.getDeptId();
                orgCategory = userOrg.getOrgCategory();
            }
            loginUser.setUserId(sysUser.getUserId());
            loginUser.setUser(sysUser);
            loginUser.setDeptId(sysUser.getDeptId());
            loginUser.setOrgId(orgId);
            loginUser.setOrgType(orgCategory);
            tokenService.setLoginUser(loginUser);
            // 更新用户选择
            userService.updateUserLoginFlag(sysUser.getUserGuid(), sysUser.getUserId());
        }
        return AjaxResult.success(loginUser);
    }

}
