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

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.hm.util.DateUtil;
import org.linlinjava.jz.service.HmEmployClockService;
import org.linlinjava.jz.service.HmServantIncomeService;
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.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author fuxubing
 */
@Api(value = "保姆-打卡任务相关信息", description = "保姆-打卡任务相关信息")
@RestController
@RequestMapping("home")
@Valid
public class EmployerHomeController {
    @Resource
    private HmEmployRelationService hmEmployRelationService;
    @Resource
    private ContractSubService contractSubService;
    @Resource
    private HmAppUserService hmAppUserService;
    @Resource
    private HmEmployClockService hmEmployClockService;
    @Resource
    private HmEmployTaskService hmEmployTaskService;
    @Resource
    private ContractSubTemplateService contractSubTemplateService;
    @Resource
    private HmServantIncomeService hmServantIncomeService;

    @ApiOperation(value = "我的保姆服务管家和保姆信息展示", notes = "我的保姆服务管家和保姆信息展示")
    @GetMapping(value = "getEmployInfo")
    public Object getEmployInfo(@NotNull @RequestParam Long employRelationId) {
        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("servantName", relation.getServantName());
        map.put("butlerTel", hmAppUserService.queryById(relation.getUserButlerId()).getPhone());

        return HmResponseUtil.ok(map);
    }

    @ApiOperation(value = "打卡日历", notes = "打卡日历")
    @GetMapping(value = "getClockCalendar")
    public Object getClockCalendar(@NotNull @RequestParam Long employRelationId, @NotBlank @RequestParam String date) throws ParseException {
        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, HmEmployClockEnum.STATUS_2.getType()));
        //请假
        map.put("leaveTimes", hmEmployClockService.queryByState(employRelationId, HmEmployClockEnum.STATUS_4.getType()));
        //缺勤
        map.put("offWorkTimes", hmEmployClockService.queryByState(employRelationId, HmEmployClockEnum.STATUS_5.getType()));
        //打卡日历
        map.put("calendar", calendarDto);
        //薪资计算
        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 totalIncome = hmServantIncomeService.getTotalIncome(relation.getId(), contractSubTemplate, firstDayOfMonth, lastDayOfMonth);
        map.put("totalIncome", totalIncome);

        return HmResponseUtil.ok(map);
    }

    @ApiOperation(value = "每日任务清单", notes = "每日任务清单")
    @GetMapping(value = "taskList")
    public Object taskList(@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());
        //每日任务
        List<Map<String, Object>> dayTaskList = Lists.newArrayList();
        //每周任务
        List<Map<String, Object>> weekEmployTaskList = Lists.newArrayList();
        //每月任务
        List<Map<String, Object>> monthEmployTaskList = Lists.newArrayList();

        //是否休息日
        boolean isRestDay = false;
        //是否质疑
        boolean isQuestion = false;

        long inCompleteCount = 0;

        if (null != hmEmployClock) {
            //如果不为空 从打卡记录取
            isRestDay = hmEmployClock.getIsRestday() == 1;
            boolean flag = hmEmployTaskService.isQuestion(hmEmployClock.getId(), relation.getIsNeedClock());
            ContractSubTemplate contractSubTemplate = contractSubTemplateService.selectByOrderNo(relation.getOrderNo());
            String lastPayDay = DateTimeUtil.localDateFormat(LocalDateTime.now().plusMonths(-1), "yyyy-MM") + "-" + contractSubTemplate.getPayday();
            //是否质疑
            if (1 == hmEmployClock.getStatus() || 2 == hmEmployClock.getStatus()) {
                if (DateTimeUtil.strToLocalDate(lastPayDay).isBefore(DateTimeUtil.strToLocalDate(date))) {
                    if (flag) {
                        isQuestion = true;
                    }
                }
            }

        } else {
            //判断是否是休息日
            if (relation.getRestDay().contains(date)) {
                isRestDay = true;
            }
            hmEmployClock = new HmEmployClock();
            hmEmployClock.setStatus(HmEmployClockEnum.STATUS_0.getType());
            hmEmployClock.setApprovalState(HmEmployClockEnum.APPROVAL_STATE_3);
        }

        //当前输入日期与合同开始日期比较
        boolean before = contractSubTemplateService.isBefore(relation.getOrderNo(), DateTimeUtil.strToLocalDate(date));

        if (!before && relation.getIsNeedClock() == 1) {
            //每日任务
            dayTaskList = hmEmployTaskService.getEmployTaskList(employRelationId, date);
            //每周任务
            weekEmployTaskList = hmEmployTaskService.getWeekEmployTaskList(employRelationId, date);
            //每月任务
            monthEmployTaskList = hmEmployTaskService.getMonthEmployTaskList(employRelationId, date);
        }


        Map<String, Object> map = new HashMap<>(16);
        map.put("isNeedClock", relation.getIsNeedClock() == 1);
        map.put("dayTaskList", dayTaskList);
        map.put("weekTaskList", weekEmployTaskList);
        map.put("monthTask", monthEmployTaskList);
        map.put("isRestDay", isRestDay);
        map.put("hmEmployClock", hmEmployClock);
        map.put("isQuestion", isQuestion);
        map.put("isBefore", before);
        map.put("inCompleteCount", inCompleteCount);
        return HmResponseUtil.ok(map);
    }

    @ApiOperation(value = "薪资说明", notes = "薪资说明")
    @GetMapping(value = "getSalaryDesc")
    public Object getSalaryDesc(@NotNull @RequestParam Long employRelationId) throws Exception {
        HmEmployRelation relation = hmEmployRelationService.queryById(employRelationId);
        if (relation == null) {
            return HmResponseUtil.fail_null();
        }

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

        Map<String, Object> map = new HashMap<>(16);

        List<Map<String, Object>> historyIncome = hmServantIncomeService.getHistoryIncome(employRelationId, contractSubTemplate);
        map.put("payType", contractSubTemplate.getMonthlySalary() != null ? 0 : 1);
        map.put("historyIncome", historyIncome);

        return HmResponseUtil.ok(map);
    }
}
