package com.sunxung.factoring.service.sys.workingDayManage.impl;

import cn.hutool.core.date.DateTime;
import com.sunxung.factoring.component.util.DateUtil;
import com.sunxung.factoring.component.util.ValidatorUtil;
import com.sunxung.factoring.entity.ValidatorEntity.ValidatorType;
import com.sunxung.factoring.entity.sys.workingDayManage.WorkingDayManage;
import com.sunxung.factoring.mapper.sys.workingDayManage.WorkingDayManageMapper;
import com.sunxung.factoring.service.sys.workingDayManage.WorkingDayManageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class WorkingDayManageServiceImpl implements WorkingDayManageService {

    @Autowired
    private WorkingDayManageMapper workingDayManageMapper;

    @Override
    public List<WorkingDayManage> findByMonth(String yearMonth) {
        return workingDayManageMapper.findByMonth(yearMonth);
    }

    @Transactional
    @Override
    public WorkingDayManage add(WorkingDayManage workingDay) {
        ValidatorUtil.validator(ValidatorType.ADD, workingDay);
        workingDayManageMapper.add(workingDay);
        return get(workingDay.getId());
    }

    @Transactional
    @Override
    public WorkingDayManage update(WorkingDayManage workingDay) {
        ValidatorUtil.validator(ValidatorType.UPDATE, workingDay);
        workingDayManageMapper.update(workingDay);
        return get(workingDay.getId());
    }

    @Override
    public WorkingDayManage get(Long id) {
        return workingDayManageMapper.get(id);
    }

    @Override
    public WorkingDayManage getByDateTime(Date dateTime) {
        return workingDayManageMapper.getByDateTime(dateTime);
    }

    @Override
    public List<WorkingDayManage> findByStartEndDate(Date start, Date end) {
        return workingDayManageMapper.findByStartEndDate(start, end);
    }

    @Transactional
    @Override
    public boolean delete(Long id) {
        return workingDayManageMapper.delete(id) > 0;
    }

    @Transactional
    @Override
    public void addBetweenDates(String begin, String end) {
        List<Date> list = DateUtil.getBetweenDates(begin, end);
        list.stream().forEach((date) -> {
            WorkingDayManage workingDay = new WorkingDayManage();
            workingDay.setDateTime(date);
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            // 判断日期是否是周六周日，不是周末则默认设置为工作日
            if (cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY
                    && cal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) {
                workingDay.setWorkingDay(true);
            }
            add(workingDay);
        });
    }

    @Override
    public String getMaxYear() {
        Date maxDate = workingDayManageMapper.getMaxDate();
        return DateUtil.dateToString(maxDate, "yyyy");
    }

    @Override
    public Date getNextWorkDay(Date dateTime) {

        cn.hutool.core.date.DateTime date = cn.hutool.core.date.DateUtil.beginOfDay(dateTime);
        return getNext(date);
    }

    @Override
    public Date getLastWorkDay(Date dateTime) {
        DateTime date = cn.hutool.core.date.DateUtil.beginOfDay(dateTime);
        return getLast(date);
    }

    @Override
    public Date getWorkDay(Date dateTime, Integer interval) {
        DateTime date = cn.hutool.core.date.DateUtil.beginOfDay(dateTime);
        return getByInterval(date, interval);
    }

    private Date getByInterval(Date date, Integer interval) {
        if (date == null) {
            return null;
        }
        if (interval == 0) {
            return date;
        }
        DateTime next = cn.hutool.core.date.DateUtil.offsetDay(date, 1);
        WorkingDayManage workingDayManage = workingDayManageMapper.getByDateTime(next);

        if (workingDayManage == null) {
            return null;
        }

        if (workingDayManage.isWorkingDay()) {
            return getByInterval(next, interval - 1);
        } else {
            return getByInterval(next, interval);
        }
    }

    private Date getLast(Date date) {
        if (date == null) {
            return null;
        }
        DateTime next = cn.hutool.core.date.DateUtil.offsetDay(date, -1);
        WorkingDayManage workingDayManage = workingDayManageMapper.getByDateTime(next);

        if (workingDayManage.isWorkingDay()) {
            return next;
        } else {
            return getLast(next);
        }
    }


    Date getNext(Date date) {
        if (date == null) {
            return null;
        }
        DateTime next = cn.hutool.core.date.DateUtil.offsetDay(date, 1);
        WorkingDayManage workingDayManage = workingDayManageMapper.getByDateTime(next);

        if (workingDayManage.isWorkingDay()) {
            return next;
        } else {
            return getNext(next);
        }
    }
}
