package com.yonyou.hrcloud.attend.web;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.yonyou.hrcloud.adder.context.AppContext;
import com.yonyou.hrcloud.adder.exception.AdderBusinessException;
import com.yonyou.hrcloud.adder.exception.AdderRuntimeException;
import com.yonyou.hrcloud.adder.model.param.PagerRequest;
import com.yonyou.hrcloud.adder.model.param.Sorter;
import com.yonyou.hrcloud.adder.model.query.Condition;
import com.yonyou.hrcloud.adder.model.query.Operator;
import com.yonyou.hrcloud.adder.service.IGenericService;
import com.yonyou.hrcloud.attend.dao.IAttendStaffDao;
import com.yonyou.hrcloud.attend.helper.ValidateParams;
import com.yonyou.hrcloud.attend.model.AttendStaff;
import com.yonyou.hrcloud.attend.service.IAttendStaffListenterService;
import com.yonyou.hrcloud.attend.service.IAttendStaffService;
import com.yonyou.hrcloud.berry.model.MessageResult;
import com.yonyou.hrcloud.commons.staff.model.CommonSimpleStaff;
import com.yonyou.hrcloud.tcommon.helper.AttendServiceCodeConstant;
import com.yonyou.hrcloud.tcommon.helper.staffAndOrg.OrgCommonHepler;
import com.yonyou.hrcloud.tcommon.helper.staffAndOrg.SimpleStaffCommonHepler;
import com.yonyou.hrcloud.tcommon.helper.staffAndOrg.SqlQueryHpler;
import com.yonyou.hrcloud.tcommon.service.IOrgPowerService;
import com.yonyou.hrcloud.tcommon.utils.AttendCommonUtils;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import lombok.extern.slf4j.Slf4j;

/**
 * 考勤档案
 * Created by Administrator on 2018/5/14.
 */
@Api(value = "考勤档案",description = "考勤档案",tags = {"考勤档案"})
@RestController
@RequestMapping("/attendstaff")
@Slf4j
public class AttendStaffController {

	@Autowired
	IAttendStaffDao dao;
	@Autowired
	private IAttendStaffService attendStaffService;
	@Autowired
	private IAttendStaffListenterService attendStaffListenterService;
	@Autowired
	private SimpleStaffCommonHepler simpleStaffCommonHepler;
	@Autowired
	private OrgCommonHepler orgCommonHepler;
	@Autowired
	private IOrgPowerService orgPowerService;
	@Autowired
	private IGenericService genericService;
	public static final int PAGE_SIZE = 500;



	/**
	 * 新增假勤档案
	 *
	 * @param attendStaff
	 * @return
	 */
	@ApiOperation(value = "新增假勤档案")
	@ApiResponse(code = 400, message = "操作失败")
	@RequestMapping(value = "/insert", method = RequestMethod.GET)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "staffName", value = "员工姓名", paramType = "query", dataType = "String", required = true),
			@ApiImplicitParam(name = "attendType", value = "考勤方式", paramType = "query", dataType = "String", required = true),
			@ApiImplicitParam(name = "begindate", value = "开始日期", paramType = "query", required = true)
	})
	public Object insert(AttendStaff attendStaff) {
		ValidateParams.validateInsertAttendStaff(attendStaff);
		MessageResult result = new MessageResult("操作成功！", null, "attend.common.i18n1");
		//获取当前用户有权限的组织/部门id集合
		List<String> orgIdList = orgCommonHepler.getPowerDeptOnlys(AttendServiceCodeConstant.ATTEND_STAFF);
		if (CollectionUtils.isNotEmpty(orgIdList)) {
			if (orgIdList.contains(attendStaff.getOrgId()) || orgIdList.contains(attendStaff.getDeptId())) {
				attendStaffService.insert(attendStaff);
			} else {
				throw new AdderBusinessException("新增失败，您没有此人所对应组织的权限！", "attend.doc.i18n58");
			}
		}
		return result;
	}

	/**
	 * 编辑假勤档案
	 *
	 * @param attendStaff
	 * @return
	 */
	@ApiOperation(value = "更新假勤档案")
	@ApiResponse(code = 400, message = "操作失败")
	@RequestMapping(value = "/update", method = RequestMethod.POST)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "假勤档案id", paramType = "query", dataType = "String")
	})
	public Object update(AttendStaff attendStaff) {
		ValidateParams.validateUpdateAttendStaff(attendStaff);
		attendStaffService.update(attendStaff);
		return new MessageResult("操作成功！", null, "attend.common.i18n1");
	}

	/**
	 * 批量修改假勤档案
	 *
	 * @param begindate  开始时间
	 * @param enddate    结束时间
	 * @param attendType 考勤方式 1正常考勤,2不考勤,3免签卡
	 * @param cardCode   员工卡号
	 * @param ids
	 * @return
	 */
	@ApiOperation(value = "批量修改假勤档案")
	@ApiResponse(code = 400, message = "操作失败")
	@RequestMapping(value = "/updateBatch", method = RequestMethod.POST)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "begindate", value = "开始时间", dataType = "Date", required = true),
			@ApiImplicitParam(name = "enddate", value = "结束时间", dataType = "Date", required = true),
			@ApiImplicitParam(name = "attendType", value = "考勤方式 1正常考勤,2不考勤,3免签卡", dataType = "String", required = true),
			@ApiImplicitParam(name = "cardCode", value = "员工卡号", dataType = "String", required = true),
			@ApiImplicitParam(name = "ids", value = "假勤档案id", dataType = "String", required = true)
	})
	public Object updateBatch(Date begindate, Date enddate, String attendType, String cardCode, String[] ids) {
		if (begindate != null && enddate != null && begindate.after(enddate)) {
			throw new AdderBusinessException("开始日期不能晚于结束日期!", "attend.doc.i18n59");
		}
		attendStaffService.updateBatch(begindate, enddate, attendType, cardCode, ids);
		return new MessageResult("操作成功！", null, "attend.common.i18n1");
	}

	/**
	 * 根据人员id获取人员考勤档案信息
	 *
	 * @param id
	 * @return
	 */
	@ApiOperation(value = "根据人员id获取人员考勤档案信息")
	@ApiResponse(code = 400, message = "操作失败")
	@RequestMapping(value = "/getStaffInfo", method = RequestMethod.GET)
	@ApiImplicitParam(name = "id", value = "人员id", paramType = "query", dataType = "String", required = true)
	public Object getStaffInfo(String id) {
		CommonSimpleStaff staff = null;
		try {
			//人员查询优化
			staff = simpleStaffCommonHepler.querySimpleStaffById(id);
		} catch (Exception e) {
			throw new AdderRuntimeException(e.getMessage(), e);
		}
		if (staff != null) {
			AttendStaff attendStaff = new AttendStaff();
			attendStaff.setStaffCode(staff.getCode());
			attendStaff.setStaffName(staff.getName());
			attendStaff.setDeptName(staff.getDeptName());
			//人员类别名称
			attendStaff.setPsnclName(staff.getPsnclName());
			attendStaff.setPsnclId(staff.getPsnclId());
			attendStaff.setDeptId(staff.getDeptId());
			attendStaff.setEmployedDate(staff.getBeginDate());
			MessageResult result = new MessageResult("操作成功！", null, "attend.common.i18n1");
			result.setData(attendStaff);
			return result;
		} else {
			throw new AdderBusinessException("获取人员信息失败！", "attend.doc.i18n25");
		}
	}

	/**
	 * 列表分页展示假勤档案
	 *
	 * @return
	 */
	@ApiOperation(value = "列表分页展示假勤档案")
	@ApiResponse(code = 400, message = "操作失败")
	@RequestMapping(value = "/query", method = RequestMethod.GET)
	@ApiImplicitParams(
			{@ApiImplicitParam(name = "pageNum", value = "页索引，从1开始", paramType = "query", dataType = "Integer", required = true),
					@ApiImplicitParam(name = "pageSize", value = "页大小", paramType = "query", dataType = "Integer", required = true)}
	)
    public Object query(Pageable pageable) {
		MessageResult result= new MessageResult("操作成功！", null, "attend.common.i18n1");
        //默认每页10条数据
        if(null == pageable) {
            pageable = new PagerRequest(0, 10);
        }
        Condition cond = new Condition();
        cond.addExpression("islast", 1, Operator.EQUAL);
        Sorter sorter = new Sorter(Sort.Direction.DESC, "begindate");
        Page<AttendStaff> dataPages = attendStaffService.queryByConditon4WebAll(cond, pageable, sorter);
        Map<String, Object> data = new HashMap<>();
        data.put("attendstaffs", dataPages);
        result.setData(data);
        return result;
    }
    
    /**按照条件查询假期档案
     * @param attendStaff 假期档案查询高级搜索条件,此接口会用到
     *                    staffName(员工姓名)
     *                    orgId(组织id)
     *                    attendType(考勤方式,0全部,1正常考勤,2不考勤,3免签卡)
     *                    psncl_id(人员类别id)
     * @param keyWord 姓名、员工编号关键字
     * @param begindatehead 开始时间左区间
     * @param begindatetail 开始时间右区间
     * @param enddatehead 结束时间左区间
     * @param enddatetail 结束时间右区间
     * @param status 状态(0全部1结束2未结束)
     * @return
     */
	@ApiOperation(value = "按照条件查询假期档案")
	@ApiResponse(code = 400, message = "操作失败")
	@RequestMapping(value = "/queryByCondition", method = RequestMethod.GET)
	public Object queryByCondition(Pageable pageable, String keyWord, Date begindatehead, Date begindatetail, String jobIds,
								   Date enddatehead, Date enddatetail, Integer status, boolean isIncludeSub, String attendType, AttendStaff attendStaff) {
		//默认每页10条数据
		if (null == pageable) {
			pageable = new PagerRequest(0, 10);
		}
		Condition condStaff = SqlQueryHpler.getAttendStaffCon(null,keyWord,attendStaff.getPsnclId(),jobIds, attendType,
				                                              status,begindatehead,begindatetail,enddatehead,enddatetail);
		MessageResult result = new MessageResult("操作成功！", null, "attend.common.i18n1");
		Map<String, Object> data = new HashMap<>();
		data.put("attendstaffs", attendStaffService.queryPagesByCondition(pageable,condStaff,isIncludeSub,attendStaff));
		result.setData(data);
		return result;
	}

	/**
	 * 考勤档案监听服务
	 *
	 * @param params
	 * @return
	 */
	@ApiOperation(value = "考勤档案监听服务")
	@ApiResponse(code = 400, message = "操作失败")
	@SuppressWarnings("rawtypes")
	@RequestMapping(value = "/internal/staffListener", method = RequestMethod.POST)
	public Object staffListener(@RequestBody HashMap params) {
		try { // params = {isCustomDef=false, opType=2, tenantId=gtbjopdx, id=7941aa2a38c24645be9a8fec26cdfba4, userId=4a143f32-aea4-4d3f-be23-7d9bba6d0190, metaDefinedName=staff_job}
			AppContext.getContext().setScope(params.get("tenantId").toString());
			AppContext.getContext().setUserId(params.get("userId").toString());


			log.error("diwork监听考勤方案begin");
			log.error("diwork监听考勤方案参数 params = " + JSON.toJSONString(params));
//			if(LockHelper.lock("staffListener"+params.get("staff_id").toString())){
			//opType : 1 新增  2 修改  3 删除 ;
			if ("1".equals(params.get("opType").toString())) {
				log.error("监听新增考勤方案begin");
				//元数据默认名称: staff -基本信息  staff_orgrel -组织关系   staff_job -任职  staff_part -兼职
				if ("staff".equals(params.get("metaDefinedName"))) {

				} else if ("staff_orgrel".equals(params.get("metaDefinedName"))) {

				} else if ("staff_job".equals(params.get("metaDefinedName"))) {
					String tenantId = params.get("tenantId").toString();
					//String userId = params.get("userId").toString();
					//获取任职记录id
					String staffJob_id = params.get("id").toString();
					attendStaffService.addAttendStaff(tenantId, staffJob_id);
				} else if ("staff_part".equals(params.get("metaDefinedName"))) {

				}
				log.error("监听新增考勤方案end");
			} else if ("2".equals(params.get("opType").toString())) {//opType : 1 新增  2 修改  3 删除  4启用  5停用;
				log.error("监听修改考勤方案begin");
				if ("staff".equals(params.get("metaDefinedName"))) {

				} else if ("staff_orgrel".equals(params.get("metaDefinedName"))) {
					//no
				} else if ("staff_job".equals(params.get("metaDefinedName"))) {
					String tenantId = params.get("tenantId").toString();
					//String userId = params.get("userId").toString();
					//获取任职记录id
					String staffJob_id = params.get("id").toString();
					attendStaffService.updateAttendStaff(tenantId, staffJob_id);
				} else if ("staff_part".equals(params.get("metaDefinedName"))) {
					//no
				}
				log.error("监听修改考勤方案end");
			} else if ("3".equals(params.get("opType").toString())) {//opType : 1 新增  2 修改  3 删除  4启用  5停用;
                 log.error("监听删除考勤方案begin");
				 if("staff".equals(params.get("metaDefinedName"))){
				 	String tenantId = params.get("tenantId").toString();
					//获取任职记录id
					String staff_id = params.get("id").toString();
					attendStaffService.deleteAttendStaff(tenantId, staff_id);
				 }
				 log.error("监听删除考勤方案end");
			} else if ("4".equals(params.get("opType").toString())) {//opType : 1 新增  2 修改  3 删除  4启用  5停用;
				log.error("监听启用考勤方案begin");
				if ("staff".equals(params.get("metaDefinedName"))) {
					String tenantId = params.get("tenantId").toString();
					//String userId = params.get("userId").toString();
					//获取任职记录id
					String staff_id = params.get("id").toString();
					attendStaffService.enableAttendStaff(tenantId, staff_id, params.get("opType").toString());
				}
				log.error("监听启用考勤方案end");
			} else if ("5".equals(params.get("opType").toString())) {//opType : 1 新增  2 修改  3 删除  4启用  5停用;
				log.error("监听停用考勤方案begin");
				if ("staff".equals(params.get("metaDefinedName"))) {
					String tenantId = params.get("tenantId").toString();
					//String userId = params.get("userId").toString();
					//获取任职记录id
					String staff_id = params.get("id").toString();
					attendStaffService.enableAttendStaff(tenantId, staff_id, params.get("opType").toString());
				}
				log.error("监听停用考勤方案end");
			}
//			}
			log.error("diwork监听考勤方案end");
		} catch (Exception e) {
			log.error("考勤档案监听服务报错信息:" + e.getMessage(), e);
			throw new AdderBusinessException("处理考勤档案同步错误", e, null);
		} finally {
//			LockHelper.unlock("staffListener"+params.get("staff_id").toString());
		}
		return AttendCommonUtils.successResult();
	}

	/**
	 * 考勤档案同步操作服务
	 *
	 * @return
	 */
	@ApiOperation(value = "考勤档案同步操作服务")
	@ApiResponse(code = 400, message = "操作失败")
	@RequestMapping(value = "/syncAttendStaffInfo", method = RequestMethod.GET)
	public Object syncAttendStaffInfo() {
		long star1=System.currentTimeMillis();
		String bufStr=attendStaffListenterService.syncAttendStaffInfo();
		long star2=System.currentTimeMillis();
		System.out.println("....查询人员共计用时.....: "+(star2-star1));
		if (StringUtils.isNoneBlank(bufStr)) {
			return new MessageResult("{0}的人员信息有异常，有多条启用状态的数据，不对其考勤档案进行更新操作。", null, "attend.doc.i18n88", bufStr.toString());//{0}:的人员信息有异常，有多条启用状态的数据，不对其考勤档案进行更新操作。
		} else {
			return new MessageResult("同步成功!", null, "attend.doc.i18n89");
		}
	}
}
