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

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jpsoft.shinestar.modules.base.dao.*;
import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.base.service.CanteenDiningRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.github.pagehelper.Page;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.github.pagehelper.PageHelper;

@Slf4j
@Transactional
@Component(value="canteenDiningRecordService")
public class CanteenDiningRecordServiceImpl implements CanteenDiningRecordService {
	@Resource(name="canteenDiningRecordDAO")
	private CanteenDiningRecordDAO canteenDiningRecordDAO;

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

	@Resource(name="canteenDeviceDAO")
	private CanteenDeviceDAO canteenDeviceDAO;

	@Resource(name="canteenDiningDAO")
	private CanteenDiningDAO canteenDiningDAO;

	@Resource(name="canteenInfoDAO")
	private CanteenInfoDAO canteenInfoDAO;

	@Resource(name = "personInfoDAO")
	private PersonInfoDAO personInfoDAO;

	@Resource(name="companyInfoDAO")
	private CompanyInfoDAO companyInfoDAO;

	@Resource(name="canteenOutsourcerBalanceDAO")
	private CanteenOutsourcerBalanceDAO canteenOutsourcerBalanceDAO;

	@Autowired
	private ValueOperations<String, Object> valueOperations;

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

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

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

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

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

	@Override
	public int findCountByPersonId(Long personId){
		return canteenDiningRecordDAO.findCountByPersonId(personId);
	}

	@Override
	public int findCountByPersonIdAndAddress(Map<String, Object> searchParams){
		return canteenDiningRecordDAO.findCountByPersonIdAndAddress(searchParams);
	}

	@Override
	public List<CanteenDiningRecord> findByPersonId(Long personId){
		return canteenDiningRecordDAO.findByPersonId(personId);
	}

	@Override
	public CanteenDiningRecord lastEatTime(Long personId){
		return canteenDiningRecordDAO.lastEatTime(personId);
	}
		
	@Override
	public Page<CanteenDiningRecord> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize,boolean count,List<Sort> sortList) {
        Page<CanteenDiningRecord> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
            canteenDiningRecordDAO.search(searchParams,sortList);
        });
        
        return page;
	}

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

		return page;
	}

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

		return page;
	}

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

		return page;
	}





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

		return page;
	}

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

		return page;
	}


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

		try {
		//1分钟之内只通知一次
//		boolean absent = valueOperations.setIfAbsent("canteen_" + personId, true, 1, TimeUnit.MINUTES);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Calendar calendar = Calendar.getInstance();
			String recordDate = sdf.format(recordTime);

			Date now = new Date();
			PersonInfo personInfo = personInfoDAO.get(personId);
			CompanyInfo companyInfo = companyInfoDAO.get(personInfo.getCompanyId());

			Boolean isOutsourcer = false;

			if (companyInfo != null) {
				isOutsourcer = companyInfo.getIsOutsourcer();
			}

			DeviceInfo deviceInfo = deviceInfoDAO.findByDeviceNo(deviceNo);

			if (deviceInfo != null) {
				CanteenDevice canteenDevice = canteenDeviceDAO.findByDeviceId(deviceInfo.getId());
				if (canteenDevice != null) {
					CanteenInfo canteenInfo = canteenInfoDAO.get(canteenDevice.getCanteenId());

					List<CanteenDining> list = canteenDiningDAO.findByCanteenId(canteenDevice.getCanteenId());

					for (CanteenDining canteenDining : list) {
						String diningTime = canteenDining.getDiningTime();
						JSONObject jsonObject = JSONUtil.parseObj(diningTime);
						String start = (String) jsonObject.get("start");
						String end = (String) jsonObject.get("end");

						String startDateStr = recordDate + " " + start + ":00";
						String endDateStr = recordDate + " " + end + ":00";

						Date startTime = sdf1.parse(startDateStr);
						Date endTime = sdf1.parse(endDateStr);

						if (startTime.compareTo(endTime) > 0) {
							calendar.setTime(recordTime);
							calendar.add(Calendar.DATE, 1);
							Date newDate = calendar.getTime();
							String newDateStr = sdf.format(newDate);
							endDateStr = newDateStr + " " + end + ":00";
							endTime = sdf1.parse(endDateStr);
						}

						if (recordTime.compareTo(startTime) >= 0 && recordTime.compareTo(endTime) <= 0) {
							CanteenDiningRecord canteenDiningRecord = canteenDiningRecordDAO.findByPersonIdAndRecordTime(personId, startTime, endTime);
							if (canteenDiningRecord == null) {
								//此时段无刷卡记录
								canteenDiningRecord = new CanteenDiningRecord();
								canteenDiningRecord.setId(UUID.randomUUID().toString());
								canteenDiningRecord.setDelFlag(false);
								canteenDiningRecord.setCreateTime(now);
								canteenDiningRecord.setRecordTime(recordTime);
								canteenDiningRecord.setDeviceNo(deviceNo);
								canteenDiningRecord.setPersonId(personId);
								canteenDiningRecord.setAttendanceDate(recordDate);

								if (isOutsourcer) {
									canteenDiningRecord.setIsOutsourcer(true);
								} else {
									canteenDiningRecord.setIsOutsourcer(false);
								}

								if (canteenInfo != null) {
									canteenDiningRecord.setAddress(canteenInfo.getAddress());
									canteenDiningRecord.setCategory(canteenDining.getDiningType());
									canteenDiningRecord.setCategoryAmount(canteenDining.getOutsourcerDiningFee());
//									if (isOutsourcer) {
//										canteenDiningRecord.setCategoryAmount(canteenDining.getOutsourcerDiningFee());
//									} else {
//										canteenDiningRecord.setCategoryAmount(canteenDining.getDiningFee());
//									}
								}

								int count = canteenDiningRecordDAO.insert(canteenDiningRecord);

								if (count > 0) {
//								CanteenOutsourcerBalance canteenOutsourcerBalance = canteenOutsourcerBalanceDAO.findByPersonId(personId);
//								if(canteenOutsourcerBalance!=null){
//									BigDecimal amount = canteenOutsourcerBalance.getAmount();
//									BigDecimal outsourcerDiningFee = canteenDining.getOutsourcerDiningFee();
//									if(amount.compareTo(outsourcerDiningFee)>-1){
//										//余额大于就餐金额
//										BigDecimal bdFee = amount.subtract(outsourcerDiningFee);
//										canteenOutsourcerBalance.setAmount(bdFee);
//										canteenOutsourcerBalance.setUpdateTime(now);
//										canteenOutsourcerBalanceDAO.update(canteenOutsourcerBalance);
//									}
//								}
									result = true;
									break;
								}
							}
						}
					}
				}
			}

			log.warn("食堂就餐打卡PersonId={},result={}", personId, result);
		}
		catch (Exception ex){
			log.error(ex.getMessage(), ex);
		}

		return result;
	}
}