package com.jpsoft.shinestar.modules.business.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.annotation.Resource;

import com.jpsoft.shinestar.modules.base.dao.*;
import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
import org.joda.time.DateTime;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.jpsoft.shinestar.modules.business.dao.MeetingPersonRecodeDAO;
import com.jpsoft.shinestar.modules.business.entity.MeetingPersonRecode;
import com.jpsoft.shinestar.modules.business.service.MeetingPersonRecodeService;
import com.github.pagehelper.Page;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.github.pagehelper.PageHelper;

@Slf4j
@Transactional
@Component(value="meetingPersonRecodeService")
public class MeetingPersonRecodeServiceImpl implements MeetingPersonRecodeService {
	@Resource(name="meetingPersonRecodeDAO")
	private MeetingPersonRecodeDAO meetingPersonRecodeDAO;

	@Resource(name="meetingAddressDAO")
	private MeetingAddressDAO meetingAddressDAO;

	@Resource(name="addressDeviceDAO")
	private AddressDeviceDAO addressDeviceDAO;

	@Resource(name="deviceInfoDAO")
	private DeviceInfoDAO deviceInfoDAO;

	@Resource(name="meetingTimeDAO")
	private MeetingTimeDAO meetingTimeDAO;

	@Resource(name="meetingPersonDAO")
	private MeetingPersonDAO meetingPersonDAO;

	@Resource(name="meetingInfoDAO")
	private MeetingInfoDAO meetingInfoDAO;

	@Override
	public MeetingPersonRecode get(String id) {
		// TODO Auto-generated method stub
		return meetingPersonRecodeDAO.get(id);
	}

	@Override
	public int insert(MeetingPersonRecode model) {
		// TODO Auto-generated method stub
		//model.setId(UUID.randomUUID().toString());
		
		return meetingPersonRecodeDAO.insert(model);
	}

	@Override
	public int update(MeetingPersonRecode model) {
		// TODO Auto-generated method stub
		return meetingPersonRecodeDAO.update(model);		
	}

	@Override
	public int delete(String id) {
		// TODO Auto-generated method stub
		return meetingPersonRecodeDAO.delete(id);
	}

	@Override
	public boolean exist(String id) {
		// TODO Auto-generated method stub
		int count = meetingPersonRecodeDAO.exist(id);
		
		return count > 0 ? true : false;
	}
	
	@Override
	public List<MeetingPersonRecode> list() {
		// TODO Auto-generated method stub
		return meetingPersonRecodeDAO.list();
	}

	@Override
	public boolean punchIn(String deviceNo, Long personId, Date recordTime) throws ParseException {
		boolean result = false;

		DeviceInfo deviceInfo = deviceInfoDAO.findByDeviceNo(deviceNo);

		AddressDevice addressDevice = addressDeviceDAO.findByDeviceId(deviceInfo.getId());

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		if(addressDevice!=null){
			String addressId = addressDevice.getAddressId();

			List<MeetingAddress> list = meetingAddressDAO.findByAddressId(addressId);

			for (MeetingAddress meetingAddress:list) {
				List<MeetingTime> meetingTimeList = meetingTimeDAO.findByMeetingIdAndStatus(meetingAddress.getMeetingId(),"1,2");

				for (MeetingTime meetingTime:meetingTimeList) {
					Date meetingDate = meetingTime.getMeetingDate();
					String meetingDateStr = sdf.format(meetingDate);

					String startTimeStr = meetingTime.getStartSignInTime();
                    String meetingTimeStr =  meetingTime.getMeetingTime();

					if(StringUtils.isNotEmpty(startTimeStr)) {
						Boolean flag = isInSignInTime(meetingTime.getMeetingId(),personId,"0",startTimeStr,meetingDateStr,recordTime);
						//如果在签到时间范围内
						if(flag){
							MeetingPerson meetingPerson = meetingPersonDAO.findByMeetingIdAndPersonId(meetingTime.getMeetingId(),personId);

							if(meetingPerson !=null){
								if(meetingPerson.getSignTime()==null){
									meetingPerson.setSignTime(recordTime);
								}
								else if(recordTime.before(meetingPerson.getSignTime())){
									meetingPerson.setSignTime(recordTime);
								}

								meetingPerson.setUpdateTime(new Date());
								meetingPerson.setSignType("0");
								meetingPersonDAO.update(meetingPerson);

								MeetingPersonRecode meetingPersonRecode = new MeetingPersonRecode();
								meetingPersonRecode.setId(UUID.randomUUID().toString());
								meetingPersonRecode.setMeetingInfoId(meetingTime.getMeetingId());
								meetingPersonRecode.setCreateTime(new Date());
								meetingPersonRecode.setDelFlag(false);
								meetingPersonRecode.setPersonId(personId);
								meetingPersonRecode.setSignTime(recordTime);
								meetingPersonRecode.setSignType("0");
								meetingPersonRecodeDAO.insert(meetingPersonRecode);
								result = true;
								break;
							}
						}
					}

					//会议中打卡
                    if(StringUtils.isNotEmpty(meetingTimeStr)) {
                        Boolean flag = isInSignInTime(meetingTime.getMeetingId(),personId,"2",meetingTimeStr,meetingDateStr,recordTime);
                        //如果在会议中时间范围内
                        if(flag){
                            MeetingPerson meetingPerson = meetingPersonDAO.findByMeetingIdAndPersonId(meetingTime.getMeetingId(),personId);

                            if(meetingPerson !=null){
								if(meetingPerson.getSignTime()==null){
									meetingPerson.setSignTime(recordTime);
									meetingPerson.setUpdateTime(new Date());
									meetingPerson.setSignType("2");

									meetingPersonDAO.update(meetingPerson);

									MeetingPersonRecode meetingPersonRecode = new MeetingPersonRecode();
									meetingPersonRecode.setId(UUID.randomUUID().toString());
									meetingPersonRecode.setMeetingInfoId(meetingTime.getMeetingId());
									meetingPersonRecode.setCreateTime(new Date());
									meetingPersonRecode.setDelFlag(false);
									meetingPersonRecode.setPersonId(personId);
									meetingPersonRecode.setSignTime(recordTime);
									meetingPersonRecode.setSignType("2");
									meetingPersonRecodeDAO.insert(meetingPersonRecode);
									result = true;
									break;
								}
                            }
                        }
                    }

					String endTimeStr = meetingTime.getEndSignInTime();

					if(StringUtils.isNotEmpty(endTimeStr)) {
						Boolean flag = isInSignInTime(meetingTime.getMeetingId(),personId,"1",endTimeStr,meetingDateStr,recordTime);
						//如果在签到时间范围内
						if(flag){
							MeetingPerson meetingPerson = meetingPersonDAO.findByMeetingIdAndPersonId(meetingTime.getMeetingId(),personId);

							boolean isSignPerson = false;

							if(meetingPerson !=null){
								isSignPerson = true;
							}

							if(isSignPerson) {
								MeetingPersonRecode meetingPersonRecode = new MeetingPersonRecode();
								meetingPersonRecode.setId(UUID.randomUUID().toString());
								meetingPersonRecode.setMeetingInfoId(meetingTime.getMeetingId());
								meetingPersonRecode.setCreateTime(new Date());
								meetingPersonRecode.setDelFlag(false);
								meetingPersonRecode.setPersonId(personId);
								meetingPersonRecode.setSignTime(recordTime);
								meetingPersonRecode.setSignType("1");
								meetingPersonRecodeDAO.insert(meetingPersonRecode);
								result = true;
								break;
							}
						}
					}
				}
			}
		}

		return result;
	}

	private boolean isInSignInTime(String meetingId,Long personId,String signType,String startTimeStr,String meetingDateStr,Date recordTime) throws ParseException {
		boolean result = false;

		SimpleDateFormat sdfLong = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		if(StringUtils.isNotEmpty(startTimeStr)) {
			JSONObject jsonObject = JSONObject.fromObject(startTimeStr);
			String start = jsonObject.get("start").toString();
			String end = jsonObject.get("end").toString();

			String startSignInTimeStr = meetingDateStr + " " + start + ":00";
			String endSignInTimeStr = meetingDateStr + " " + end + ":00";

			Date startSignInTime = sdfLong.parse(startSignInTimeStr);
			Date endSignInTime = sdfLong.parse(endSignInTimeStr);

			//在签到范围内
			if(recordTime.compareTo(startSignInTime) >= 0 && recordTime.compareTo(endSignInTime) <= 0){
				MeetingPersonRecode meetingPersonRecode = meetingPersonRecodeDAO.findByMeetingIdAndSignTime(meetingId,personId,startSignInTime,endSignInTime,signType);
				//该会议该时间段没有签到记录
				if(meetingPersonRecode == null) {
					result = true;
				}
			}
		}
		return result;
	}
		
	@Override
	public Page<MeetingPersonRecode> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize,boolean count,List<Sort> sortList) {
        Page<MeetingPersonRecode> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
            meetingPersonRecodeDAO.search(searchParams,sortList);
        });
        
        return page;
	}

/*	@Override
	public Page<Map> leaveEarlySearch(Map<String, Object> searchParams, int pageNumber, int pageSize,boolean count,List<Sort> sortList) {
		Page<Map> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
			meetingPersonRecodeDAO.leaveEarlySearch(searchParams,sortList);
		});
		return page;
	}*/

	@Override
	public Page<Map> meetingRecordPageList(Map<String, Object> searchParams, int pageNumber, int pageSize, boolean count, List<Sort> sortList){
		Page<Map> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
			meetingPersonRecodeDAO.meetingRecordPageList(searchParams,sortList);
		});
		return page;
	}

	@Override
	public Map<String, Object> findByPersonIdAndDate(Long personId, Date attendanceDate) {
		Map<String,Object> timeMap = null;

		DateTime attendanceTime = new DateTime(attendanceDate);

		List<MeetingPersonRecode> recodeList = meetingPersonRecodeDAO.findByPersonIdAndSignTime(personId,
				attendanceTime.withTimeAtStartOfDay().toDate(),
				attendanceTime.withTimeAtStartOfDay().plusDays(1).toDate());

		SimpleDateFormat ymdFormat = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat fullFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

		//查询今日打卡的每个会议的开始、截止时间，看与考勤时间是否有交集
		for (MeetingPersonRecode meetingPersonRecode : recodeList) {
			List<MeetingTime> timeList = meetingTimeDAO.findByMeetingId(meetingPersonRecode.getMeetingInfoId());

			boolean find = false;

			//一个会议可以分多个时间开
			for (MeetingTime meetingTime : timeList) {
				try {
					String meetingDate = ymdFormat.format(meetingTime.getMeetingDate());
					JSONObject jsonObject = JSONObject.fromObject(meetingTime.getMeetingTime());

					Date startTime = fullFormat.parse(meetingDate + " " + jsonObject.get("start"));
					Date endTime = fullFormat.parse(meetingDate + " " + jsonObject.get("end"));

					if(startTime.compareTo(attendanceDate)<=0 && attendanceDate.compareTo(endTime)<=0){
						timeMap = new HashMap<>();
						timeMap.put("startTime",startTime);
						timeMap.put("endTime",endTime);

						find = true;
						break;
					}
				}
				catch (Exception ex){
					log.error(ex.getMessage(),ex);
				}
			}

			if (find){
				break;
			}
		}

		return timeMap;
	}
}