package com.engine.kq.biz;

import com.engine.integration.util.MyX509TrustManager;
import com.engine.kq.log.KQLog;
import net.sf.json.JSONObject;
import weaver.common.DateUtil;
import weaver.conn.RecordSet;
import weaver.file.Prop;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.systeminfo.SystemEnv;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.*;

/**
 * 节假日设置相关接口数据
 */
public class KQHolidaySetBiz {

    private static KQLog logger = new KQLog();

    /**
     * 获取指定考勤组ID获取节假日设置数据
     *
     * @param resourceId 指定人员的ID
     * @param year       指定年份
     * @param month      指定月份 指定月份为空时查询指定年份一整年的数据
     * @return
     */
    public static List getGroupHolidaySetList(String groupId, String year, String month) {
        List<Map<String, Object>> valueList = new ArrayList<Map<String, Object>>();
        Map<String, Object> valueMap = new HashMap<String, Object>();
        /*指定年月*/
        String startDate = year;
        String endDate = month;
        if (month.length() == 0) {
            startDate = year + "-01" + "-01";
            endDate = year + "-12" + "-31";
        } else if (month.length() == 1) {
            startDate = year + "-0" + month + "-01";
            endDate = year + "-0" + month + "-31";
        } else if (month.length() == 2) {
            startDate = year + "-" + month + "-01";
            endDate = year + "-" + month + "-31";
        }
        RecordSet recordSet = new RecordSet();
        KQGroupMemberComInfo kqGroupMemberComInfo = new KQGroupMemberComInfo();
        KQHolidaySetComInfo holidaySetComInfo = new KQHolidaySetComInfo();
        boolean isEnd = false;
        for (String date = startDate; !isEnd; ) {
            if (date.compareTo(endDate) >= 0) {
                isEnd = true;
            }

            String changeType = holidaySetComInfo.getChangeType(groupId, date);
            String holidayDesc = holidaySetComInfo.getHolidayDesc(groupId, date);
            if (!changeType.equals("")) {
                valueMap = new HashMap<String, Object>();
                valueMap.put("date", date);
                valueMap.put("name", holidayDesc);
                valueMap.put("type", changeType);
                valueList.add(valueMap);
            }
            date = DateUtil.getDate(date, 1);
        }
        return valueList;
    }

    /**
     * 获取指定考勤组ID获取节假日设置数据
     *
     * @param resourceId 指定人员的ID
     * @param year       指定年份
     * @param month      指定月份 指定月份为空时查询指定年份一整年的数据
     * @return
     */
    public static List getKQHolidaySetList(String resourceId, String year, String month) {
        Map<String, Object> valueMap = new HashMap<String, Object>();
        List<Map<String, Object>> valueList = new ArrayList<Map<String, Object>>();

        /*指定年月*/
        String startDate = year;
        String endDate = month;
        if (month.length() == 0) {
            startDate = year + "-01" + "-01";
            endDate = year + "-12" + "-31";
        } else if (month.length() == 1) {
            startDate = year + "-0" + month + "-01";
            endDate = year + "-0" + month + "-31";
        } else if (month.length() == 2) {
            startDate = year + "-" + month + "-01";
            endDate = year + "-" + month + "-31";
        }
        valueList = getHolidaySetListByScope(resourceId, startDate, endDate);
        return valueList;
    }

    /**
     * 根据日期范围获取节假日数据
     *
     * @param resourceId 指定人员的ID
     * @param startDate  指定日期范围的起点
     * @param endDate    指定日期范围的终点
     * @return
     */
    public static List getHolidaySetListByScope(String resourceId, String startDate, String endDate) {
        Map<String, Object> valueMap = new HashMap<String, Object>();
        List<Map<String, Object>> valueList = new ArrayList<Map<String, Object>>();

        RecordSet recordSet = new RecordSet();
        KQGroupMemberComInfo kqGroupMemberComInfo = new KQGroupMemberComInfo();
        KQHolidaySetComInfo holidaySetComInfo = new KQHolidaySetComInfo();

        boolean isEnd = false;
        for (String date = startDate; !isEnd; ) {
            if (date.compareTo(endDate) >= 0) {
                isEnd = true;
            }

            /*获取考勤组的ID，因为考勤组有有效期，所以需要传入日期*/
            String groupId = kqGroupMemberComInfo.getKQGroupId(resourceId, date);

            String changeType = holidaySetComInfo.getChangeType(groupId, date);
            String holidayDesc = holidaySetComInfo.getHolidayDesc(groupId, date);
            if (!changeType.equals("")) {
                valueMap = new HashMap<String, Object>();
                valueMap.put("date", date);
                valueMap.put("name", holidayDesc);
                valueMap.put("type", changeType);
                valueList.add(valueMap);
            }
            date = DateUtil.getDate(date, 1);
        }
        return valueList;
    }


    /**
     * 判断某天是否是节假日（公众假日+调配休息日）
     *
     * @param resourceId 指定人员ID
     * @param date       指定日期
     * @return true-节假日、false、不是节假日
     */
    public static boolean isHoliday(String resourceId, String date) {
        return isHoliday(resourceId, date, false);
    }

    /**
     * 判断某天是否是节假日（公众假日+调配休息日+周末）
     *
     * @param resourceId     指定人员ID
     * @param date           指定日期
     * @param containWeekend 是否包含周末 为true包含周末、false不包含
     * @return true-节假日、false、不是节假日
     */
    public static boolean isHoliday(String resourceId, String date, boolean containWeekend) {
        boolean flag = false;

        /*获取考勤组的ID，因为考勤组有有效期，所以需要传入日期*/
        KQGroupMemberComInfo kqGroupMemberComInfo = new KQGroupMemberComInfo();
        String groupId = kqGroupMemberComInfo.getKQGroupId(resourceId, date);

        int changeType = getChangeType(groupId, date);
        /*如果需要包含周末，判断传入的日期是不是周末*/
        if (containWeekend && changeType != 2 && (DateUtil.getWeek(date) == 6 || DateUtil.getWeek(date) == 7)) {
            flag = true;
        }
        if (changeType == 1 || changeType == 3) {
            flag = true;
        }
        return flag;
    }

    /**
     * 获取当前日期是何种类型(这里只考虑节假日设置)
     *
     * @param groupId 考勤组ID
     * @param date    指定日期
     * @return 1-节假日、2-工作日、3-休息日、-1-没有设置过数据
     */
    public static int getChangeType(String groupId, String date) {
        int changeType = -1;//默认没有设置过节假日(节假日设置的类型：1-公众假日、2-调配工作日、3-调配休息日)
        KQHolidaySetComInfo kqHolidaySetComInfo = new KQHolidaySetComInfo();
        changeType = Util.getIntValue(kqHolidaySetComInfo.getChangeType(groupId, date), -1);
        return changeType;
    }

    /**
     * 获取调配工作日时的指定工作日(当考勤组不属于排班制时)
     *
     * @param resourceId 指定人员的ID
     * @param date       指定日期
     * @return
     */
    public static int getRelatedDay(String resourceId, String date) {
        int relatedDay = -1;

        /*获取考勤组的ID，因为考勤组有有效期，所以需要传入日期*/
        KQGroupMemberComInfo kqGroupMemberComInfo = new KQGroupMemberComInfo();
        String groupId = kqGroupMemberComInfo.getKQGroupId(resourceId, date);

        /*排班制不支持调配节假日数据*/
        KQGroupComInfo kqGroupComInfo = new KQGroupComInfo();
        String KQType = kqGroupComInfo.getKqtype(groupId);//考勤类型：1-固定班制、2-排班制、3-自由班制
        if (KQType.equals("2")) {
            return relatedDay;
        }

        /*只有当调配工作日时才有对应工作日*/
        KQHolidaySetComInfo kqHolidaySetComInfo = new KQHolidaySetComInfo();
        int changeType = Util.getIntValue(kqHolidaySetComInfo.getChangeType(groupId, date), -1);
        if (changeType == 2) {
            relatedDay = Util.getIntValue(kqHolidaySetComInfo.getRelatedDay(groupId, date), 0);
        }

        return relatedDay;
    }

    /**
     * 指定的考勤组初始化节假日设置数据(只初始化固定班制和自由班制)
     *
     * @param groupIds 指定考勤组ID(多个ID之间用,分隔)
     * @param year     指定年份
     * @return
     */
    public static Map<String, Object> initHolidaySet(String groupIds, String year, User user) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        List<String> errInfoList = new ArrayList<String>();//错误信息集合
        /**
         * 调用网上的节假日API，数据格式如下(不是JSON字符串)：(此后如果原来的节假日API不能用了，只要调整将新的API接口调整成如下格式即可)
         * status：1-成功、0-失败
         * sketch：'简要描述错误原因'
         * holidayList：[{holidayDate:'',changeType:'',holidayDesc:''},……,{holidayDate:'',changeType:'',holidayDesc:''}]
         */
        String url = Prop.getInstance().getPropValue("kq_settings", "KQHolidaySetUrl");
        Map<String, Object> tempMap = httpRequest(url +"?year="+year+"&key="+Util.getEncrypt(Util.getRandom()), user);
        if ("0".equals((String) tempMap.get("status"))) {
            resultMap.put("status", "0");
            resultMap.put("sketch", (String) tempMap.get("sketch"));
            return resultMap;
        }
        List<String> holidayDateList = new ArrayList<String>();
        try {
            List<String> groupIdList = Util.TokenizerString(groupIds, ",");//考勤组ID集合
            for (int i = 0; i < groupIdList.size(); i++) {
                String groupId = groupIdList.get(i);
                /**
                 * 预先加载此考勤组已经调整了哪些日期了，如果某日期在初始化之前已经调整过了，删除掉原来的数据，插入新的数据
                 */
                List<String> dateList = new ArrayList<String>();
                KQHolidaySetComInfo kqHolidaySetComInfo = new KQHolidaySetComInfo();
                kqHolidaySetComInfo.setTofirstRow();
                while (kqHolidaySetComInfo.next()) {
                    if (kqHolidaySetComInfo.getGroupId().equals(groupId)) {
                        dateList.add(kqHolidaySetComInfo.getHolidayDate());
                    }
                }

                /**
                 * 预先加载固定班制周一~周日这一周中一天开始上班的是周几
                 */
                int relatedDay = 0;
                for (int x = 0; x < 7; x++) {
                    KQFixedSchedulceComInfo kqFixedSchedulceComInfo = new KQFixedSchedulceComInfo();
                    String serialId = Util.null2String(kqFixedSchedulceComInfo.getSerialid(groupId, x));
                    if (!serialId.equals("")) {
                        relatedDay = x;
                        break;
                    }
                }

                /**
                 * 初始化改考勤组的节假日数据(只初始化)
                 */
                boolean flag = true;
                RecordSet recordSet = new RecordSet();
                KQGroupComInfo kqGroupComInfo = new KQGroupComInfo();

                List<Map<String, Object>> holidayList = (List<Map<String, Object>>) tempMap.get("holidayList");
                Map<String, Object> holidayMap = new HashMap<String, Object>();
                for (int j = 0; j < holidayList.size(); j++) {
                    holidayMap = holidayList.get(j);

                    String holidayDate = year + "-" + (String) holidayMap.get("holidayDate");
                    if (!holidayDateList.contains(holidayDate)) {
                        holidayDateList.add(holidayDate);
                    }
                    int changeType = (int) holidayMap.get("changeType");
                    if (kqGroupComInfo.getKqtype(groupId).equals("2")&&changeType == 2 ) {
                        //排班制的考勤组不能初始化调配工作日
                        continue;
                    }
                    String holidayDesc = (String) holidayMap.get("holidayDesc");
                    if (dateList.contains(holidayDate)) {
                        String deleteSql = "delete from kq_HolidaySet where groupId=? and holidayDate=?";
                        recordSet.executeUpdate(deleteSql, groupId, holidayDate);
                    }

                    String sql = "insert into kq_HolidaySet(groupId,holidayDate,changeType,holidayDesc,relatedDay) values(?,?,?,?,?)";
                    flag = recordSet.executeUpdate(sql, groupId, holidayDate, changeType, holidayDesc, relatedDay);
                    if (!flag) {
                        errInfoList.add(SystemEnv.getHtmlLabelName(5056701, user.getLanguage()).replace("$groupName$", kqGroupComInfo.getGroupname(groupId)).replace("$holidayDate$", holidayDate));
                    }
                }
            }

            /**
             * 如果没有错误信息则代表初始化成功
             */
            if (errInfoList.size() > 0) {
                resultMap.put("status", "0");
                resultMap.put("sketch", SystemEnv.getHtmlLabelName(125960, user.getLanguage()));
                resultMap.put("description", errInfoList);
            } else {
                resultMap.put("status", "1");
                resultMap.put("sketch", SystemEnv.getHtmlLabelName(20196, user.getLanguage()));
            }
        } catch (Exception e) {
            resultMap.put("status", "0");
            resultMap.put("sketch", SystemEnv.getHtmlLabelName(382661, user.getLanguage()));
            resultMap.put("desscription", errInfoList);
        } finally {
            /*刷新缓存*/
            KQHolidaySetComInfo kqHolidaySetComInfo = new KQHolidaySetComInfo();
            kqHolidaySetComInfo.removeCache();

            /*刷新考勤报表*/
            logger.info("初始化节假日数据，格式化考勤报表。groupIdList=" + com.alibaba.fastjson.JSONObject.toJSONString(groupIds) +
                    "。holidayDateList=" + com.alibaba.fastjson.JSONObject.toJSONString(holidayDateList));
            List<String> groupIdList = Util.TokenizerString(groupIds, ",");//考勤组ID集合
            new KQHolidaySetThread(groupIdList,holidayDateList).start();
        }
        return resultMap;
    }

    /**
     * 请求网络上的节假日API接口，获取节假日设置数据
     *
     * @param requestUrl
     * @return
     */
    private static Map<String, Object> httpRequest(String requestUrl, User user) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        //buffer用于接受返回的字符
        StringBuffer buffer = new StringBuffer();
        try {
            TrustManager[] tm = {new MyX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url= new URL(null, requestUrl, new sun.net.www.protocol.https.Handler());
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            httpUrlConn.setRequestMethod("GET");
            httpUrlConn.connect();

            //获得输入
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            //将bufferReader的值给放到buffer里
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            //关闭bufferReader和输入流
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            //断开连接
            httpUrlConn.disconnect();

            /**
             * 解析JSON字符串
             */
            String jsonStr = buffer.toString();
            JSONObject jsonObject = JSONObject.fromObject(jsonStr).getJSONObject("data");
            int code = jsonObject.optInt("code");//0服务正常。-1服务出错
            if (code != 0) {
                //初始化节假日失败，获取网络服务出错
                resultMap.put("status", "0");
                resultMap.put("sketch", SystemEnv.getHtmlLabelName(520011, user.getLanguage()));
                return resultMap;
            }
            JSONObject holiday = jsonObject.getJSONObject("holiday");
            if (holiday.size() == 0) {
                //初始化节假日失败，暂未获取到所选年份的节假日数据
                resultMap.put("status", "0");
                resultMap.put("sketch", SystemEnv.getHtmlLabelName(505673, user.getLanguage()));
                return resultMap;
            }
            Map<String, Object> holidayMap = new HashMap<String, Object>();
            List<Map<String, Object>> holidayList = new ArrayList<Map<String, Object>>();
            Iterator iterator = holiday.keys();
            while (iterator.hasNext()) {
                holidayMap = new HashMap<String, Object>();

                String holidayDate = (String) iterator.next();
                holidayMap.put("holidayDate", holidayDate);//日期
                JSONObject detailInfo = holiday.getJSONObject(holidayDate);
                int wage = detailInfo.optInt("wage");
                if (wage == 1) {
                    holidayMap.put("changeType", 2);//调配工作日
                } else if (wage == 2) {
                    holidayMap.put("changeType", 3);//调配休息日
                } else if (wage == 3) {
                    holidayMap.put("changeType", 1);//公众假日
                }
                String holidayDesc = detailInfo.getString("name");
                holidayMap.put("holidayDesc", holidayDesc);//说明

                holidayList.add(holidayMap);
            }
            resultMap.put("status", "1");
            resultMap.put("sketch", SystemEnv.getHtmlLabelName(505674, user.getLanguage()));
            resultMap.put("holidayList", holidayList);
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("status", "0");
            resultMap.put("sketch", SystemEnv.getHtmlLabelName(520011, user.getLanguage()));
            return resultMap;
        }
        return resultMap;
    }

}
