package com.kingdee.eas.hr.project.app;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.dao.IObjectPK;
import com.kingdee.bos.util.BOSUuid;
import com.kingdee.eas.basedata.person.PersonCollection;
import com.kingdee.eas.basedata.person.PersonFactory;
import com.kingdee.eas.basedata.person.PersonInfo;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.framework.CoreBaseCollection;
import com.kingdee.eas.framework.LineResult;
import com.kingdee.eas.framework.Result;
import com.kingdee.eas.hr.base.HRBillStateEnum;
import com.kingdee.eas.hr.project.IWorkHoursConfirm;
import com.kingdee.eas.hr.project.IWorkHoursReport;
import com.kingdee.eas.hr.project.ProjectManagementInfo;
import com.kingdee.eas.hr.project.WorkHoursConfirmFactory;
import com.kingdee.eas.hr.project.WorkHoursConfirmInfo;
import com.kingdee.eas.hr.project.WorkHoursReportEntryInfo;
import com.kingdee.eas.hr.project.WorkHoursReportFactory;
import com.kingdee.eas.hr.project.WorkHoursReportInfo;
import com.kingdee.eas.hr.project.dataSource;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.jdbc.rowset.IRowSet;

public class WorkHoursFacadeControllerBean extends AbstractWorkHoursFacadeControllerBean
{
    private static Logger logger =
        Logger.getLogger("com.kingdee.eas.hr.project.app.WorkHoursFacadeControllerBean");

    /**
     * 生产打卡确认单
     */
    protected void _initWorkHoursConfirm(Context ctx, String number, String star, String end, int day)
    		throws BOSException, EASBizException {
    	IRowSet rs = null;
    	List<String> keyList = new ArrayList<String>();
    	IWorkHoursConfirm  biz = WorkHoursConfirmFactory.getLocalInstance(ctx); 
    	
    	WorkHoursConfirmInfo wInfo = null;
    	SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	List<WorkHoursConfirmInfo> listInfo = null;
    	List<String> listproid = new ArrayList<String>();
    	Map<String,String> mapdate = new HashMap<String,String>();
    	Map<String,String> mapproid = new HashMap<String,String>();
    	//存放打卡数据 map
    	Map<String,List<WorkHoursConfirmInfo>> mapInfo = new HashMap<String,List<WorkHoursConfirmInfo>>();
    	StringBuffer sb = new StringBuffer("/*dialect*/");
    	if(day <= 0) {
    		//默认3天
    		day = 3;
    	}
    	sb = new StringBuffer("/*dialect*/");
    	sb.append("	select  t.fid tfid,t1.fid pid,t1.fnumber,t1.fname_l2,t3.fid proid,t3.fnumber,t3.CFProjectName ,TO_CHAR(t.FPUNCHCARDTIME, 'YYYY-MM-DD') CFCLOCKTIME1 "
    			+ ",TO_CHAR(t.FPUNCHCARDTIME, 'YYYY-MM-DD HH24:MI:SS') CFCLOCKTIME,t.FPUNCHCARDPLACE FPUNCHCARDPLACE,t3en.CFCLOCKLOCATION CFCLOCKLOCATION from T_HR_ATS_PunchCardRecord t ").append(" \n");
    	sb.append("	inner join T_BD_Person t1 on t1.fid = t.FPROPOSERID ").append(" \n");
    	sb.append("	inner join CT_PRO_MemberManagement t2 on t2.CFEmployeeID = t1.fid ").append(" \n");
    	sb.append("	inner join CT_PRO_ProjectManagement t3 on t3.fid = t2.CFProjectManagemenID ").append(" \n");
    	sb.append("	left join CT_PRO_ProjectManagementEntry t3en on t3en.FPARENTID = t3.fid  ").append(" \n");
    	sb.append("	where t3.CFExpectedStartTime <FPUNCHCARDTIME and t3.CFExpectedEndTime >= FPUNCHCARDTIME ").append(" \n");
    	sb.append("	and t.fid not in (select FSOURCEBILLID from CT_PRO_WorkHoursConfirm  where FSOURCEBILLID is not null ) ").append(" \n");
    	//按照时间过滤
    	if(star != null) {
    		sb.append("	and t.FPUNCHCARDTIME  >= TO_CHAR("+star+", 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
    	}else if(end != null) {
    		sb.append("	and t.FPUNCHCARDTIME  <= TO_CHAR("+end+", 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
    	}else {
    		sb.append("	and t.FPUNCHCARDTIME >= sysdate -"+day).append(" \n");
    	}
    	if(number !=null && number.length() > 0) {
    		sb.append("	and t1.fnumber in (").append(number).append(") \n");
    	}
    	sb.append("	order by t1.fid, t.FPUNCHCARDTIME desc ").append(" \n");//排序
    	//获取打卡数据
    	rs = DbUtil.executeQuery(ctx, sb.toString());
    	try {
			while (rs.next()) {
				String pid = rs.getString("pid");
				String tfid = rs.getString("tfid");
				String proid = rs.getString("proid");
				String CFCLOCKLOCATION = rs.getString("CFCLOCKLOCATION"); //项目打卡位置
				String FPUNCHCARDPLACE = rs.getString("FPUNCHCARDPLACE"); //考勤位置打卡
				String CFCLOCKTIME = rs.getString("CFCLOCKTIME"); //年月日时分秒 打卡时间
				String CFCLOCKTIME1 = rs.getString("CFCLOCKTIME1"); //年月日--------当前
				String key = pid+CFCLOCKTIME1;//员工id+年月日为 一个 唯一组合
				//同一天不在多个项目情况下进行标记
				if(!listproid.contains(key) && mapproid.containsKey(key) && mapproid.get(key).equals(proid)) {
					listproid.add(key);
				}
				//去重-年月日时分秒匹配-跳过
				if(mapdate.containsKey(key) && mapproid.get(key).equals(CFCLOCKTIME)) {
					continue;
				}
				if(mapInfo.containsKey(key)) {
					listInfo = mapInfo.get(key);
				}else {
					listInfo = new ArrayList<WorkHoursConfirmInfo>();
					keyList.add(key);
					mapproid.put(key, proid);
					mapdate.put(key, CFCLOCKTIME);
				}
				wInfo = getWConfirmInfo(ctx,pid, proid,CFCLOCKLOCATION,FPUNCHCARDPLACE,simpleDateFormat.parse(CFCLOCKTIME),tfid);
				listInfo.add(wInfo);
				mapInfo.put(key, listInfo);
			}
		} catch (SQLException | ParseException e) {
			e.printStackTrace();
		}
    	//写入打卡数据
    	CoreBaseCollection addSubColl = new CoreBaseCollection();
    	CoreBaseCollection addAudColl = new CoreBaseCollection();
    	//多个项目且不在同一个项目情况下
    	List<String> notList = new ArrayList<String>();
    	if(listproid.size() > 0) {
        	for (int i = 0; i < listproid.size(); i++) {
        		String key = listproid.get(i);
        		listInfo = mapInfo.get(key);
        		String oldprojid = null;
        		boolean isoneprojid = true;
        		for (int j = 0; j < listInfo.size(); j++) {
        			wInfo = listInfo.get(j);
        			if(j == 0) {
        				if(wInfo.getProject().getId() != null) {
        					oldprojid = wInfo.getProject().getId().toString();
        				}else {
        					oldprojid = "0";
        				}
        			}else {
        				//不在同一个项目
            			if(!oldprojid.equals(wInfo.getProject().getId().toString()) || wInfo.getProject().getId() == null) {
            				isoneprojid = false;
            				break;
            			}
        			}
    			}
        		//不在同一个项目
        		if(!isoneprojid) {
        			for (int j = 0; j < listInfo.size(); j++) {
            			wInfo = listInfo.get(j);
            			wInfo.setProject(null); //所属项目
            			wInfo.setBillState(HRBillStateEnum.SAVED);//暂存
            			addSubColl.add(wInfo);
        			}
        			notList.add(key);
        		}
    		}
    	}
    	//剩余数据处理
    	if (keyList.size() > 0){
    		for (int i = 0; i < keyList.size(); i++) {
    			String key = keyList.get(i);
    			if(notList.contains(key)) {
    				continue;
    			}
        		listInfo = mapInfo.get(key);
        		for (int j = 0; j < listInfo.size(); j++) {
        			wInfo = listInfo.get(j);
        			//直接生效
        			if(wInfo.getBillState().compareTo(HRBillStateEnum.AUDITED) == 0) {
        				addAudColl.add(wInfo);
        			}else {
        				//匹配不上的
        				addSubColl.add(wInfo);
        			}
    			}
			}
    	}
    	//提交工作流
    	if(addSubColl.size() > 0) {
    		biz.submit(addSubColl);
    	}
    	if(addAudColl.size() > 0) {
    		//保存处理-审核通过
        	Result re = biz.addnew(addAudColl);
        	LineResult lr = null;
        	if(re != null && re.size() > 0){
        		for (int i = 0; i < re.size(); i++) {
        			lr = re.getLineResult(i);
        			biz.setAudited(BOSUuid.read(lr.getPk().toString())); //-审核通过
    			}
        	}
    	}
    }
    
    /**
     * 解析为工时确认单
     * @param pid
     * @param proid
     * @param p1
     * @param p2
     * @param clockTime
     * @return
     */
    private WorkHoursConfirmInfo getWConfirmInfo(Context ctx,String pid,String proid,String p1,String p2,Date clockTime,String FSOURCEBILLID) {
    	WorkHoursConfirmInfo wInfo = new WorkHoursConfirmInfo();
    	PersonInfo pinfo = new PersonInfo();pinfo.setId(BOSUuid.read(pid)); //人员
    	
    	PersonCollection personCollection = null;
		try {
			personCollection = PersonFactory.getLocalInstance(ctx).getPersonCollection(" select * where id = '"+pid+"'");
		} catch (BOSException e) {
			e.printStackTrace();
		}
		if(personCollection != null && personCollection.size()>0){
			pinfo = personCollection.get(0);
		}
		
		ProjectManagementInfo proinfo = new ProjectManagementInfo();proinfo.setId(BOSUuid.read(proid)); //所属项目
		wInfo.setEmployee(pinfo);
		wInfo.setProject(proinfo); //所属项目
		wInfo.setClockDate(clockTime); //打卡日期
		wInfo.setSourceBillId(FSOURCEBILLID);//来源id
		wInfo.setHrOrgUnit(pinfo.getHrOrgUnit());
		wInfo.setCU(pinfo.getCU());
		Timestamp t = new Timestamp(clockTime.getTime());
		wInfo.setClockTime(t); //打卡--------------------------------------------------------------------------------------------------------------
		//打卡位置 clockLocation 
		if(p1.equals(p2)) {
			wInfo.setClockLocation(p2);
			wInfo.setBillState(HRBillStateEnum.AUDITED);//审核通过
		}else {
			wInfo.setProject(null); //所属项目
			wInfo.setBillState(HRBillStateEnum.SAVED);//暂存
		}
		return wInfo;
    }
    
    /**
     * 工时计算
     */
    protected void _updateWorkHoursReport(Context ctx, String number, String star, String end, int day,String type)
    		throws BOSException, EASBizException {
    	//获取工时确认单生成工时单
    	String CFCLOCKTIME = null; //年月日-时分秒
		String CFCLOCKDATE = null; //年月日
		String CFPROJECTID = null; //项目id
		String CFEMPLOYEEID = null; //人员id
		String CFCLOCKLOCATION = null; //位置
		String fid = null; //fid
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	SimpleDateFormat sdfs = new SimpleDateFormat("HH:mm:ss");
    	IWorkHoursReport biz = WorkHoursReportFactory.getLocalInstance(ctx);
    	CoreBaseCollection coll = new CoreBaseCollection();
    	WorkHoursReportInfo info = null;
    	List<String> listDate = new ArrayList<String>(); //一天天的判断
    	Map<String,List<Map<String,String>>> dateMap = null;
    	List<Map<String,String>> listMap = null;
    	Map<String,List<String>> mapListPersonid = new HashMap<String,List<String>>(); //每天有多少人
    	List<String> personidList = null;
    	Map<String,String> map = null;
    	Map<String,Map<String,List<Map<String,String>>>> mapRs = new HashMap<String,Map<String,List<Map<String,String>>>>();
    	if(day <= 0) {
    		//默认3天
    		day = 3;
    	}
    	StringBuffer sb = new StringBuffer("/*dialect*/");
    	sb.append("	select fid fid,CFPROJECTID CFPROJECTID,CFEMPLOYEEID CFEMPLOYEEID"
    			+ " ,TO_CHAR(CFCLOCKDATE, 'YYYY-MM-DD') CFCLOCKDATE"
    			+ " ,TO_CHAR(CFCLOCKTIME, 'YYYY-MM-DD HH24:MI:SS') CFCLOCKTIME "
    			+ " FROM CT_PRO_WorkHoursConfirm where FBILLSTATE ='3' "
    			+ " and CFPROJECTID is not null ").append(" \n");
    	//按照时间过滤
    	if(star != null) {
    		sb.append("	and CFCLOCKDATE  >= TO_CHAR("+star+", 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
    	}else if(end != null) {
    		sb.append("	and CFCLOCKDATE  <= TO_CHAR("+end+", 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
    	}else {
    		sb.append("	and CFCLOCKDATE >= sysdate -"+day).append(" \n");
    	}
    	if(number !=null && number.length() > 0) {
    		sb.append("	and CFEMPLOYEEID in (select fid from (").append(number).append(")) \n");
    	}
    	sb.append("	 order by  CFEMPLOYEEID,CFCLOCKTIME asc").append(" \n");//排序
    	//获取打卡数据-审核通过的数据
    	IRowSet rs = DbUtil.executeQuery(ctx, sb.toString());
    	System.out.println("sb："+sb);
		try {
			while (rs.next()) {
				CFCLOCKTIME = rs.getString("CFCLOCKTIME"); //年月日-时分秒
				CFCLOCKDATE = rs.getString("CFCLOCKDATE"); //年月日
				CFPROJECTID = rs.getString("CFPROJECTID"); //项目id
				CFEMPLOYEEID = rs.getString("CFEMPLOYEEID"); //人员id
				CFCLOCKLOCATION = "";//rs.getString("CFCLOCKLOCATION"); //位置
				fid = rs.getString("fid"); //fid
				map = new HashMap<String,String>();
				map.put("CFCLOCKTIME", CFCLOCKTIME);
				map.put("CFCLOCKDATE", CFCLOCKDATE);
				map.put("CFPROJECTID", CFPROJECTID);
				map.put("CFEMPLOYEEID", CFEMPLOYEEID);
				map.put("fid", fid);
				if(!listDate.contains(CFCLOCKDATE)){
					listDate.add(CFCLOCKDATE);
					dateMap = new HashMap<String,List<Map<String,String>>>();
					personidList = new ArrayList<String>();
				}else {
					dateMap = mapRs.get(CFCLOCKDATE);
					personidList = mapListPersonid.get(CFCLOCKDATE);
				}
				//重复人员
				if(!personidList.contains(CFEMPLOYEEID)) {
					personidList.add(CFEMPLOYEEID);
					listMap = new ArrayList<Map<String,String>>();
				}else {
					listMap = dateMap.get(CFEMPLOYEEID);
				}
				listMap.add(map);
				
				dateMap.put(CFEMPLOYEEID,listMap);
				mapListPersonid.put(CFCLOCKDATE, personidList); 
				mapRs.put(CFCLOCKDATE, dateMap);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		List<String> delist = new ArrayList<String>();
    	//一天一天的处理
		for (int i = 0; i < listDate.size(); i++) {
			CFCLOCKDATE = listDate.get(i);
			dateMap = mapRs.get(CFCLOCKDATE);
			personidList = mapListPersonid.get(CFCLOCKDATE);
			for (int j = 0; j < personidList.size(); j++) {
				CFEMPLOYEEID = personidList.get(j);//人员id
				listMap = dateMap.get(CFEMPLOYEEID); //这个人有多少打卡数据
				String oldCFPROJECTID = null; //旧的项目
				String oldCFCLOCKTIME = null;   //旧的打卡时间
				String oldfid = null;   //旧的fid
				String deleteWhere = " CFEMPLOYEEID='"+CFEMPLOYEEID+"' and to_char(CFDATA,'YYYY-MM-DD') = '"+CFCLOCKDATE+"'";
				for (int j2 = 0; j2 < listMap.size(); j2++) {
					map = listMap.get(j2);
					CFCLOCKTIME = map.get("CFCLOCKTIME"); //年月日-时分秒
					CFPROJECTID = map.get("CFPROJECTID"); //项目id
					CFEMPLOYEEID = map.get("CFEMPLOYEEID"); //人员id
					CFCLOCKLOCATION = map.get("CFEMPLOYEEID"); //位置
					fid = map.get("fid"); //fid
					//第一次记录最早的
					if(j2 == 0){
						oldCFPROJECTID = CFPROJECTID;
						oldCFCLOCKTIME = CFCLOCKTIME;
						oldfid = fid;
					}
					//跟上一次的不一致情况下
					if(!oldCFPROJECTID.equals(CFPROJECTID)) {
						map = listMap.get(j2-1);
						CFCLOCKTIME = map.get("CFCLOCKTIME"); //年月日-时分秒
						CFPROJECTID = map.get("CFPROJECTID"); //项目id
						CFEMPLOYEEID = map.get("CFEMPLOYEEID"); //人员id
						CFCLOCKLOCATION = map.get("CFEMPLOYEEID"); //位置
						fid = map.get("fid"); //fid
						//取上一次的数据与第一次数据进行比较计算
						//计算两者时间差几个小时
						try {
							Date oldDate = sdf.parse(oldCFCLOCKTIME);
							Date date = sdf.parse(CFCLOCKTIME);
					        long diffInMillies = date.getTime() - oldDate.getTime();
					        // 将毫秒数转换为小时
					        long diffInHours = diffInMillies / (60 * 60 * 1000);
					        BigDecimal hours = new BigDecimal(diffInHours);
					        //组装数据
					        info = initInfo(ctx,CFEMPLOYEEID, oldCFPROJECTID, date, sdf.format(sdf.parse(CFCLOCKTIME)), null, hours,oldfid+","+fid);
					        if(!delist.contains(deleteWhere)) {
					        	delist.add(deleteWhere);
					        }
					        coll.add(info);
						} catch (ParseException ee) {
							ee.printStackTrace();
						}
						//当前重新开始
						map = listMap.get(j2);
						CFCLOCKTIME = map.get("CFCLOCKTIME"); //年月日-时分秒
						CFPROJECTID = map.get("CFPROJECTID"); //项目id
						CFEMPLOYEEID = map.get("CFEMPLOYEEID"); //人员id
						CFCLOCKLOCATION = map.get("CFEMPLOYEEID"); //位置
						fid = map.get("fid"); //fid
						oldCFPROJECTID = CFPROJECTID;
						oldCFCLOCKTIME = CFCLOCKTIME;
						oldfid = fid;
					}
					
					//最后一次记录
					if(j2 == listMap.size()-1){
						if(oldCFPROJECTID.equals(CFPROJECTID) && !oldCFCLOCKTIME.equals(CFCLOCKTIME)) { //项目相同时间相同情况下
							try {
								Date oldDate = sdf.parse(oldCFCLOCKTIME);
								Date date = sdf.parse(CFCLOCKTIME);
						        long diffInMillies = date.getTime() - oldDate.getTime();
						        // 将毫秒数转换为小时
						        long diffInHours = diffInMillies / (60 * 60 * 1000);
						        BigDecimal hours = new BigDecimal(diffInHours);
						        //组装数据
						        info = initInfo(ctx,CFEMPLOYEEID, oldCFPROJECTID, date, sdf.format(sdf.parse(CFCLOCKTIME)), null, hours,oldfid+","+fid);
						        if(!delist.contains(deleteWhere)) {
						        	delist.add(deleteWhere);
						        }
						        coll.add(info);
							} catch (ParseException ee) {
								ee.printStackTrace();
							}
						}
					}
				}
			}
		}
		//删除情况下
		if(type.equals("update") && delist.size() > 0) {
			//删除当天
			for (int i = 0; i < delist.size(); i++) {
				DbUtil.execute(ctx, " delete from CT_PRO_WorkHoursReport where CFDATASOURCE = 'workHoursCal' and  FBILLSTATE = '3' "
						+ "and CFFILLINGSTARTDATE = CFFILLINGENDDATE and fid in(select FParentID from CT_PRO_WorkHoursReportentry where "+delist.get(i)+") ");
				DbUtil.execute(ctx, " delete from CT_PRO_WorkHoursReportentry where "+delist.get(i)+" ");
			}
    	}
		//保存处理-审核通过
		System.out.println("coll："+coll.toString());
    	if(coll.size() > 0) {
    		for (int i = 0; i < coll.size(); i++) {
    			info = (WorkHoursReportInfo) coll.get(i);
    			IObjectPK pk = biz.addnew(info);
    			biz.setAudited(BOSUuid.read(pk.toString())); //-审核通过
			}
    	}
    }
    
    /**
     * 组装工时单据
     * @param pid
     * @param proid
     * @param data
     * @param ClockTime
     * @param ClockLocation
     * @param hours
     * @return
     */
    private WorkHoursReportInfo initInfo(Context ctx,String pid,String proid,Date data,String ClockTime
    		,String ClockLocation,BigDecimal hours,String ids) {
    	WorkHoursReportInfo info = new WorkHoursReportInfo();
    	WorkHoursReportEntryInfo einfo = new WorkHoursReportEntryInfo();
    	PersonInfo pinfo = new PersonInfo();pinfo.setId(BOSUuid.read(pid)); //人员
    	PersonCollection personCollection = null;
		try {
			personCollection = PersonFactory.getLocalInstance(ctx).getPersonCollection(" select * where id = '"+pid+"'");
		} catch (BOSException e) {
			e.printStackTrace();
		}
		if(personCollection != null && personCollection.size()>0){
			pinfo = personCollection.get(0);
		}
		ProjectManagementInfo proinfo = new ProjectManagementInfo();
		proinfo.setId(BOSUuid.read(proid)); //所属项目
		info.setHrOrgUnit(pinfo.getHrOrgUnit());
		info.setCU(pinfo.getCU());
		info.setDataSource(dataSource.workHoursCal);
    	info.setAffiliatedProject(proinfo);
    	info.setBillState(HRBillStateEnum.AUDITED); //审核通过
    	info.setFillingStartDate(data); //默认当天
    	info.setFillingEndDate(data); //默认当天
    	info.setSourceBillId(ids);
    	einfo.setEmployee(pinfo);
//    	einfo.setClockLocation("工时计算");
    	einfo.setClockTime(ClockTime); //打卡时间
    	einfo.setData(data); //日期
    	einfo.setWorkingHours(hours); //工时
    	info.getEntrys().add(einfo);
    	return info;
    }
    
}