package com.engine.kq.cmd.report4E;

import com.alibaba.fastjson.JSON;
import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.entity.BizLogContext;
import com.engine.core.interceptor.CommandContext;
import com.engine.kq.biz.KQFormatBiz;
import com.engine.kq.biz.KQFormatData;
import com.engine.kq.biz.KQGroupBiz;
import com.engine.kq.cmd.attendanceButton.ButtonStatusEnum;
import com.engine.kq.log.KQLog;
import com.engine.kq.timer.KQQueue;
import com.engine.kq.timer.KQTaskBean;
import com.engine.kq.util.KQDurationCalculatorUtil;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import net.sf.json.JSONObject;
import weaver.common.DateUtil;
import weaver.conn.RecordSet;
import weaver.dateformat.TimeZoneVar;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.systeminfo.SystemEnv;

/**
 * 小E 签到签退
 * 针对正式系统 没有处理跨天和多班次的情况
 * 没有处理加班的情况
 */
public class PunchButton4ECmd extends AbstractCommonCommand<Map<String, Object>> {
  private KQLog kqLog = new KQLog();
  private HttpServletRequest request;

	public PunchButton4ECmd(HttpServletRequest request,Map<String, Object> params, User user) {
		this.request = request;
	  this.user = user;
		this.params = params;
	}

	@Override
	public Map<String, Object> execute(CommandContext commandContext) {
		Map<String, Object> retmap = new HashMap<String, Object>();
		try{
      kqLog.info(user.getLastname()+":PunchButton4ECmd:params:"+params);
      insertSign(retmap);
    }catch (Exception e) {
      retmap.put("status", "-1");
      retmap.put("message",  SystemEnv.getHtmlLabelName(382661,user.getLanguage()));
      kqLog.info("PunchButton4ECmd报错::");
      StringWriter errorsWriter = new StringWriter();
      e.printStackTrace(new PrintWriter(errorsWriter));
      kqLog.info(errorsWriter.toString());
		}
		return retmap;
	}

  public void insertSign(Map<String, Object> retmap) throws Exception{

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
    LocalDateTime localDateTime = LocalDateTime.now();

    String curDate = localDateTime.format(dateFormatter);

    Map<String, Object> todayLineMap = KQDurationCalculatorUtil.getWorkButton(user, curDate,false);

    RecordSet rs = new RecordSet();
    KQFormatData kqFormatData = new KQFormatData();
    int userId = user.getUID();
    //小e的不考虑跨天
    String belongdate = "";

    String signDate = curDate;
    String signTime =localDateTime.format(dateTimeFormatter);

    String userType = user.getLogintype();
    String clientAddress = Util.getIpAddr(request);
    String isInCom = "1";
    String timeZone = Util.null2String(TimeZoneVar.getTimeZone(),"");

    String signType = Util.null2String(params.get("signtype"));
    String signStatus = ButtonStatusEnum.NORMAL.getStatusCode();;
    //手机打卡部分
    String longitude = Util.null2String(params.get("longitude"));
    String latitude = Util.null2String(params.get("latitude"));

    String position = request.getParameter("position");
    if(Util.null2String(position).length() > 0){
//      String decode_pos = java.net.URLDecoder.decode(position, "UTF-8");
//      //小E 是get方式请求的，中文的话addr是乱码，需要decode+byte处理下
//      String byte_decode_pos = new String(decode_pos.getBytes("ISO-8859-1"),"UTF-8");
//      position = byte_decode_pos;
    }else{
      position = getPosition(longitude,latitude);
    }

    String deviceInfo = Util.null2String(params.get("deviceInfo"));
    com.alibaba.fastjson.JSONObject jsonObject = null;
    if(deviceInfo.length() > 0){
      jsonObject = JSON.parseObject(deviceInfo);
      com.alibaba.fastjson.JSONObject jsonObject1 = new com.alibaba.fastjson.JSONObject();
      Set<Entry<String, Object>> jsonSet =  jsonObject.entrySet();
      for(Entry<String, Object> js : jsonSet){
        String key = js.getKey();
        String value = Util.null2String(js.getValue());
        jsonObject1.put(key, value);
      }
      if(!jsonObject1.isEmpty()){
        deviceInfo = jsonObject1.toJSONString();
      }
    }

//    String addr = Util.null2String(params.get("position"));

    //记录下是来自于E9的小e签到
    String signfrom = "e9e";
    //打卡所属的工作时段
    String worksection = Util.null2String(params.get("worksection"));
    String belongtime = Util.null2String(params.get("belongtime"));

    KQGroupBiz kqGroupBiz = new KQGroupBiz();
    Map<String,Object> locationMap = kqGroupBiz.checkLocationScope(userId+"",longitude,latitude);
    String locationNeedCheck = Util.null2String(locationMap.get("needCheck"));
    boolean locationInScope = Boolean.parseBoolean(Util.null2String(locationMap.get("inScope")));
    if("1".equalsIgnoreCase(locationNeedCheck)){
      if(!locationInScope){
        retmap.put("status", "2");
        retmap.put("message",  SystemEnv.getHtmlLabelName(500510, user.getLanguage()));
        isInCom = "0";
      }
    }

    if(todayLineMap.get("timelineList") != null){
      List<Object> todayLine = (List<Object>)todayLineMap.get("timelineList");
      if(todayLine != null && !todayLine.isEmpty() && todayLine.size() >= 2){
        Map<String,Object> onTimelineMap = (Map<String,Object>)todayLine.get(0);
        Map<String,Object> offTimelineMap = (Map<String,Object>)todayLine.get(1);

        String onTime = Util.null2String(onTimelineMap.get("time"));
        String offTime = Util.null2String(offTimelineMap.get("time"));

        LocalTime onTimeLocal = LocalTime.parse(onTime+":00", dateTimeFormatter);
        LocalTime offTimeLocal = LocalTime.parse(offTime+":00", dateTimeFormatter);

        int onMin = Util.getIntValue(Util.null2String(onTimelineMap.get("min")),60);
        LocalTime onCanTimeLocal = LocalTime.parse(onTime+":00", dateTimeFormatter).minusMinutes(onMin);
        int offMin = Util.getIntValue(Util.null2String(offTimelineMap.get("min")),60);
        LocalTime offCanTimeLocal = LocalTime.parse(offTime+":59", dateTimeFormatter).plusMinutes(offMin);

        String signOnDateTime = curDate+" 00:00:00";
        String signOffDateTime = curDate+" 23:59:59";

        if(onCanTimeLocal.isBefore(onTimeLocal) && offCanTimeLocal.isAfter(offTimeLocal)){
          LocalTime nowLocal = localDateTime.toLocalTime();
          if(onCanTimeLocal != null && nowLocal.isBefore(onCanTimeLocal) && "1".equalsIgnoreCase(signType)){
            retmap.put("status", "2");
            retmap.put("message",  ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005338,weaver.general.ThreadVarLanguage.getLang())+"");
            isInCom = "0";
          }
          if(offCanTimeLocal != null && nowLocal.isAfter(offCanTimeLocal)){
            if("1".equalsIgnoreCase(signType)){
              retmap.put("status", "2");
              retmap.put("message",  ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005339,weaver.general.ThreadVarLanguage.getLang())+"");
              isInCom = "0";
            }
            if("2".equalsIgnoreCase(signType)){
              retmap.put("status", "2");
              retmap.put("message",  ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005340,weaver.general.ThreadVarLanguage.getLang())+"");
              isInCom = "0";
            }
          }
          signOnDateTime = curDate+" "+onCanTimeLocal.format(dateTimeFormatter);
          signOffDateTime = curDate+" "+offCanTimeLocal.format(dateTimeFormatter);
        }
        String signedMsg = signedMsg(userId+"",signType,user, signOnDateTime, signOffDateTime);
        if(signedMsg != null && signedMsg.length() > 0){
          retmap.put("status", "2");
          retmap.put("message",  signedMsg);
          isInCom = "0";
        }

        //打卡所属的工作时段
        worksection = onTime+"-"+offTime;

        if("1".equalsIgnoreCase(signType)){
          belongtime = onTime;
        }else{
          belongtime = offTime;
        }
        signStatus = getSignStatus(signType,onTime,offTime,signTime);
        belongdate = curDate;
      }else{
        kqLog.info("PunchButton4ECmd:userid"+userId+":curDate:"+curDate+":todayLine:"+todayLine);
      }
    }else{
      kqLog.info("PunchButton4ECmd:userid"+userId+":curDate:"+curDate+":todayLineMap:"+todayLineMap);
    }

    String punchSql = "insert into HrmScheduleSign(userId,userType,signType,signDate,signTime,clientAddress,isInCom,timeZone,belongdate,signfrom,longitude,latitude,addr,deviceInfo) "+
        " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
    boolean isOk = rs.executeUpdate(punchSql,userId,userType,signType,signDate,signTime,clientAddress,isInCom,
        timeZone,belongdate,signfrom,longitude,latitude,position,deviceInfo);
    if(!isOk){
      retmap.put("status", "-1");
      retmap.put("message",  SystemEnv.getHtmlLabelName(382661,user.getLanguage()));
      return ;
    }
    kqLog.info("PunchButton4ECmd:user.getLastname():"+user.getLastname()+":isOk:"+isOk+":punchSql:"+punchSql);

    //打卡提醒处理 还有微信企业钉钉打卡checkin4e.jsp别忘了
    String remindSql = "insert into hrmschedulesign_remind(userId,signType,signDate,signTime,belongdate) values(?,?,?,?,?)";
    isOk = rs.executeUpdate(remindSql, userId,signType,signDate,signTime,belongdate);
    kqLog.info(user.getLastname()+":PunchButtonCmd:remindSql:"+remindSql+":isOk:"+isOk);

    String messageDateTime = signDate+" "+signTime;
    if("".equalsIgnoreCase(Util.null2String(retmap.get("message")))){
      if("1".equalsIgnoreCase(signType)){
        retmap.put("message",  SystemEnv.getHtmlLabelName(10000832,weaver.general.Util.getIntValue(user.getLanguage()))+"<br/>"+messageDateTime);
      }else if("2".equalsIgnoreCase(signType)){
        retmap.put("message",  SystemEnv.getHtmlLabelName(10000833,weaver.general.Util.getIntValue(user.getLanguage()))+"<br/>"+messageDateTime);
      }
    }
    retmap.put("status", "1");
    retmap.put("signdate", signDate);
    retmap.put("signtime", signTime);
    retmap.put("position", position);

    //同步更新考勤数据到考勤报表
    new KQFormatBiz().formatDate(""+userId,(belongdate.length() == 0 ? DateUtil.getCurrentDate() : belongdate));
  }

  public String getPosition(String longitude, String latitude)  {
    String addrStr = "";
    try{
      String url="https://restapi.amap.com/v3/geocode/regeo?output=json&location="+longitude+","+latitude+"&key=fbe499c6f3d6d39af9fea6ff9971a7c8&radius=1000&extensions=all";

      URL tirc = new URL(url);
      BufferedReader in = new BufferedReader(new InputStreamReader(tirc.openStream(),"UTF-8"));
      String res;
      StringBuilder sb = new StringBuilder("");
      while((res = in.readLine())!=null){
        sb.append(res.trim());
      }
      String str = sb.toString();
      JSONObject jsonResult=JSONObject.fromObject(str);
      JSONObject detail = jsonResult.getJSONObject("regeocode");

      addrStr = detail.getString("formatted_address");
    }catch (Exception e){
      kqLog.info("PunchButton4ECmd getPosition:"+e.getMessage());
    }
    return addrStr;
  }

  /**
   * 校验是否已经签到过
   * @param userid
   * @param signtype
   * @param curUser
   * @param signOnDateTime
   * @param signOffDateTime
   * @return
   */
  public String signedMsg(String userid, String signtype, User curUser,String signOnDateTime,String signOffDateTime) throws Exception{
    String signedMsg = "";
    RecordSet rs = new RecordSet();
    boolean hasSigned = false;
    if(signOnDateTime.length() > 0 && signOffDateTime.length() > 0){
      String hasSign = "select 1 from hrmschedulesign where 1 = 1 and isInCom = '1' and userid = ? ";

      StringBuffer sql = new StringBuffer();
      if(rs.getDBType().equals("oracle")||rs.getDBType().equals("postgresql")){
        sql.append(" AND signDate||' '||signTime>=? ");
        sql.append(" AND signDate||' '||signTime<=? ");
      }else if(rs.getDBType().equals("mysql")){
        sql.append(" AND concat(signDate,' ',signTime)>=? ");
        sql.append(" AND concat(signDate,' ',signTime)<=? ");
      }else{
        sql.append(" AND signDate+' '+signTime>=? ");
        sql.append(" AND signDate+' '+signTime<=? ");
      }
      hasSign += sql.toString();
      rs.executeQuery(hasSign, userid,signOnDateTime,signOffDateTime);
      if(rs.next()){
        hasSigned = true;
      }
      if("1".equalsIgnoreCase(signtype)){
        if(hasSigned){
          signedMsg = SystemEnv.getHtmlLabelName(523888, curUser.getLanguage());
        }
      }else if("2".equalsIgnoreCase(signtype)){
        if(!hasSigned){
          signedMsg = SystemEnv.getHtmlLabelName(501301, curUser.getLanguage());
        }
      }
    }
    return signedMsg;
  }

  /**
   * 在签到签退的时候先根据打卡数据
   * 粗步 得到打卡状态 正常，迟到，早退
   * @return
   */
  private String  getSignStatus(String signType, String onTime, String offTime,
      String signTime) {
    String signStatus = "";
    onTime = onTime + ":00";
    offTime = offTime + ":00";
    if("1".equalsIgnoreCase(signType)){
      if(signTime.compareTo(onTime) > 0){
        signStatus = ButtonStatusEnum.BELATE.getStatusCode();
      }else{
        signStatus = ButtonStatusEnum.NORMAL.getStatusCode();
      }
    }
    if("2".equalsIgnoreCase(signType)){
      if(signTime.compareTo(offTime) < 0){
        signStatus = ButtonStatusEnum.LEAVEERALY.getStatusCode();
      }else{
        signStatus = ButtonStatusEnum.NORMAL.getStatusCode();
      }
    }
    return signStatus;
  }

  @Override
	public BizLogContext getLogContext() {
		return null;
	}

}
