package com.kingdee.eas.custom.task;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gemdale.gdgateway.util.MD5Utils;
import com.kingdee.eas.base.permission.UserCollection;
import com.kingdee.eas.base.permission.UserFactory;
import com.kingdee.eas.base.permission.UserInfo;
import com.kingdee.eas.basedata.person.PersonInfo;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.util.DateTimeUtils;
import com.kingdee.util.StringUtils;
import okhttp3.*;
import org.apache.log4j.Logger;

import java.io.FileInputStream;
import java.io.IOException;

import com.kingdee.bos.*;

import java.lang.String;
import java.text.SimpleDateFormat;
import java.util.*;

public class SyncZYEmpFacadeControllerBean extends AbstractSyncZYEmpFacadeControllerBean {
    private static String propertiesUrl = System.getProperty("EAS_HOME") + "/server/properties/Api/propertie.properties";
    private List empInfoList = new ArrayList<>();
    private static Logger logger = Logger.getLogger(SyncZYEmpFacadeControllerBean.class);
    private int pageSize = 100;

    /**
     * 同步所有用户
     *
     * @param ctx
     * @throws BOSException
     */
    @Override
    protected void _SyncAllEmp(Context ctx) throws BOSException {
        super._SyncAllEmp(ctx);
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream(propertiesUrl));
        } catch (IOException e) {
            e.printStackTrace();
            throw new BOSException(String.format("获取配置失败，请检查配置[%s]", propertiesUrl));
        }
        int empCount = getEmpCount(properties, null, null);
        logger.error("获取用户总数: " + empCount);
        getEmp(properties, null, null, empCount);
        //更新用户信息
        updateUserInfo(ctx);
    }

    /**
     * 更新用户信息
     *
     * @param ctx
     * @throws BOSException
     */
    private void updateUserInfo(Context ctx) throws BOSException {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            UserCollection userCollection = UserFactory.getLocalInstance(ctx).getUserCollection("select id,person.* where person is not null");
            Map<String, String> idCardNoMap = new HashMap<>();
            Map<String, String> passportNoMap = new HashMap<>();
            Map<String, String> emailMap = new HashMap<>();
            for (int i = 0; i < userCollection.size(); i++) {
                UserInfo userInfo = userCollection.get(i);
                String userId = userInfo.getId().toString();
                PersonInfo personInfo = userInfo.getPerson();
                //身份证号码
                String idCardNO = personInfo.getIdCardNO();
                if (!StringUtils.isEmpty(idCardNO)) {
                    idCardNoMap.put(idCardNO, userId);
                }
                //护照号码
                String passportNO = personInfo.getPassportNO();
                if (!StringUtils.isEmpty(passportNO)) {
                    passportNoMap.put(passportNO, userId);
                }
                //邮箱
                String email = personInfo.getEmail();
                if (!StringUtils.isEmpty(email)) {
                    emailMap.put(email, userId);
                }
            }
            List<Object[]> updateParams = new ArrayList<>();
            for (int i = 0; i < empInfoList.size(); i++) {
                //首先匹配身份证或护照号,再匹配邮箱
                Map<String, Object> empInfo = (Map<String, Object>) empInfoList.get(i);
                //账号
                String username = (String) empInfo.get("username");
                String email = (String) empInfo.get("email");
                String cardType = (String) empInfo.get("cardType");
                String cardNum = (String) empInfo.get("cardNum");
                String userId = null;
                if (!StringUtils.isEmpty(cardNum) && "null".equals(cardNum)) {
                    if (!StringUtils.isEmpty(cardType) && cardType.contains("身份证")) {
                        userId = idCardNoMap.get(cardNum);
                    } else {
                        userId = passportNoMap.get(cardNum);
                    }
                } else {
                    userId = emailMap.get(email);
                }
                if (!StringUtils.isEmpty(userId)) {
                    updateParams.add(new Object[]{username, userId});
                }
            }
            logger.error("更新用户信息参数: " + objectMapper.writeValueAsString(updateParams));
            String updateSql = "update t_pm_user set CFZYLoginName=? where fid=?";
            DbUtil.executeBatch(ctx, updateSql, updateParams);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BOSException("更新用户信息报错: " + e.getMessage());
        }
    }

    /**
     * 根据更新时间同步用户
     *
     * @param ctx
     * @param updateBeginTime 更新开始时间（yyyy-MM-dd HH:mm:ss）
     * @param updateEndTime   更新结束时间（yyyy-MM-dd HH:mm:ss）
     * @throws BOSException
     */
    @Override
    protected void _SyncEmpByUpdateTime(Context ctx, String updateBeginTime, String updateEndTime) throws BOSException {
        super._SyncEmpByUpdateTime(ctx, updateBeginTime, updateEndTime);
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream(propertiesUrl));
        } catch (IOException e) {
            e.printStackTrace();
            throw new BOSException(String.format("获取配置失败，请检查配置[%s]", propertiesUrl));
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (StringUtils.isEmpty(updateBeginTime) && StringUtils.isEmpty(updateEndTime)) {
            updateBeginTime = sdf.format(DateTimeUtils.addDay(new Date(), -7));
        }
        int empCount = getEmpCount(properties, updateBeginTime, updateEndTime);
        logger.error("获取用户总数: " + empCount);
        getEmp(properties, updateBeginTime, updateEndTime, empCount);
        //更新用户信息
        updateUserInfo(ctx);
    }

    /**
     * 获取md5签名
     *
     * @param appSecret
     * @param path
     * @return
     * @throws BOSException
     */
    private String getSignMd5String(String appSecret, String path) throws BOSException {
        StringBuilder errorMsg = new StringBuilder();
        if (StringUtils.isEmpty(appSecret)) {
            errorMsg.append("appSecret不能为空!").append("\n");
        }
        if (StringUtils.isEmpty(path)) {
            errorMsg.append("path不能为空!").append("\n");
        }
        if (errorMsg.length() > 0) {
            throw new BOSException("生成md5签名报错: " + errorMsg);
        }
        String sign = MD5Utils.sign(appSecret, path);
        logger.error("生成md5签名: " + sign);
        return sign;
    }

    /**
     * 查询用户总数
     *
     * @param properties
     * @param updateBeginTime 更新开始时间
     * @param updateEndTime   更新结束时间
     * @return
     * @throws BOSException
     */
    private int getEmpCount(Properties properties, String updateBeginTime, String updateEndTime) throws BOSException {
        StringBuilder errorMsg = new StringBuilder();
        OkHttpClient client = new OkHttpClient();
        String appkey = properties.getProperty("Appkey");
        String appSecret = properties.getProperty("AppSecret");
        //"https://api-test.gemdale.com/openApi/organization-center/emp/getEmpCount"
        String serverName = properties.getProperty("serverName");
        //获取用户总数接口地址
        String getEmpCountPath = properties.getProperty("getEmpCountPath");
        if (StringUtils.isEmpty(appkey)) {
            errorMsg.append("appkey 不能为空!").append("\n");
        }
        if (StringUtils.isEmpty(appSecret)) {
            errorMsg.append("appSecret 不能为空!").append("\n");
        }
        if (StringUtils.isEmpty(serverName)) {
            errorMsg.append("serverName 不能为空!").append("\n");
        }
        if (StringUtils.isEmpty(getEmpCountPath)) {
            errorMsg.append("获取用户总数接口地址 不能为空!").append("\n");
        }
        if (errorMsg.length() > 0) {
            throw new BOSException("生成md5签名报错: " + errorMsg);
        }
        JSONObject content = new JSONObject();
        content.put("containslnvalid", false);//是否包含失效用户
        if (!StringUtils.isEmpty(updateBeginTime)) {
            content.put("updateBeginTime", updateBeginTime);
        }
        if (!StringUtils.isEmpty(updateEndTime)) {
            content.put("updateEndTime", updateEndTime);
        }
        String contentStr = content.toJSONString();
        logger.error("查询用户总数请求参数: " + contentStr);
        RequestBody body = RequestBody.create(MediaType.parse("application/json"), contentStr);
        try {
            Request request = new Request.Builder()
                    .url(serverName + getEmpCountPath)
                    .post(body)
                    .addHeader("x-ca-key", appkey)
                    .addHeader("x-ca-signature", getSignMd5String(appSecret, getEmpCountPath))
                    .addHeader("x-ca-signature-method", "MD5")
                    .addHeader("content-type", "application/json")
                    .build();
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                ObjectMapper objectMapper = new ObjectMapper();
                Map result = objectMapper.readValue(response.body().string(), Map.class);
                Boolean success = (Boolean) result.get("success");
                if (success) {
                    return (int) result.get("total");
                } else {
                    String msg = (String) result.get("msg");
                    throw new BOSException(msg);
                }
            } else {
                throw new BOSException("请求失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BOSException("查询用户总数报错: " + e.getMessage());
        }
    }

    /**
     * 查询用户
     *
     * @param properties
     * @param updateBeginTime 更新开始时间
     * @param updateEndTime   更新结束时间
     * @return
     * @throws BOSException
     */
    private void getEmp(Properties properties, String updateBeginTime, String updateEndTime, int empCount) throws BOSException {
        if (empCount > 0) {
            ObjectMapper objectMapper = new ObjectMapper();
            StringBuilder errorMsg = new StringBuilder();
            OkHttpClient client = new OkHttpClient();
            String appkey = properties.getProperty("Appkey");
            String appSecret = properties.getProperty("AppSecret");
            String serverName = properties.getProperty("serverName");
            //获取用户总数接口地址
            String getEmpPath = properties.getProperty("getEmpPath");
            if (StringUtils.isEmpty(appkey)) {
                errorMsg.append("appkey 不能为空!").append("\n");
            }
            if (StringUtils.isEmpty(appSecret)) {
                errorMsg.append("appSecret 不能为空!").append("\n");
            }
            if (StringUtils.isEmpty(serverName)) {
                errorMsg.append("serverName 不能为空!").append("\n");
            }
            if (StringUtils.isEmpty(getEmpPath)) {
                errorMsg.append("获取用户接口地址 不能为空!").append("\n");
            }
            if (errorMsg.length() > 0) {
                throw new BOSException("生成md5签名报错: " + errorMsg);
            }
            String signMd5String = getSignMd5String(appSecret, getEmpPath);
            int pageCount = empCount % pageSize == 0 ? empCount / pageSize : empCount / pageSize + 1;
            for (int i = 1; i <= pageCount; i++) {
                JSONObject content = new JSONObject();
                content.put("containslnvalid", false);//是否包含失效用户
                content.put("pageSize", pageSize);
                content.put("pageNum", i);
                if (!StringUtils.isEmpty(updateBeginTime)) {
                    content.put("updateBeginTime", updateBeginTime);
                }
                if (!StringUtils.isEmpty(updateEndTime)) {
                    content.put("updateEndTime", updateEndTime);
                }
                RequestBody body = RequestBody.create(MediaType.parse("application/json"), content.toJSONString());
                try {
                    Request request = new Request.Builder()
                            .url(serverName + getEmpPath)
                            .post(body)
                            .addHeader("x-ca-key", appkey)
                            .addHeader("x-ca-signature", signMd5String)
                            .addHeader("x-ca-signature-method", "MD5")
                            .addHeader("content-type", "application/json")
                            .build();
                    Response response = client.newCall(request).execute();
                    if (response.isSuccessful()) {
                        String resultStr = response.body().string();
                        Map result = objectMapper.readValue(resultStr, Map.class);
                        Boolean success = (Boolean) result.get("success");
                        logger.error("查询用户数据: " + resultStr);
                        if (success) {
                            List data = (List) result.get("data");
                            //EmpInfo empInfo = objectMapper.readValue(data, EmpInfo.class);
                            empInfoList.addAll(data);
                        } else {
                            String msg = (String) result.get("msg");
                            throw new BOSException(msg);
                        }
                    } else {
                        throw new BOSException("请求失败");
                    }
                    Thread.sleep(100);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new BOSException("查询用户报错: " + e.getMessage());
                }
            }
        }
    }
//
//    public static void main(String[] args) throws IOException, BOSException {
//        OkHttpClient client = new OkHttpClient();
//        ObjectMapper objectMapper = new ObjectMapper();
//        Map<String, String> idCardNoMap = new HashMap<>();
//        idCardNoMap.put("2342", "111");
//        Map<String, String> passportNoMap = new HashMap<>();
//        passportNoMap.put("234123", "111");
//        Map<String, String> emailMap = new HashMap<>();
//        emailMap.put("liucanyu1@gemdale.com", "111");
//
//
//        int total = 0;
//        JSONObject content = new JSONObject();
//        content.put("containslnvalid", false);//是否包含失效用户
//        String contentStr = content.toJSONString();
//        RequestBody body = RequestBody.create(MediaType.parse("application/json"), contentStr);
//
//        Request request = new Request.Builder()
//                .url("https://api-test.gemdale.com/openApi/organization-center/emp/getEmpCount")
//                .post(body)
//                .addHeader("x-ca-key", "1838882415880818690")
//                .addHeader("x-ca-signature", "+fCDx073OeZDGPalliiigQ==")
//                .addHeader("x-ca-signature-method", "MD5")
//                .addHeader("content-type", "application/json")
//                .build();
//        Response response = client.newCall(request).execute();
//        if (response.isSuccessful()) {
//            Map result = objectMapper.readValue(response.body().string(), Map.class);
//            Boolean success = (Boolean) result.get("success");
//            if (success) {
//                total = (int) result.get("total");
//            } else {
//                String msg = (String) result.get("msg");
//                throw new BOSException(msg);
//            }
//        } else {
//            throw new BOSException("请求失败");
//        }
//        System.out.println("total: " + total);
//        boolean flag = true;
//        int pageCount = total % 100 == 0 ? total / 100 : total / 100 + 1;
//        for (int page = 1; page <= pageCount && flag; page++) {
//            content = new JSONObject();
//            content.put("containslnvalid", false);//是否包含失效用户
//            content.put("pageSize", 100);
//            content.put("pageNum", page);
//            body = RequestBody.create(MediaType.parse("application/json"), content.toJSONString());
//            System.out.println("page: " + page);
//
//            request = new Request.Builder()
//                    .url("https://api-test.gemdale.com/openApi/organization-center/emp/getEmp")
//                    .post(body)
//                    .addHeader("x-ca-key", "1838882415880818690")
//                    .addHeader("x-ca-signature", "KvB3twvz5cYyffJlvZQo8Q==")
//                    .addHeader("x-ca-signature-method", "MD5")
//                    .addHeader("content-type", "application/json")
//                    .build();
//            response = client.newCall(request).execute();
//            if (response.isSuccessful()) {
//                String resultStr = response.body().string();
//                Map result = objectMapper.readValue(resultStr, Map.class);
//                Boolean success = (Boolean) result.get("success");
//                logger.error("查询用户数据: " + resultStr);
//                if (success) {
//                    List data = (List) result.get("data");
//                    for (int i = 0; i < data.size() && flag; i++) {
//                        Map<String, Object> map = (Map<String, Object>) data.get(i);
//                        String username = (String) map.get("username");
//                        if ("liucanyu1".equals(username)) {
//                            System.out.println("username: " + username);
//                            String cardType = (String) map.get("cardType");
//                            System.out.println("cardType: " + cardType);
//                            String cardNum = (String) map.get("cardNum");
//                            System.out.println("cardNum: " + cardNum);
//                            if (!StringUtils.isEmpty(cardNum)) {
//                                System.out.println("cardNum: " + cardNum);
//                            }
//                            String email = (String) map.get("email");
//                            System.out.println("email: " + email);
//                            String userId = null;
//                            if (!StringUtils.isEmpty(cardNum)) {
//                                if (!StringUtils.isEmpty(cardType) && cardType.contains("身份证")) {
//                                    userId = idCardNoMap.get(cardNum);
//                                } else {
//                                    userId = passportNoMap.get(cardNum);
//                                }
//                            } else {
//                                userId = emailMap.get(email);
//                            }
//                            System.out.println("userId: " + userId);
//                            flag = false;
//                        }
//                    }
//                } else {
//                    String msg = (String) result.get("msg");
//                    throw new BOSException(msg);
//                }
//            } else {
//                throw new BOSException("请求失败");
//            }
//        }
//    }
}