package org.linlinjava.jz.hm.web.servant;

import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.linlinjava.jz.core.util.DateTimeUtil;
import org.linlinjava.jz.db.domain.ContractSub;
import org.linlinjava.jz.db.domain.ContractSubTemplate;
import org.linlinjava.jz.db.domain.HmEmployClock;
import org.linlinjava.jz.db.domain.HmEmployRelation;
import org.linlinjava.jz.db.dto.hm.calendar.CalendarDto;
import org.linlinjava.jz.db.dto.hm.calendar.EveryDay;
import org.linlinjava.jz.db.service.ContractSubService;
import org.linlinjava.jz.db.service.ContractSubTemplateService;
import org.linlinjava.jz.db.service.hm.HmAppUserService;
import org.linlinjava.jz.db.service.hm.HmEmployRelationService;
import org.linlinjava.jz.db.service.hm.HmEmployTaskService;
import org.linlinjava.jz.db.util.HmResponseUtil;
import org.linlinjava.jz.db.util.hm.CalendarUtil;
import org.linlinjava.jz.db.util.hm.HmEmployClockEnum;
import org.linlinjava.jz.db.util.hm.HmNoticeEnum;
import org.linlinjava.jz.db.util.hm.HolidayUtil;
import org.linlinjava.jz.dto.HmNoticeDto;
import org.linlinjava.jz.hm.util.DateUtil;
import org.linlinjava.jz.service.HmEmployClockService;
import org.linlinjava.jz.service.HmServantIncomeService;
import org.linlinjava.jz.service.NoticeService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author fuxubing
 */
@Api(value = "保姆-服务打卡请假信息", description = "保姆-服务打卡请假信息")
@RestController
@RequestMapping("serviceInfo")
@Valid
public class HmServantInfoController {

    @Resource
    private HmEmployRelationService hmEmployRelationService;
    @Resource
    private HmEmployClockService hmEmployClockService;
    @Resource
    private HmEmployTaskService hmEmployTaskService;
    @Resource
    private ContractSubService contractSubService;
    @Resource
    private HmAppUserService hmAppUserService;
    @Resource
    private HmServantIncomeService hmServantIncomeService;
    @Resource
    private NoticeService noticeService;
    @Resource
    private ContractSubTemplateService contractSubTemplateService;

    @ApiOperation(value = "上班打卡", notes = "上班打卡")
    @GetMapping(value = "servantWorkClock")
    public Object servantClock(@NotNull @RequestParam Long employRelationId, @NotBlank @RequestParam String date) {
        HmEmployRelation relation = hmEmployRelationService.queryById(employRelationId);
        if (relation == null) {
            return HmResponseUtil.fail_null();
        }

        HmEmployClock hmEmployClock = hmEmployClockService.queryByDate(employRelationId, DateUtil.strToLocalDate(date).atStartOfDay());

        if (null == hmEmployClock) {
            return HmResponseUtil.fail_null();
        }

        //未打卡
        if (HmEmployClockEnum.STATUS_0.getType() == hmEmployClock.getStatus()) {
            //判断是否为休息日
            if (relation.getRestDay().contains(DateUtil.dateToString(DateUtil.stringToDate(date)))) {
                hmEmployClock.setIsRestday(1);
            }

            HolidayUtil.holidays holiday = HolidayUtil.getHoliday(date);
            //是否为法定节假日
            if (null != holiday) {
                hmEmployClock.setIsHoliday(1);
            }

            hmEmployClock.setStartWorkTime(DateUtil.strToLocalDate(date).atTime(LocalTime.now()));
            hmEmployClock.setStatus(HmEmployClockEnum.STATUS_1.getType());
            hmEmployClock.setUpdateTime(LocalDateTime.now());
            hmEmployClockService.update(hmEmployClock);
        }

        return HmResponseUtil.ok();
    }


    @ApiOperation(value = "下班打卡", notes = "下班打卡")
    @GetMapping(value = "servantOffWorkClock")
    public Object servantOffWorkClock(@NotNull @RequestParam Long employClockId) throws ParseException {
        HmEmployClock hmEmployClock = hmEmployClockService.queryById(employClockId);
        if (null == hmEmployClock) {
            return HmResponseUtil.fail_null();
        }

        HmEmployRelation relation = hmEmployRelationService.queryById(hmEmployClock.getEmployRelationId());

        boolean allCompleted = hmEmployTaskService.isAllCompleted(employClockId, relation.getIsNeedClock());

        if (!allCompleted) {
            return HmResponseUtil.fail("请确认任务是否全部完成，全部完成后再重试");
        }

        hmEmployClock.setEndWorkTime(LocalDateTime.now());
        hmEmployClock.setStatus(HmEmployClockEnum.STATUS_2.getType());
        hmEmployClock.setUpdateTime(LocalDateTime.now());
        int count = hmEmployClockService.update(hmEmployClock);

        //通知
        HmNoticeDto hmNoticeDto = new HmNoticeDto();
        hmNoticeDto.setAppUserId(Lists.newArrayList(relation.getUserEmployerId()));
        hmNoticeDto.setEmployRelationId(relation.getId());
        hmNoticeDto.setrId(hmEmployClock.getId().toString());
        hmNoticeDto.setCreateUserId(relation.getUserServantId());
//        hmNoticeDto.setContent("保姆" + hmEmployClock.getWorkData().toLocalDate() + "服务已经全部完成，评价一下吧！");
        hmNoticeDto.setRtype(HmNoticeEnum.NOTICE_NUM_4.getType());
        hmNoticeDto.setNoticeUserType(HmNoticeEnum.NOTICE_NUM_4.getNoticeUserType());
        hmNoticeDto.setRemark(DateUtil.DateFormatToyyyyMMdd(hmEmployClock.getWorkData()));
        noticeService.create(hmNoticeDto);

        if (count > 0) {
            ContractSubTemplate contractSubTemplate = contractSubTemplateService.selectByOrderNo(hmEmployClock.getOrderNo());
            if (null == contractSubTemplate) {
                return HmResponseUtil.fail_null();
            }
            BigDecimal dayClockIncome = hmServantIncomeService.getDayClockIncome(contractSubTemplate);
            return HmResponseUtil.ok(dayClockIncome);
        } else {
            return HmResponseUtil.fail();
        }
    }

    @ApiOperation(value = "我的工资页面我的东家和我的老师信息展示", notes = "我的工资页面我的东家和我的老师信息展示")
    @GetMapping(value = "getEmployInfo")
    public Object getEmployInfo(@NotNull @RequestParam Long employRelationId) throws ParseException {
        HmEmployRelation relation = hmEmployRelationService.queryById(employRelationId);
        if (relation == null) {
            return HmResponseUtil.fail_null();
        }

        Map<String, Object> map = new HashMap<>(16);
        map.put("restDay", relation.getRestDay());
        ContractSub contractSub = contractSubService.queryByOrderNo(relation.getOrderNo());
        if (null != contractSub) {
            map.put("serviceModel", contractSub.getServiceModel());
            map.put("contractState", contractSub.getContractState());
        }

        map.put("employerName", relation.getEmployerName());
        map.put("butlerName", relation.getButlerName());
        map.put("butlerTel", hmAppUserService.queryById(relation.getUserButlerId()).getPhone());

        LocalDate firstDayOfMonth = DateTimeUtil.firstDayOfMonth(LocalDate.now());
        LocalDate lastDayOfMonth = DateTimeUtil.lastDayOfMonth(LocalDate.now());

        ContractSubTemplate contractSubTemplate = contractSubTemplateService.selectByOrderNo(relation.getOrderNo());
        if (null == contractSubTemplate) {
            return HmResponseUtil.fail_null();
        }

        BigDecimal currentMonthlyIncome = hmServantIncomeService.getTotalIncome(relation.getId(), contractSubTemplate, firstDayOfMonth, lastDayOfMonth);
        BigDecimal totalIncome = hmServantIncomeService.getTotalIncome(relation.getId(), contractSubTemplate, null, null);

        map.put("currentMonthlyIncome", currentMonthlyIncome);
        map.put("totalIncome", totalIncome);
        return HmResponseUtil.ok(map);
    }


    @ApiOperation(value = "打卡日历", notes = "打卡日历")
    @GetMapping(value = "getClockCalendar")
    public Object getClockCalendar(@NotNull @RequestParam Long employRelationId, @NotBlank @RequestParam String date) {
        HmEmployRelation relation = hmEmployRelationService.queryById(employRelationId);
        if (relation == null) {
            return HmResponseUtil.fail_null();
        }
        String[] restDayArr = relation.getRestDay().split(",");
        CalendarDto calendarDto = CalendarDto.currentDayMonth(date);
        CalendarDto.setBusinessRestDay(calendarDto, restDayArr);

        List<EveryDay> everyDay = calendarDto.getEveryDay();
        //设置打卡状态
        everyDay.forEach(item -> {
            HmEmployClock hmEmployClock = hmEmployClockService.queryByDate(employRelationId, DateUtil.strToLocalDate(item.getDayymd()).atStartOfDay());
            if (null == hmEmployClock) {
                item.setClockStatus(HmEmployClockEnum.STATUS_0.getType());
            } else {
                item.setRestDay(hmEmployClock.getIsRestday() == 1);
                item.setClockStatus(hmEmployClock.getStatus());
            }
        });

        Map<String, Object> map = new HashMap<>(16);
        // 获取当月天数
        List<String> days = CalendarUtil.getDayListOfMonth(calendarDto.getCurrentMonth());
        //需打卡次数
        map.put("needClockTimes", days.size() - restDayArr.length);
        //已打卡次数
        map.put("alreadyTimes", hmEmployClockService.queryByState(employRelationId, 2));
        //请假
        map.put("leaveTimes", hmEmployClockService.queryByState(employRelationId, 4));
        //缺勤
        map.put("offWorkTimes", hmEmployClockService.queryByState(employRelationId, 5));
        //打卡日历
        map.put("calendar", calendarDto);
        return HmResponseUtil.ok(map);
    }

    @ApiOperation(value = "请假")
    @GetMapping(path = "leave")
    public Object leave(@NotNull @RequestParam Long employRelationId, @NotBlank @RequestParam String leaveDate, @NotBlank @RequestParam String leaveReason) {
        HmEmployRelation relation = hmEmployRelationService.queryById(employRelationId);
        if (relation == null) {
            return HmResponseUtil.fail_null();
        }

        LocalDate localDate = DateTimeUtil.strToLocalDate(leaveDate);
        if (LocalDate.now().isAfter(localDate) || localDate.equals(LocalDate.now())) {
            return HmResponseUtil.fail("该时间段不可发起请假");
        }

        HmEmployClock hmEmployClock = new HmEmployClock();

        hmEmployClock.setWorkData(DateUtil.strToLocalDate(leaveDate).atStartOfDay());

        if (relation.getRestDay().contains(DateUtil.dateToString(DateUtil.stringToDate(leaveDate)))) {
            hmEmployClock.setIsRestday(1);
        }

        HolidayUtil.holidays holiday = HolidayUtil.getHoliday(leaveDate);
        //是否为法定节假日
        if (null != holiday) {
            hmEmployClock.setIsHoliday(1);
        }
        hmEmployClock.setStatus(HmEmployClockEnum.STATUS_3.getType());
        hmEmployClock.setLeaveDate(DateUtil.strToLocalDate(leaveDate).atStartOfDay());
        hmEmployClock.setLeaveReason(leaveReason);
        hmEmployClock.setApprovalState(HmEmployClockEnum.APPROVAL_STATE_0);
        hmEmployClock.setOrderNo(relation.getOrderNo());
        hmEmployClock.setEmployRelationId(employRelationId);
        hmEmployClock.setCreateTime(LocalDateTime.now());
        hmEmployClock.setUpdateTime(LocalDateTime.now());

        hmEmployClockService.insert(hmEmployClock);
        //通知
        HmNoticeDto hmNoticeDto = new HmNoticeDto();
        hmNoticeDto.setAppUserId(Lists.newArrayList(relation.getUserEmployerId()));
        hmNoticeDto.setEmployRelationId(relation.getId());
        hmNoticeDto.setrId(hmEmployClock.getId().toString());
        hmNoticeDto.setCreateUserId(relation.getUserServantId());
//        hmNoticeDto.setContent("保姆发起了" + leaveDate + "的请假申请，需要您的审批！");
        hmNoticeDto.setRtype(HmNoticeEnum.NOTICE_NUM_1.getType());
        hmNoticeDto.setNoticeUserType(HmNoticeEnum.NOTICE_NUM_1.getNoticeUserType());
        hmNoticeDto.setRemark(leaveDate);
        noticeService.create(hmNoticeDto);

        return HmResponseUtil.ok();
    }

}
