package com.younike.system.service.impl;

import com.younike.common.core.domain.AjaxResult;
import com.younike.common.exception.ServiceException;
import com.younike.common.utils.StringUtils;
import com.younike.system.domain.ServerTimeSection;
import com.younike.system.domain.vo.ServerTimeSectionVo;
import com.younike.system.mapper.ServerTimeSectionMapper;
import com.younike.system.service.IMerchantServerTimeService;
import com.younike.system.service.IServerTimeSectionService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 服务人员服务时间段Service业务层处理
 * 
 * @author elev
 * @date 2022-01-10
 */
@Service
public class ServerTimeSectionServiceImpl implements IServerTimeSectionService {
    @Autowired
    private ServerTimeSectionMapper serverTimeSectionMapper;
    @Autowired
    private IMerchantServerTimeService merchantServerTimeService;

    /**
     * 查询服务人员服务时间段
     * 
     * @param sectionId 服务人员服务时间段主键
     * @return 服务人员服务时间段
     */
    @Override
    public ServerTimeSection selectServerTimeSectionBySectionId(Long sectionId) {
        return serverTimeSectionMapper.selectServerTimeSectionBySectionId(sectionId);
    }

    /**
     * 查询服务人员服务时间段列表
     * 
     * @param serverTimeSection 服务人员服务时间段
     * @return 服务人员服务时间段
     */
    @Override
    public List<ServerTimeSection> selectServerTimeSectionList(ServerTimeSection serverTimeSection) {
        return serverTimeSectionMapper.selectServerTimeSectionList(serverTimeSection);
    }

    /**
     * 新增服务人员服务时间段
     * 
     * @param serverTimeSection 服务人员服务时间段
     * @return 结果
     */
    @Override
    public int insertServerTimeSection(ServerTimeSection serverTimeSection) {
        serverTimeSection.setCreateTime(LocalDateTime.now());
        return serverTimeSectionMapper.insertServerTimeSection(serverTimeSection);
    }

    /**
     * 修改服务人员服务时间段
     * 
     * @param serverTimeSection 服务人员服务时间段
     * @return 结果
     */
    @Override
    public int updateServerTimeSection(ServerTimeSection serverTimeSection) {
        serverTimeSection.setUpdateTime(LocalDateTime.now());
        return serverTimeSectionMapper.updateServerTimeSection(serverTimeSection);
    }

    /**
     * 批量删除服务人员服务时间段
     * 
     * @param sectionIds 需要删除的服务人员服务时间段主键
     * @return 结果
     */
    @Override
    public int deleteServerTimeSectionBySectionIds(Long[] sectionIds) {
        return serverTimeSectionMapper.deleteServerTimeSectionBySectionIds(sectionIds);
    }

    /**
     * 删除服务人员服务时间段信息
     * 
     * @param sectionId 服务人员服务时间段主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteServerTimeSectionBySectionId(Long sectionId)
    {
        ServerTimeSection serverTimeSection = serverTimeSectionMapper.selectServerTimeSectionBySectionId(sectionId);
        if (Objects.isNull(serverTimeSection)){
            throw new ServiceException("时间段不存在或已被删除");
        }
        int result = serverTimeSectionMapper.deleteServerTimeSectionBySectionId(sectionId);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateServerTimeSectionVo(ServerTimeSectionVo serverTimeSection) {
        // 校验所添加的时间段是否存在交叉重复
        if (isTimeSectionRepeatAndCross(serverTimeSection)) {
            return AjaxResult.error("修改的服务时间不能存在交叉重复!");
        }
        serverTimeSection.setUpdateTime(LocalDateTime.now());
        serverTimeSection.setUpdateBy(serverTimeSection.getServerId());
        serverTimeSectionMapper.updateServerTimeSectionVo(serverTimeSection);
        merchantServerTimeService.generateBookTimes(Long.valueOf(serverTimeSection.getServerId()), serverTimeSection.getCurrentUser());
        return AjaxResult.success("修改成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult insertServerTimeSectionVo(ServerTimeSectionVo serverTimeSection) {
        // 校验所添加的时间段是否存在交叉重复
        if (isTimeSectionRepeatAndCross(serverTimeSection)) {
            return AjaxResult.error("添加的服务时间不能存在交叉重复!");
        }
        serverTimeSection.setDelFlag("0");
        serverTimeSection.setCreateBy(serverTimeSection.getServerId());
        serverTimeSection.setCreateTime(LocalDateTime.now());
        serverTimeSection.setUpdateTime(LocalDateTime.now());
        serverTimeSection.setUpdateBy(serverTimeSection.getServerId());
        serverTimeSectionMapper.insertServerTimeSectionVo(serverTimeSection);
        merchantServerTimeService.generateBookTimes(Long.valueOf(serverTimeSection.getServerId()), serverTimeSection.getCurrentUser());
        return AjaxResult.success("新增成功");
    }

    /**
     * 校验服务人员设置工作时间段不能重复
     *
     * @param serverTimeSectionVo
     * @return
     */
    private boolean isTimeSectionRepeatAndCross(ServerTimeSectionVo serverTimeSectionVo) {
        if (Objects.isNull(serverTimeSectionVo)
                || StringUtils.isBlank(serverTimeSectionVo.getServerId())
                || StringUtils.isBlank(serverTimeSectionVo.getHoursFromString())
                || StringUtils.isBlank(serverTimeSectionVo.getHoursEndString())) {
            return false;
        }
        // 查询该服务人员所有服务时间段
        ServerTimeSection queryParam = new ServerTimeSection();
        queryParam.setServerId(serverTimeSectionVo.getServerId());
        List<ServerTimeSection> serverTimeSectionList = serverTimeSectionMapper.selectServerTimeSectionList(queryParam);
        if (CollectionUtils.isEmpty(serverTimeSectionList)) {
            return false;
        }
        // 校验时间段是否存在交叉重复
        for (ServerTimeSection serverTimeSection : serverTimeSectionList) {
            if (Objects.equals(serverTimeSection.getSectionId(), serverTimeSectionVo.getSectionId())) {
                // 遇到原时间段，则跳过不校验
                continue;
            }
            String originalWeeks = serverTimeSection.getWeeks();
            String addWeeks = serverTimeSectionVo.getWeeks();
            String originalFrom = DateUtils.formatDate(new Date(), "yyyy-MM-dd") + ' ' + serverTimeSection.getHoursFrom() + ":00";
            String originalEnd = DateUtils.formatDate(new Date(), "yyyy-MM-dd") + ' ' + serverTimeSection.getHoursEnd() + ":00";
            String addFrom = DateUtils.formatDate(new Date(), "yyyy-MM-dd") + ' ' + serverTimeSectionVo.getHoursFromString() + ":00";
            String addEnd = DateUtils.formatDate(new Date(), "yyyy-MM-dd") + ' ' + serverTimeSectionVo.getHoursEndString() + ":00";
            String[] datePatternArr = {"yyyy-MM-dd HH:mm:ss"};
            Date originalFromDate = DateUtils.parseDate(originalFrom, datePatternArr);
            Date originalEndDate = DateUtils.parseDate(originalEnd, datePatternArr);
            Date addFromDate = DateUtils.parseDate(addFrom, datePatternArr);
            Date addEndDate = DateUtils.parseDate(addEnd, datePatternArr);
            boolean isTimeSectionRepeat = originalFromDate.equals(addFromDate) || originalEndDate.equals(addEndDate);
            boolean isTimeSectionCross = originalEndDate.after(addFromDate) && originalFromDate.before(addEndDate);
            if (originalWeeks.contains("0") && addWeeks.contains("0")) {
                if (isTimeSectionRepeat || isTimeSectionCross) {
                    return true;
                }
            } else if (originalWeeks.contains("1") && addWeeks.contains("1")) {
                if (isTimeSectionRepeat || isTimeSectionCross) {
                    return true;
                }
            } else if (originalWeeks.contains("2") && addWeeks.contains("2")) {
                if (isTimeSectionRepeat || isTimeSectionCross) {
                    return true;
                }
            } else if (originalWeeks.contains("3") && addWeeks.contains("3")) {
                if (isTimeSectionRepeat || isTimeSectionCross) {
                    return true;
                }
            } else if (originalWeeks.contains("4") && addWeeks.contains("4")) {
                if (isTimeSectionRepeat || isTimeSectionCross) {
                    return true;
                }
            } else if (originalWeeks.contains("5") && addWeeks.contains("5")) {
                if (isTimeSectionRepeat || isTimeSectionCross) {
                    return true;
                }
            } else if (originalWeeks.contains("6") && addWeeks.contains("6")) {
                if (isTimeSectionRepeat || isTimeSectionCross) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public List<ServerTimeSection> selectAllSectionBy(Integer dayOfWeek) {
        return serverTimeSectionMapper.selectAllSectionBy(dayOfWeek);
    }

    @Override
    public List<ServerTimeSection> selectSectionBy(Integer dayOfWeek, Long serverId) {
        return serverTimeSectionMapper.selectSectionBy(dayOfWeek, serverId);
    }
}
