package com.bcxin.tenant.domain.services.impls;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bcxin.Infrastructures.enums.AbnormalPersonnelEmployeeType;
import com.bcxin.Infrastructures.enums.CredentialType;
import com.bcxin.Infrastructures.enums.OccupationType;
import com.bcxin.Infrastructures.models.CredentialModel;
import com.bcxin.Infrastructures.utils.AuthUtil;
import com.bcxin.api.interfaces.tenants.requests.employees.EmployeeRequest;
import com.bcxin.tenant.domain.configs.SSOConfig;
import com.bcxin.tenant.domain.dto.AjaxResult;
import com.bcxin.tenant.domain.dto.SingleLoginUserDto;
import com.bcxin.tenant.domain.entities.DepartmentEntity;
import com.bcxin.tenant.domain.entities.EmployeeEntity;
import com.bcxin.tenant.domain.repositories.DepartmentRepository;
import com.bcxin.tenant.domain.repositories.EmployeeRepository;
import com.bcxin.tenant.domain.services.DepartmentService;
import com.bcxin.tenant.domain.services.EmployeeService;
import com.bcxin.tenant.domain.services.SingleLoginService;
import com.bcxin.tenant.domain.services.commands.CreateEmployeeRequestCommand;
import com.bcxin.tenant.domain.services.commands.DepartmentCommand;
import com.bcxin.tenant.domain.services.commands.UpdateEmployeeRequestCommand;
import com.bcxin.tenant.domain.utils.SSOContants;
import com.bcxin.tenant.domain.utils.encry.AES;
import com.bcxin.tenant.domain.utils.encry.CreatRandomStr;
import com.bcxin.tenant.domain.utils.encry.Md5;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author linqinglin
 * @date 2021/10/13 0013 9:47
 */
@Service
public class SingleLoginServiceImpl implements SingleLoginService {

    private final Logger logger = LoggerFactory.getLogger(SingleLoginServiceImpl.class);


    private final DepartmentService departmentService;

    private final DepartmentRepository departmentRepository;

    private final EmployeeRepository employeeRepository;

    private final EmployeeService employeeService;

    public SingleLoginServiceImpl(DepartmentService departmentService,
                                  DepartmentRepository departmentRepository,
                                  EmployeeRepository employeeRepository,
                                  EmployeeService employeeService){
        this.departmentService = departmentService;
        this.departmentRepository = departmentRepository;
        this.employeeRepository = employeeRepository;
        this.employeeService = employeeService;
    }


    private Map getParamMap(){
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("clientId", SSOConfig.getClientId());
        paramMap.put("randomStr", CreatRandomStr.CreatenNonce_str());
        paramMap.put("timeStamp", System.currentTimeMillis());
        String signTemp= CreatRandomStr.createStr(paramMap, SSOConfig.getClientSecret());
        String signStr= Md5.encoderMD5(signTemp);
        paramMap.put("signStr",signStr);
        return paramMap;
    }

    /**
     * 单点登录 创建更新用户
     * @param userName
     * @throws Exception
     */
    @Override
    public SingleLoginUserDto saveLoginUser(String userName) throws Exception {
        boolean isNew = false;
        String employeeId = null;
        try{
            String domainId = SSOConfig.getDomainId();
            if(StrUtil.isEmpty(domainId)){
                throw new Exception("domainId配置错误");
            }
            EmployeeRequest request = new EmployeeRequest();
            CredentialModel credential = new CredentialModel();
            request.setCredential(credential);
            EmployeeEntity employee = employeeRepository.getByIdNum(domainId, userName);
            if(employee == null){
                isNew = true;
            }

            String urlPath = SSOConfig.getUrl() + SSOContants.getjhuser;
            Map<String, Object> paramMap = getParamMap();
            paramMap.put("jh", AES.encrypt(userName, SSOConfig.getKey()));
            logger.error("根据警号获取用户信息,请求地址：{}", urlPath);
            logger.error("根据警号获取用户信息,请求参数：{}", JSON.toJSONString(paramMap));

            String reqResult = HttpUtil.post(urlPath, paramMap, 30000);
            logger.error("根据警号获取用户信息,返回结果:{}", reqResult);
            JSONObject resultJSON = JSON.parseObject(reqResult);
            String code = resultJSON.getString("code");
            if ("0".equals(code)) {
                String userObject = resultJSON.getString("userObject");
                JSONObject userJSON = JSON.parseObject(AES.decrypt(userObject, SSOConfig.getKey()));

                logger.error("根据警号获取用户信息,解密结果:{}", JSON.toJSONString(userJSON));
                request.setName(userJSON.getString("NAME"));
                request.setTelephone(userName);
                //手机号，如果手机号不存在，则使用警号
                if(userJSON.getString("SOTHER_INFO") != null) {
                    request.setTelephone(userJSON.getString("SOTHER_INFO"));
                    credential.setType(CredentialType.PoliceNo);
                    credential.setNumber(userName);
                }else{
                    //身份证号
                    if (StrUtil.isNotEmpty(userJSON.getString("PID"))) {
                        credential.setType(CredentialType.IdCard);
                        credential.setNumber(userJSON.getString("PID"));
                    }
                }

                request.setDepartId(getPoliceDepart(userJSON.getString("SUNIT_CODE")));

                //NSTATION_NO	字符型	15	系统权限_岗位ID
                //sstation_name	字符型	200	系统权限_岗位名称部门

                if(userJSON.getString("NSTATION_NO") == null) {
                    throw new Exception("该账号未配置岗位");
                }

                String roleNo = userJSON.getString("NSTATION_NO");
                String roleName = userJSON.getString("SSTATION_NAME");

                if (isNew) {
                    employeeId =
                            this.employeeService.dispatch(
                                    CreateEmployeeRequestCommand.create(domainId,
                                            request.getName(), request.getTelephone(),
                                            null,
                                            request.getDepartId(), OccupationType.Police, null,
                                            new Date(), request.getCredential().getType(),
                                            request.getCredential().getNumber(),
                                            AuthUtil.getCurrentOperator(),
                                            AbnormalPersonnelEmployeeType.NOT_VERIFY));
                } else {
                    employeeId  = employee.getId();
                    this.employeeService.dispatch(
                            UpdateEmployeeRequestCommand.create(domainId, employee.getId(),
                                    request.getDepartId(),
                                    employee.getHiredDate(),
                                    employee.getSuperior() == null ?null:employee.getSuperior().getId(),
                                    employee.getPosition(),
                                    employee.getPositiveDate(),null,
                                    employee.getInterview(),
                                    employee.getPersonStatus(),
                                    employee.getProbation(),
                                    employee.getPlanPositiveDate(),employee.getSalary()));
                }

                return SingleLoginUserDto.create(employeeId,request.getTelephone(),getPoliceRole(roleNo, roleName));

            }else{
                throw new Exception(resultJSON.getString("msg"));
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取部门 没有则创建
     * @param jgdm
     * @return
     * @throws Exception
     */
    private String getPoliceDepart(String jgdm) throws Exception {
        DepartmentEntity department = departmentRepository.getByOrganIdAndCode(SSOConfig.getDomainId(),jgdm);
        if(department == null) {
            String urlPath = SSOConfig.getUrl() + SSOContants.getorgcode;
            Map<String, Object> paramMap = getParamMap();
            paramMap.put("jgdm", AES.encrypt(jgdm, SSOConfig.getKey()));
            logger.error("根据机构编号获取机构信息,请求地址：{}",urlPath);
            logger.error("根据机构编号获取机构信息,请求参数：{}", JSON.toJSONString(paramMap));

            String result = HttpUtil.post(urlPath, paramMap, 30000);
            logger.error("根据机构编号获取机构信息,返回结果:{}", result);
            JSONObject resultJSON = JSON.parseObject(result);
            String code = resultJSON.getString("code");
            if ("0".equals(code)) {
                String dwObject = resultJSON.getString("dwObject");
                JSONObject orgJSON = JSON.parseObject(AES.decrypt(dwObject, SSOConfig.getKey()));
                logger.error("根据机构编号获取机构信息,解密结果:{}", JSON.toJSONString(orgJSON));

                String parentCode = orgJSON.getString("SUPUNIT_CODE");

                DepartmentCommand command = null;
                String parentId = null;

                if(StrUtil.isNotEmpty(parentCode)){
                    DepartmentEntity parentDepart = departmentRepository.getByOrganIdAndCode(SSOConfig.getDomainId(),jgdm);
                    if(parentDepart == null){
                        parentId = getPoliceDepart(parentCode);
                    }else {
                        parentId = parentDepart.getId();
                    }
                }else{
                    DepartmentEntity rootDepart = departmentRepository.getRootByOrganId(SSOConfig.getDomainId());
                    parentId = rootDepart.getId();
                }

                command = DepartmentCommand.create(SSOConfig.getDomainId(),
                        orgJSON.getString("ORGNAME"),
                        parentId,
                        jgdm
                );

                return departmentService.create(command);
            } else {
                throw new Exception(resultJSON.getString("msg"));
            }
        }

        return department.getId();
    }


    /**
     * 获取角色
     * 没有则创建，有则更新
     * @param roleNo
     * @param roleName
     * @return
     * @throws Exception
     */
    private List<String> getPoliceRole(String roleNo,String roleName) throws Exception {
        List<String> roleList = new ArrayList<>();
        String urlPath = SSOConfig.getUrl() + SSOContants.getmenu;
        Map<String,String> menuIdMap = new HashMap<>();
        Map<String,Object> paramMap = getParamMap();
        paramMap.put("zxtqxgw", AES.encrypt(roleNo,SSOConfig.getKey()));
        paramMap.put("zxtbm", AES.encrypt(SSOConfig.getZxtqxgw(),SSOConfig.getKey()));

        logger.error("获取菜单信息,请求地址：{}",urlPath);
        logger.error("获取菜单信息,请求参数：{}",JSON.toJSONString(paramMap));

        String result = HttpUtil.post(urlPath, paramMap,30000);
        logger.error("获取菜单信息,返回结果:{}",result);
        JSONObject resultJSON = JSON.parseObject(result);
        String code = resultJSON.getString("code");
        if("0".equals(code)){
            String dwObject = resultJSON.getString("menuObject");
            JSONObject menusJSON = JSON.parseObject(AES.decrypt(dwObject,SSOConfig.getKey()));

            logger.error("获取菜单信息,解密结果:{}", JSON.toJSONString(menusJSON));

            JSONArray menuArr = JSONArray.parseArray(menusJSON.getString("list"));
            logger.error(menusJSON.getString("list"));

            if(menuArr.size() <1){
                return roleList;
            }

            for (Object menuObj : menuArr) {
                JSONObject menu = JSON.parseObject(menuObj.toString());
                if(StrUtil.isNotEmpty(menu.getString("MENU_ID"))) {
                    menuIdMap.put(menu.getString("MENU_ID"),menu.getString("MENU_ID"));
                }
            }
            paramMap = new HashMap<>();
            paramMap.put("menuIds",menuIdMap);
            paramMap.put("roleNo",roleNo);
            paramMap.put("roleName",roleName);


            logger.error("获取V5角色,请求地址：{}",SSOConfig.getV5Url() + SSOContants.GET_V5_ROLES);
            logger.error("获取V5角色,请求参数：{}",JSON.toJSONString(paramMap));

            result = HttpUtil.post(SSOConfig.getV5Url() + SSOContants.GET_V5_ROLES, paramMap,30000);

            logger.error("获取V5角色,返回结果:{}",result);
            AjaxResult ajaxResult =JSON.parseObject(result,AjaxResult.class);

            if(ajaxResult.isSuccessful()){
                return (List<String>) ajaxResult.getData();
            }

        }else{
            throw new Exception(resultJSON.getString("msg"));
        }
        return roleList;
    }

    public static void main(String[] args) {

        AjaxResult result =JSON.parseObject("{\"code\":\"1\",\"data\":[\"1111\",\"2222\"],\"successful\":true}",AjaxResult.class);

        if(result.isSuccessful()){
            List<String> list = (List<String>) result.getData();

            for (String s : list) {
                System.out.println(s);
            }

        }
    }
}
