package org.linlinjava.jz.service;

import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import org.linlinjava.jz.db.dao.HmEmployClockMapper;
import org.linlinjava.jz.db.dao.HmEmployTaskMapper;
import org.linlinjava.jz.db.domain.*;
import org.linlinjava.jz.db.domain.HmEmployClockExample.Criteria;
import org.linlinjava.jz.db.dto.hm.HmEmployClockExtend.ClockItem;
import org.linlinjava.jz.db.dto.hm.HmEmployClockUpdateDto;
import org.linlinjava.jz.db.service.hm.HmCommentService;
import org.linlinjava.jz.db.service.hm.HmEmployRelationService;
import org.linlinjava.jz.db.service.hm.HmEmployTaskService;
import org.linlinjava.jz.db.service.hm.HmTaskItemService;
import org.linlinjava.jz.db.util.TicketStatusConstant;
import org.linlinjava.jz.db.util.hm.HmCommentEnum;
import org.linlinjava.jz.db.util.hm.HmEmployClockEnum;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author fuxubing
 */
@Service
public class HmEmployClockService {
    @Resource
    private HmEmployClockMapper hmEmployClockMapper;

    @Resource
    private HmCommentService hmCommentService;

    @Resource
    private HmEmployRelationService employRelationService;

    @Resource
    private HmEmployTaskService employTaskService;

    @Resource
    private HmTaskItemService hmTaskItemService;

    @Resource
    private HmEmployTaskMapper employTaskMapper;

    @Resource
    private NoticeService noticeService;

    public static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");

    public List<HmEmployClock> queryByOrderNo(String orderNo, Long id, Integer page, Integer limit) {
        HmEmployClockExample example = new HmEmployClockExample();
        Criteria createCriteria = example.createCriteria();
//        example.or().andOrderNoEqualTo(orderNo);
        createCriteria.andOrderNoEqualTo(orderNo);
        if (null != id) {
            createCriteria.andIdEqualTo(id);
        }
        example.setOrderByClause(" id desc ");
        PageHelper.startPage(page, limit);
        return hmEmployClockMapper.selectByExample(example);
    }

    public HmEmployClock queryById(Long id) {
        return hmEmployClockMapper.selectByPrimaryKey(id);
    }

    /**
     * 查寻单个保姆服务记录list
     *
     * @param page
     * @param limit
     * @param employRelationId
     * @return
     */
    public List<HmEmployClock> sereviceHistory(Integer page, Integer limit, Long employRelationId) {
        HmEmployClockExample example = new HmEmployClockExample();
        example.or().andEmployRelationIdEqualTo(employRelationId);
        PageHelper.startPage(page, limit);
        List<HmEmployClock> list = hmEmployClockMapper.selectByExample(example);
        HmEmployRelation er = employRelationService.queryById(employRelationId);

        for (HmEmployClock d : list) {
            String statusName = "";
            String newProgress = "";
            if (HmEmployClockEnum.STATUS_0.getType() == d.getStatus()) {
                statusName = HmEmployClockEnum.STATUS_0.getTypeName();
                newProgress = "保姆还未打卡上班";
            }
            if (HmEmployClockEnum.STATUS_1.getType() == d.getStatus()) {
                statusName = HmEmployClockEnum.STATUS_1.getTypeName();
                newProgress = "上班打卡时间:" + dtf.format(d.getStartWorkTime());
            }
            if (HmEmployClockEnum.STATUS_2.getType() == d.getStatus()) {
                // 服务完成后判断，是否评价，评价几星
                statusName = HmEmployClockEnum.STATUS_2.getTypeName();
                newProgress = "打卡服务完成时间:" + dtf.format(d.getStartWorkTime());
                HmComment comment = hmCommentService.queryByRIdAndType(d.getId(),
                        HmCommentEnum.comment_num_3.getType());
                if (null != comment) {
                    statusName = "服务已评价";
                    if (comment.getStar() > 3) {
                        newProgress = "用户已作出" + comment.getStar() + "星评价";
                    } else {
                        newProgress = "用户已作出" + comment.getStar() + "星评价，已生成管家任务";
                    }
                }

            }
            if (HmEmployClockEnum.STATUS_3.getType() == d.getStatus()) {
                statusName = HmEmployClockEnum.STATUS_3.getTypeName();
                newProgress = HmEmployClockEnum.getApprovalStateName(HmEmployClockEnum.STATUS_3.getType(), d.getApprovalState());
            }

            if (HmEmployClockEnum.STATUS_4.getType() == d.getStatus()) {
                statusName = HmEmployClockEnum.STATUS_4.getTypeName();
                newProgress = "用户当日已请假";
            }
            if (HmEmployClockEnum.STATUS_5.getType() == d.getStatus()) {
                statusName = HmEmployClockEnum.STATUS_5.getTypeName();
                newProgress = "保姆当日缺勤未打卡,已生成管家任务";//，已生成管家工单
            }
            d.setStatusName(statusName);
            d.setNewProgress(newProgress);
            d.setServantName(er.getServantName());
            d.setCustomerName(er.getEmployerName());
        }

        return list;
    }

    /**
     * 查看保姆某天的任务
     *
     * @param employClockId
     * @return
     */
    public HmEmployClock getServantClockInfo(Long employClockId) {
        HmEmployClock emClock = queryById(employClockId);
        if (emClock == null) {
            throw new RuntimeException("数据异常");
        }

        HmEmployRelation er = employRelationService.queryById(emClock.getEmployRelationId());
        emClock.setServantName(er.getServantName());

        String statusName = HmEmployClockEnum.getTypeName(emClock.getStatus());
        if (emClock.getStatus() == HmEmployClockEnum.STATUS_3.getType()) {
            statusName = HmEmployClockEnum.getApprovalStateName(HmEmployClockEnum.STATUS_3.getType(), emClock.getStatus());
        }
        emClock.setStatusName(statusName);

        //拿每日任务hm_employ_task_set
        List<HmEmployTask> employTaskList = employTaskService.getEmployTaskList(employClockId);


        emClock.setErvryDayList(getEmpLoyTaskType(employTaskList, 1));
        emClock.setErvryWeekList(getEmpLoyTaskType(employTaskList, 2));
        emClock.setErvryMonthList(getEmpLoyTaskType(employTaskList, 3));

        return emClock;
    }


    public List<ClockItem> getEmpLoyTaskType(List<HmEmployTask> list, int type) {
        List<ClockItem> itemList = new ArrayList<ClockItem>();
        if (list == null || list.size() == 0) {
            return itemList;
        }

        list.forEach(e -> {
            if (e.getTaskType().equals(type)) {
                ClockItem c = new ClockItem();
                c.setClockId(e.getId());
                c.setStatus(e.getState());
                c.setTaskName(hmTaskItemService.getItemName(e.getItemId()));
                itemList.add(c);
            }
        });

        return itemList;
    }

    /**
     * 管家修改保姆打卡
     *
     * @param emClock
     * @return
     */
    @Transactional
    public void updateEmployClockInof(HmEmployClockUpdateDto emClock) {
        HmEmployClock clock = new HmEmployClock();
        clock.setId(emClock.getEmployClockId());
        clock.setStartWorkTime(emClock.getStartWorkTime());
        clock.setEndWorkTime(emClock.getEndWorkTime());
        clock.setStatus(emClock.getStatus());
        hmEmployClockMapper.updateByPrimaryKeySelective(clock);

//		if(null!=ervryDayList&&ervryDayList.size()>0) {
//			HmEmployTask record;
//			employTaskMapper.updateByPrimaryKey(record);
//		}
        List<ClockItem> taskList = new ArrayList<ClockItem>();


        List<ClockItem> ervryDayList = emClock.getErvryDayList();
        if (null != ervryDayList) {
            taskList.addAll(ervryDayList);
        }
        List<ClockItem> ervryWeekList = emClock.getErvryWeekList();
        if (null != ervryWeekList) {
            taskList.addAll(ervryWeekList);
        }
        List<ClockItem> ervryMonthList = emClock.getErvryMonthList();
        if (null != ervryMonthList) {
            taskList.addAll(ervryMonthList);
        }

        if (taskList.size() > 0) {
            taskList.forEach(e -> {
                HmEmployTask record = new HmEmployTask();
                record.setId(e.getClockId());
                record.setState(e.getStatus());
                employTaskMapper.updateByPrimaryKeySelective(record);
            });
        }

        if (null != emClock.getNoticeId()) {
            noticeService.addNoticeUser(emClock.getNoticeId(), "修改了打卡记录", TicketStatusConstant.STATUS_PROCESSING.toString());
        }

    }

    public int insert(HmEmployClock hmEmployClock) {
        return hmEmployClockMapper.insertSelective(hmEmployClock);
    }

    public int update(HmEmployClock hmEmployClock) {
        return hmEmployClockMapper.updateByPrimaryKeySelective(hmEmployClock);
    }

    /**
     * 工作日未打卡或打了上班卡未打下班卡视为缺勤
     *
     * @return
     */
    public int updateAbsentOfWork() {
        HmEmployClock hmEmployClock = new HmEmployClock();
        hmEmployClock.setStatus(HmEmployClockEnum.STATUS_5.getType());
        hmEmployClock.setUpdateTime(LocalDateTime.now());

        HmEmployClockExample example = new HmEmployClockExample();
        HmEmployClockExample.Criteria criteria = example.createCriteria();
        criteria.andWorkDataEqualTo(LocalDate.now().plusDays(-1).atStartOfDay());
        criteria.andStatusIn(Lists.newArrayList(0, 1));
        criteria.andIsRestdayEqualTo(0);

        return hmEmployClockMapper.updateByExampleSelective(hmEmployClock, example);
    }

    public long queryByState(Long employRelationId, Integer status) {
        HmEmployClockExample example = new HmEmployClockExample();
        example.or().andEmployRelationIdEqualTo(employRelationId).andStatusEqualTo(status);
        return hmEmployClockMapper.countByExample(example);
    }

    /**
     * 获取打卡天数
     *
     * @param employRelationId
     * @param startTime
     * @param endTime
     * @return
     */
    public long getDayOfMonthClock(Long employRelationId, LocalDate startTime, LocalDate endTime) {
        HmEmployClockExample example = new HmEmployClockExample();

        HmEmployClockExample.Criteria criteria = example.createCriteria();
        criteria.andEmployRelationIdEqualTo(employRelationId);
        criteria.andStatusEqualTo(HmEmployClockEnum.STATUS_2.getType());
        if (null != startTime) {
            criteria.andWorkDataGreaterThanOrEqualTo(startTime.atStartOfDay());
        }
        if (null != endTime) {
            criteria.andWorkDataLessThanOrEqualTo(endTime.atStartOfDay());
        }

        return hmEmployClockMapper.countByExample(example);
    }

    public HmEmployClock queryByDate(Long employRelationId, LocalDateTime date) {
        HmEmployClockExample example = new HmEmployClockExample();
        example.or().andEmployRelationIdEqualTo(employRelationId).andWorkDataEqualTo(date);
        return hmEmployClockMapper.selectOneByExample(example);
    }

    /**
     * 查询休息日加班天数
     *
     * @param employRelationId
     * @return
     */
    public long queryCountByIsRestDay(Long employRelationId, LocalDate startTime, LocalDate endTime) {
        HmEmployClockExample example = new HmEmployClockExample();
        HmEmployClockExample.Criteria criteria = example.createCriteria();
        criteria.andEmployRelationIdEqualTo(employRelationId);
        criteria.andStatusEqualTo(HmEmployClockEnum.STATUS_2.getType());
        criteria.andIsRestdayEqualTo(1);
        if (null != startTime) {
            criteria.andWorkDataGreaterThanOrEqualTo(startTime.atStartOfDay());
        }
        if (null != endTime) {
            criteria.andWorkDataLessThanOrEqualTo(endTime.atStartOfDay());
        }
        return hmEmployClockMapper.countByExample(example);
    }

    /**
     * 查询法定节假日加班天数
     *
     * @param employRelationId
     * @return
     */
    public long queryCountByIsHoliday(Long employRelationId, LocalDate startTime, LocalDate endTime) {
        HmEmployClockExample example = new HmEmployClockExample();
        HmEmployClockExample.Criteria criteria = example.createCriteria();
        criteria.andEmployRelationIdEqualTo(employRelationId);
        criteria.andStatusEqualTo(HmEmployClockEnum.STATUS_2.getType());
        criteria.andIsHolidayEqualTo(1);
        if (null != startTime) {
            criteria.andWorkDataGreaterThanOrEqualTo(startTime.atStartOfDay());
        }
        if (null != endTime) {
            criteria.andWorkDataLessThanOrEqualTo(endTime.atStartOfDay());
        }
        return hmEmployClockMapper.countByExample(example);
    }

    /**
     * 获取打卡小时数
     *
     * @param employRelationId
     * @param isRestday
     * @param isHoliday
     * @param startTime
     * @param endTime
     * @return
     */
    public long getHoursOfMonthClock(Long employRelationId, Integer isRestday, Integer isHoliday, LocalDate startTime, LocalDate endTime) {
        return hmEmployClockMapper.getHoursOfMonthClock(employRelationId, isRestday, isHoliday, startTime, endTime);
    }

    public List<Map<String, Object>> queryByMonth(Long employRelationId, String date) {
        return hmEmployClockMapper.queryByMonth(employRelationId, date);
    }

    /**
     * 查询打卡缺勤记录
     *
     * @param dateTime
     * @return
     */
    public List<HmEmployClock> queryAbsentOfWork(LocalDateTime dateTime) {
        HmEmployClockExample example = new HmEmployClockExample();
        example.or().andWorkDataEqualTo(dateTime).andStatusEqualTo(HmEmployClockEnum.STATUS_5.getType());
        return hmEmployClockMapper.selectByExample(example);
    }

    /**
     * 休息日打了上班卡未打下班卡视为缺勤
     *
     * @return
     */
    public int updateAbsentOfRest() {
        HmEmployClock hmEmployClock = new HmEmployClock();
        hmEmployClock.setStatus(HmEmployClockEnum.STATUS_5.getType());
        hmEmployClock.setUpdateTime(LocalDateTime.now());

        HmEmployClockExample example = new HmEmployClockExample();
        HmEmployClockExample.Criteria criteria = example.createCriteria();
        criteria.andWorkDataEqualTo(LocalDate.now().plusDays(-1).atStartOfDay());
        criteria.andStatusEqualTo(HmEmployClockEnum.STATUS_1.getType());
        criteria.andIsRestdayEqualTo(1);

        return hmEmployClockMapper.updateByExampleSelective(hmEmployClock, example);
    }
}
