package com.engine.kq.biz;

import com.engine.kq.entity.KQGroupEntity;
import com.engine.kq.log.KQLog;
import weaver.cache.*;
import weaver.common.DateUtil;
import weaver.conn.RecordSet;
import weaver.general.Util;
import weaver.hrm.resource.ResourceComInfo;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class KQGroupMemberComInfo extends CacheBase implements Serializable {
  /*
   * 需要关注 : 如果完全在 initCache 自己定义数据初始化， 这个字段可以不定义
   */
  protected static String TABLE_NAME = "";

  /*
   * 需要关注 : 如果完全在 initCache 自己定义数据初始化，或者不需要指定固定的条件， 这个字段可以不定义
   * sql中的where信息，不要以where开始
   */
  protected static String TABLE_WHERE = null;

  /*
   * 需要关注 : 如果完全在 initCache 自己定义数据初始化，或者不需要指定顺序， 这个字段可以不定义 sql中的order
   * by信息，不要以order by开始
   *
   */
  protected static String TABLE_ORDER = null;

  @PKColumn(type = CacheColumnType.NUMBER)
  protected static String PK_NAME = "id";

  @CacheColumn
  protected static int group;

  private KQLog kqLog = new KQLog();

  private boolean isFormat = false;

  @Override
  public CacheItem initCache(String key) {
    if (key == null || "".equals(key.trim())) {
      return null;
    }

    RecordSet rs = new RecordSet();
    String sql = "";
    kqLog = new KQLog();
    ConcurrentHashMap<String, List> resourceKQGroups = new ConcurrentHashMap<>();
    //考勤组优先级
    try {
      ResourceComInfo resourceComInfo = new ResourceComInfo();

      String subcompanyid = Util.null2String(resourceComInfo.getSubCompanyID(key));//分部
      String departmentid = Util.null2String(resourceComInfo.getDepartmentID(key));//部门
      String jobtitle = Util.null2String(resourceComInfo.getJobTitle(key));//岗位

      //人员
      sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
              " WHERE a.id=b.typevalue and b.type =1 and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1')" +
              " and a.id = "+key+
              " order by b.groupid desc ";
      rs.executeQuery(sql);
      while (rs.next()) {
        setMemberGroup(resourceKQGroups, rs.getString("resourceid"), rs.getString("groupid"));
      }    

      //部门
      if(departmentid.length()>0) {
        sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b , kq_group c" +
                " WHERE a.departmentid = b.typevalue AND a.seclevel>=b.seclevel AND a.seclevel<=b.seclevelto AND b.type=3 " +
                " and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') " +
                " and a.departmentid = " + departmentid +
                " and a.id="+key+
                " order by b.groupid desc";
        rs.executeQuery(sql);
        while (rs.next()) {
          setMemberGroup(resourceKQGroups, rs.getString("resourceid"), rs.getString("groupid"));
        }
      }
	  
	  //分部
      if(subcompanyid.length()>0) {
        sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
                " WHERE a.subcompanyid1 = b.typevalue AND a.seclevel>=b.seclevel AND a.seclevel<=b.seclevelto AND b.type=2 " +
                " and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') " +
                " and a.subcompanyid1 = " + subcompanyid +
                " and a.id="+key+
                " order by b.groupid desc ";
        rs.executeQuery(sql);
        while (rs.next()) {
          setMemberGroup(resourceKQGroups, rs.getString("resourceid"), rs.getString("groupid"));
        }
      }

      //岗位
      if(jobtitle.length()>0) {
        sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
                " WHERE a.jobtitle = b.typevalue AND b.type=5 " +
                " AND (b.jobtitlelevel=1 OR (b.jobtitlelevel=2 AND a.subcompanyid1 IN(b.jobtitlelevelvalue)) OR (b.jobtitlelevel=3 AND a.departmentid IN(b.jobtitlelevelvalue))) " +
                " and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') " +
                " and a.jobtitle = " + jobtitle +
                " and a.id="+key+
                " order by b.groupid desc ";
        rs.executeQuery(sql);
        while (rs.next()) {
          setMemberGroup(resourceKQGroups, rs.getString("resourceid"), rs.getString("groupid"));
        }
      }

      //所有人
      sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
              " WHERE (b.type=6 AND a.seclevel>=b.seclevel AND a.seclevel<=b.seclevelto) and b.groupid=c.id " +
              " and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') " +
              " and a.id = "+key+
              " order by b.groupid desc ";
      rs.executeQuery(sql);
      while (rs.next()) {
        setMemberGroup(resourceKQGroups, rs.getString("resourceid"), rs.getString("groupid"));
      }

      if(resourceKQGroups.size()>0){
        CacheItem cacheItem = createCacheItem();
        Iterator<Map.Entry<String, List>> iterator = resourceKQGroups.entrySet().iterator();
        while (iterator.hasNext()) {
          Map.Entry<String, List> entry = iterator.next();
          String id = entry.getKey();
          List value = entry.getValue();
          cacheItem.set(PK_INDEX, id);
          cacheItem.set(group, value);
          modifyCacheItem(key, cacheItem);
        }
        return cacheItem;
      }
    } catch (Exception e) {
      kqLog.info(e);
    }
    return null;
  }

  @Override
  public CacheMap initCache() {
    CacheMap localData = createCacheMap();
    RecordSet rs = new RecordSet();
    String sql = "";
    kqLog = new KQLog();
    ConcurrentHashMap<String, List> resourceKQGroups = new ConcurrentHashMap<>();
    //考勤组优先级
    try {
      //人员
      sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
              " WHERE a.id=b.typevalue and b.type =1 and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') order by b.groupid desc ";
      rs.executeQuery(sql);
      while (rs.next()) {
        setMemberGroup(resourceKQGroups, rs.getString("resourceid"), rs.getString("groupid"));
      }
	  
	  //部门
      sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b , kq_group c" +
              " WHERE a.departmentid = b.typevalue AND a.seclevel>=b.seclevel AND a.seclevel<=b.seclevelto AND b.type=3 " +
              " and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') order by b.groupid desc";
      rs.executeQuery(sql);
	   while (rs.next()) {
        setMemberGroup(resourceKQGroups, rs.getString("resourceid"), rs.getString("groupid"));
      }

      //分部
      sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
              " WHERE a.subcompanyid1 = b.typevalue AND a.seclevel>=b.seclevel AND a.seclevel<=b.seclevelto AND b.type=2 " +
              " and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') order by b.groupid desc ";
      rs.executeQuery(sql);           
      while (rs.next()) {
        setMemberGroup(resourceKQGroups, rs.getString("resourceid"), rs.getString("groupid"));
      }

      //岗位
      sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
              " WHERE a.jobtitle = b.typevalue AND b.type=5 " +
              " AND (b.jobtitlelevel=1 OR (b.jobtitlelevel=2 AND a.subcompanyid1 IN(b.jobtitlelevelvalue)) OR (b.jobtitlelevel=3 AND a.departmentid IN(b.jobtitlelevelvalue))) " +
              " and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') order by b.groupid desc ";
      rs.executeQuery(sql);
      while (rs.next()) {
        setMemberGroup(resourceKQGroups, rs.getString("resourceid"), rs.getString("groupid"));
      }

      //所有人
      sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
              " WHERE (b.type=6 AND a.seclevel>=b.seclevel AND a.seclevel<=b.seclevelto) and b.groupid=c.id " +
              " and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') order by b.groupid desc ";
      rs.executeQuery(sql);
      while (rs.next()) {
        setMemberGroup(resourceKQGroups, rs.getString("resourceid"), rs.getString("groupid"));
      }

      if(resourceKQGroups.size()>0) {
        Iterator<Map.Entry<String, List>> iterator = resourceKQGroups.entrySet().iterator();
        while (iterator.hasNext()) {
          Map.Entry<String, List> entry = iterator.next();
          String id = entry.getKey();
          List value = entry.getValue();
          CacheItem cacheItem = createCacheItem();
          cacheItem.set(PK_INDEX, id);
          cacheItem.set(group, value);
          modifyCacheItem(id, cacheItem);
          localData.put(id, cacheItem);
        }
      }
    } catch (Exception e) {
      kqLog.writeLog(e);
    }
    return localData;
  }

  private void setMemberGroup(ConcurrentHashMap resourceKQGroups, String resourceid, String groupid) {
    try {
      List<Object> kqGroups = null;
      if (resourceKQGroups.get(resourceid) == null) {
        kqGroups = new ArrayList<>();
      } else {
        kqGroups = (List<Object>) resourceKQGroups.get(resourceid);
      }
      kqGroups.add(groupid);
      resourceKQGroups.put(resourceid, kqGroups);
    } catch (Exception e) {
      kqLog.info(e);
    }
  }

  public String getKQGroupId(String userId) {
    String workDate = DateUtil.getCurrentDate();
    return getKQGroupId(userId, workDate);
  }

  /**
   * 根据user获取考勤组id
   *
   * @param userId
   * @return
   */
  public String getKQGroupId(String userId, String workDate) {
    return getKQGroupId(userId, workDate, true);
  }

  /***
   * 根据user获取考勤组id
   * @param userId
   * @param workDate
   * @param containFixed 取不到排班取固定班
   * @return
   */
  public String getKQGroupId(String userId, String workDate, boolean containFixed) {
    String groupId = "";
    KQGroupComInfo kqGroupComInfo = new KQGroupComInfo();
    List<String> lsGroupIds = this.getKQGroups(userId);
    for (int i = 0; lsGroupIds != null && i < lsGroupIds.size(); i++) {
      String tmpGroupId = Util.null2String((String) lsGroupIds.get(i));
      String kqtype = kqGroupComInfo.getKqtype(tmpGroupId);
      String validity = kqGroupComInfo.getValidity(tmpGroupId);
      String validityfromdate = kqGroupComInfo.getValidityfromdate(tmpGroupId);
      String validityenddate = kqGroupComInfo.getValidityenddate(tmpGroupId);
      if (validity.equals("1")) {
        if (DateUtil.isInDateRange(workDate, validityfromdate, validityenddate)) {
          groupId = tmpGroupId;
        }else{
          //超过有效期
          continue;
        }
      } else {
        groupId = tmpGroupId;
      }

      //考勤组如果排班为空，取下一个考勤组
      if (groupId.length() > 0) {
        if (containFixed && kqtype.equals("2")) {
          KQShiftScheduleComInfo kqShiftScheduleComInfo = new KQShiftScheduleComInfo();
          if (Util.null2String(kqShiftScheduleComInfo.getSerialId(userId, workDate)).length() > 0 &&
                  Util.null2String(kqShiftScheduleComInfo.getGroupId(userId, workDate)).equals(groupId)) {
            break;
          }
        } else {
          break;
        }
      }
    }
    return groupId;
  }

  /**
   * 根据user获取所有考勤组
   *
   * @param userId
   * @return
   */
  public List<String> getKQGroups(String userId) {
    if(!this.isFormat){
      return (List<String>) getObjValue(group, userId);
    }
    RecordSet rs = new RecordSet();
    String sql = "";
    kqLog = new KQLog();
    List<String> kqGroups = new ArrayList<>();
    //考勤组优先级
    try {
      ResourceComInfo resourceComInfo = new ResourceComInfo();

      String subcompanyid = Util.null2String(resourceComInfo.getSubCompanyID(userId));//分部
      String departmentid = Util.null2String(resourceComInfo.getDepartmentID(userId));//部门
      String jobtitle = Util.null2String(resourceComInfo.getJobTitle(userId));//岗位

      //人员
      sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
        " WHERE a.id=b.typevalue and b.type =1 and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1')" +
        " and a.id = "+userId+
        " order by b.groupid desc ";
      rs.executeQuery(sql);
      while (rs.next()) {
        kqGroups.add(rs.getString("groupid"));
      }

      //部门
      if(departmentid.length()>0) {
        sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b , kq_group c" +
          " WHERE a.departmentid = b.typevalue AND a.seclevel>=b.seclevel AND a.seclevel<=b.seclevelto AND b.type=3 " +
          " and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') " +
          " and a.departmentid = " + departmentid +
          " and a.id="+userId+
          " order by b.groupid desc";
        rs.executeQuery(sql);
        while (rs.next()) {
          kqGroups.add(rs.getString("groupid"));
        }
      }

      //分部
      if(subcompanyid.length()>0) {
        sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
          " WHERE a.subcompanyid1 = b.typevalue AND a.seclevel>=b.seclevel AND a.seclevel<=b.seclevelto AND b.type=2 " +
          " and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') " +
          " and a.subcompanyid1 = " + subcompanyid +
          " and a.id="+userId+
          " order by b.groupid desc ";
        rs.executeQuery(sql);
        while (rs.next()) {
          kqGroups.add(rs.getString("groupid"));
        }
      }

      //岗位
      if(jobtitle.length()>0) {
        sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
          " WHERE a.jobtitle = b.typevalue AND b.type=5 " +
          " AND (b.jobtitlelevel=1 OR (b.jobtitlelevel=2 AND a.subcompanyid1 IN(b.jobtitlelevelvalue)) OR (b.jobtitlelevel=3 AND a.departmentid IN(b.jobtitlelevelvalue))) " +
          " and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') " +
          " and a.jobtitle = " + jobtitle +
          " and a.id="+userId+
          " order by b.groupid desc ";
        rs.executeQuery(sql);
        while (rs.next()) {
          kqGroups.add(rs.getString("groupid"));
        }
      }

      //所有人
      sql = " SELECT distinct a.id AS resourceid, b.groupid, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
        " WHERE (b.type=6 AND a.seclevel>=b.seclevel AND a.seclevel<=b.seclevelto) and b.groupid=c.id " +
        " and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1') " +
        " and a.id = "+userId+
        " order by b.groupid desc ";
      rs.executeQuery(sql);
      while (rs.next()) {
        kqGroups.add(rs.getString("groupid"));
      }
    } catch (Exception e) {
      kqLog.info(e);
    }
    return kqGroups;
  }

  /**
   * 根据user获取所有考勤组id
   *
   * @param userId
   * @return
   */
  public String getKQGroupIds(String userId) {
    String groupId = "";
    List<String> lsGroupIds = this.getKQGroups(userId);
    if (lsGroupIds != null) {
      groupId = String.join(",", lsGroupIds);
    }
    return groupId;
  }


  public KQGroupEntity getUserKQGroupInfo(String userId) {
    String workDate = DateUtil.getCurrentDate();
    return getUserKQGroupInfo(userId, workDate);
  }

  /**
   * 获取考勤组相关信息
   *
   * @param userId
   * @return
   */
  public KQGroupEntity getUserKQGroupInfo(String userId, String workDate) {
    return getUserKQGroupInfo(userId, workDate, true);
  }

  /***
   * 获取考勤组相关信息
   * @param userId
   * @param workDate
   * @param containFixed 取不到排班取固定班
   * @return
   */
  public KQGroupEntity getUserKQGroupInfo(String userId, String workDate, boolean containFixed) {
    KQGroupEntity kqGroupEntity = null;
    KQGroupComInfo kqGroupComInfo = new KQGroupComInfo();
    try {
      String groupid = Util.null2String(this.getKQGroupId(userId, workDate, containFixed));
      if (groupid.length() > 0) {
        kqGroupEntity = new KQGroupEntity();
        kqGroupEntity.setId(groupid);
        kqGroupEntity.setGroupname(kqGroupComInfo.getGroupname(groupid));
        kqGroupEntity.setExcludeid(kqGroupComInfo.getExcludeid(groupid));
        kqGroupEntity.setSubcompanyid(kqGroupComInfo.getSubcompanyid(groupid));
        kqGroupEntity.setKqtype(kqGroupComInfo.getKqtype(groupid));
        kqGroupEntity.setSerialids(kqGroupComInfo.getSerialids(groupid));
        kqGroupEntity.setWeekday(kqGroupComInfo.getWeekday(groupid));
        kqGroupEntity.setSignstart(kqGroupComInfo.getSignstart(groupid));
        kqGroupEntity.setWorkhour(kqGroupComInfo.getWorkhour(groupid));
        kqGroupEntity.setIsdelete(kqGroupComInfo.getIsdelete(groupid));
        kqGroupEntity.setSignintype(kqGroupComInfo.getSignintype(groupid));
        kqGroupEntity.setIpscope(kqGroupComInfo.getIpscope(groupid));
        kqGroupEntity.setLocationcheck(kqGroupComInfo.getLocationcheck(groupid));
        kqGroupEntity.setLocationcheckscope(kqGroupComInfo.getLocationcheckscope(groupid));
        kqGroupEntity.setWificheck(kqGroupComInfo.getWificheck(groupid));
        kqGroupEntity.setOutsidesign(kqGroupComInfo.getOutsidesign(groupid));
        kqGroupEntity.setCalmethod(kqGroupComInfo.getCalmethod(groupid));
        kqGroupEntity.setLocationshowaddress(kqGroupComInfo.getLocationshowaddress(groupid));
      }
    } catch (Exception e) {
      kqLog.info(e);
    }
    return kqGroupEntity;
  }

  public void removeCache() {
    super.removeCache();
  }

  public void setIsFormat(boolean isFormat){
    this.isFormat = isFormat;
  }
}