package com.jjt.ad.service.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jjt.ad.domain.AdUserInfo;
import com.jjt.ad.service.IAdSyncService;
import com.jjt.common.core.domain.entity.SysDept;
import com.jjt.common.core.domain.entity.SysRole;
import com.jjt.common.core.domain.entity.SysUser;
import com.jjt.common.utils.SecurityUtils;
import com.jjt.system.service.ISysDeptService;
import com.jjt.system.service.ISysRoleService;
import com.jjt.system.service.ISysUserService;
import com.jjt.utils.IotTools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 首页统计数据
 *
 * @author wukai
 * @date 2024/5/4 20:35
 */
@Service
@Slf4j
public class AdSyncServiceImpl implements IAdSyncService {
    @Resource
    private ISysDeptService deptService;
    @Resource
    private ISysUserService userService;
    @Resource
    private ISysRoleService roleService;
    @Value("${ad.uri}")
    private String uri;
    @Value("${ad.domain}")
    private String domain;

    @Value("${ad.user}")
    private String user;

    @Value("${ad.pass}")
    private String pass;

    /**
     * 同步
     */
    @Override
    public void sync() {
        List<AdUserInfo> userList = userList();
        Map<String, SysDept> deptMap = deptSync(userList);
        userSync(userList, deptMap);

    }

    /**
     * 部门同步
     *
     * @param userList 用户列表
     */
    private Map<String, SysDept> deptSync(List<AdUserInfo> userList) {
        List<SysDept> deptList = deptService.selectAll();
        Map<String, SysDept> deptMap = deptList.stream().collect(Collectors.toMap(SysDept::getDeptName, dept -> dept, (oldDept, newDept) -> oldDept));
        List<String> uniqueOuNames = userList.stream().map(AdUserInfo::getOuName).distinct().collect(Collectors.toList());
        SysDept parentDept = deptList.get(0);
        for (String name : uniqueOuNames) {
            String[] tmp = name.split("/");
            for (String s : tmp) {
                if (deptMap.containsKey(s)) {
                    parentDept = deptMap.get(s);
                } else {
                    SysDept dept = new SysDept();
                    dept.setDeptName(s);
                    dept.setParentId(parentDept.getDeptId());
                    deptService.insertDept(dept);
                    parentDept = dept;
                    deptMap.put(s, dept);
                }

            }
        }
        return deptMap;
    }

    private void userSync(List<AdUserInfo> adUserInfos, Map<String, SysDept> deptMap) {
        List<SysRole> roleList = roleService.selectAll();
        Map<String, SysRole> roleMap = roleList.stream().collect(Collectors.toMap(SysRole::getRoleName, dept -> dept, (o, n) -> o));
        List<SysUser> userList = userService.selectAll();
        Map<String, SysUser> userMap = userList.stream().collect(Collectors.toMap(SysUser::getUserName, dept -> dept, (o, n) -> o));
        SysRole commonRole = roleMap.get("普通角色");

        for (AdUserInfo info : adUserInfos) {
            SysUser user = new SysUser();
            if (userMap.containsKey(info.getSamAccountName())) {
                user = userMap.get(info.getSamAccountName());
            }
            user.setUserName(info.getSamAccountName());
            user.setNickName(info.getDisplayName());
            user.setEmail(info.getLogonName());
            if (info.getMobile().length() > 11) {
                user.setPassword(SecurityUtils.encryptPassword("123456"));
            } else {
                user.setPhonenumber(info.getMobile());
                user.setPassword(SecurityUtils.encryptPassword(info.getMobile()));
            }
            Set<Long> roles = new HashSet<>();
            roles.add(commonRole.getRoleId());
            String[] tmp = info.getOuName().split("/");
            if (tmp.length > 3) {
                SysRole role = roleMap.get(tmp[3]);
                if (role != null) {
                    roles.add(role.getRoleId());
                }
                SysDept dept = deptMap.get(tmp[tmp.length - 1]);
                user.setDeptId(dept.getDeptId());
            }
            user.setRoleIds(roles.toArray(new Long[0]));

            if (user.getUserId() != null) {
                userService.updateUser(user);
            } else {
                userService.insertUser(user);
            }
        }

    }

    private List<AdUserInfo> userList() {
        List<AdUserInfo> userList = new ArrayList<>();
        String uri = this.uri + "/RestAPI/SearchUser";
        Map<String, Object> map = new HashMap<>(16);
        map.put("domainName", domain);
        map.put("startIndex", "1");
        map.put("range", "10000");
        map.put("AuthToken", token());
        HttpRequest request = HttpUtil.createPost(uri);
        request.setMethod(Method.GET);
        request.form(map);
        request.setConnectionTimeout(5000);
        String success = "SUCCESS";
        try (HttpResponse res = request.execute()) {
            if (!res.isOk()) {
                throw new RuntimeException(res.body());
            }
            String result = new String(res.body().getBytes(), StandardCharsets.UTF_8);
            JSONObject jsonObject = JSONUtil.parseObj(result, true);
            if (success.equals(jsonObject.getStr("status"))) {
                JSONArray arr = jsonObject.getJSONArray("UsersList");
                for (int i = 0; i < arr.size(); i++) {
                    JSONObject user = arr.getJSONObject(i);
                    try {
                        AdUserInfo userInfo = user.toBean(AdUserInfo.class);
                        userList.add(userInfo);
                    } catch (Exception e) {
                        log.error(e.getMessage());
                    }
                }
            }
        }
        return userList;
    }

    private String token() {
        String uri = this.uri + "/RestAPI/APIAuthToken";
        Map<String, Object> map = new HashMap<>(16);
        map.put("domainName", domain);
        map.put("loginName", user);
        map.put("password", pass);
        map.put("AuthToken", "a21d15fa-58ee-4181-9fca-5f5dbc83dbd2");
        HttpRequest request = HttpUtil.createPost(uri);
        request.setMethod(Method.GET);
        request.form(map);
        request.setConnectionTimeout(5000);
        JSONObject jsonObject = IotTools.getData(request);

        if ("true".equals(jsonObject.getStr("LoginStatus"))) {
            return jsonObject.getStr("AuthTicket");
        } else {
            log.error(jsonObject.toJSONString(1));
            throw new RuntimeException();
        }
    }
}
