package com.cpop.oam.business.service.impl;

import com.cpop.api.tencent.wxWork.handler.WebHookSendHandler;
import com.cpop.common.utils.DateUtils;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.utils.SpringUtils;
import com.cpop.oam.business.bo.DutyBo;
import com.cpop.oam.business.bo.DutyListBo;
import com.cpop.oam.business.dto.StaffDto;
import com.cpop.oam.business.entity.Duty;
import com.cpop.oam.business.entity.Staff;
import com.cpop.oam.business.mapper.DutyMapper;
import com.cpop.oam.business.service.DutyService;
import com.cpop.oam.business.service.StaffService;
import com.cpop.oam.business.vo.DutyListVo;
import com.cpop.oam.framework.constant.WebHookKeyConstant;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.DbChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.sql.Date;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

import static com.cpop.core.base.table.table.SysUserTableDef.SYS_USER;
import static com.cpop.oam.business.entity.table.DutyTableDef.DUTY;
import static com.cpop.oam.business.entity.table.StaffTableDef.STAFF;

/**
 * 值班表 服务层实现。
 *
 * @author DB
 * @since 2023-09-14
 */
@Service("oamDutyService")
public class DutyServiceImpl extends ServiceImpl<DutyMapper, Duty> implements DutyService {

    @Autowired
    private WebHookSendHandler webHookSendHandler;

    /**
     * @Description: 查询值班列表(当月)
     * @param bo 请求参数
     * @return: R<List<DutyListVo>>
     * @Author: DB
     * @Date: 2023/5/11 16:39
     **/
    @Override
    public List<DutyListVo> getDutyList(DutyListBo bo) {
        //默认查询当月
        LocalDate date;
        if (StringUtils.isNotBlank(bo.getDutyMoth())) {
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            date = LocalDate.parse(bo.getDutyMoth() + "-15", df);
        } else {
            date = LocalDate.now();
        }
        // 获取目标月的第一天
        LocalDate firstDay = date.with(TemporalAdjusters.firstDayOfMonth());
        // 获取目标月的最后一天
        LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth());
        List<DutyListVo> list = this.listAs(QueryWrapper.create()
                        .select(DUTY.ID, DUTY.DUTY_DATE, DUTY.SERVICE_STAFF_ID, DUTY.TECHNOLOGY_STAFF_ID)
                        .where(DUTY.DUTY_DATE.ge(firstDay).and(DUTY.DUTY_DATE.le(lastDay))),
                DutyListVo.class);
        if (list.isEmpty()){
            return list;
        }
        //需要额外查询出员工信息
        Set<String> staffIds = list.stream().map(DutyListVo::getServiceStaffId).collect(Collectors.toSet());
        Set<String> technologyStaffIds = list.stream().map(DutyListVo::getTechnologyStaffId).collect(Collectors.toSet());
        staffIds.addAll(technologyStaffIds);
        Map<String, String> staffMap = SpringUtils.getBean(StaffService.class).listByIds(staffIds)
                .stream().collect(Collectors.toMap(Staff::getId, Staff::getName));
        list.forEach(item->{
            item.setServiceStaffName(staffMap.get(item.getServiceStaffId()));
            item.setTechnologyStaffName(staffMap.get(item.getTechnologyStaffId()));
        });
        return list;
        //查询过多
        /*return this.mapper.selectListByQueryAs(QueryWrapper.create()
                        .select(DUTY.ID, DUTY.DUTY_DATE, DUTY.SERVICE_STAFF_ID, DUTY.TECHNOLOGY_STAFF_ID)
                        .where(DUTY.DUTY_DATE.ge(firstDay).and(DUTY.DUTY_DATE.le(lastDay))),
                DutyListVo.class,
                //服务人员名
                item -> item.field(DutyListVo::getServiceStaffName)
                        .queryWrapper(serviceStaffName -> queryChain().select(STAFF.NAME).from(STAFF).where(STAFF.ID.eq(serviceStaffName.getServiceStaffId()))),
                //技术人员名
                item -> item.field(DutyListVo::getTechnologyStaffName)
                        .queryWrapper(serviceStaffName -> queryChain().select(STAFF.NAME).from(STAFF).where(STAFF.ID.eq(serviceStaffName.getTechnologyStaffId()))));*/
    }

    /**
     * @Description: 新增值班
     * @param bo 请求参数
     * @return: R<Void>
     * @Author: DB
     * @Date: 2023/5/18 9:50
     **/
    @Override
    public void insertDuty(DutyBo bo) {
        //开始日期，结束日期
        String startDate = bo.getDutyDate().get(0);
        String endDate = bo.getDutyDate().get(1);
        List<String> dateList = DateUtils.getDatesBetweenTwoDatesT(Date.valueOf(startDate), Date.valueOf(endDate));
        //先删后存
        this.remove(QueryWrapper.create().where(DUTY.DUTY_DATE.ge(startDate).and(DUTY.DUTY_DATE.le(endDate))));
        List<Duty> entityList = new ArrayList<Duty>();
        dateList.forEach(item->{
            Duty entity = new Duty();
            entity.setDutyDate(LocalDate.parse(item))
                    .setServiceStaffId(bo.getServiceStaffId())
                    .setTechnologyStaffId(bo.getTechnologyStaffId());
            entityList.add(entity);
        });
        this.saveBatch(entityList);
    }

    /**
     * @descriptions 删除值班信息
     * @author DB
     * @date 2023/09/14 18:16
     * @param dutyDate 值班日期
     */
    @Override
    public void removeDutyByDate(String dutyDate) {
        this.remove(QueryWrapper.create().where(DUTY.DUTY_DATE.eq(dutyDate)));
    }

    /**
     * @descriptions 每天9点通知值班人员
     * @author DB
     * @date 2023/11/22 18:10
     * @return: void
     */
    @Override
    public void dutyNotice() {
        LocalDate now = LocalDate.now();
        //获取当天值班员工
        Duty one = this.queryChain().where(DUTY.DUTY_DATE.eq(now)).one();
        if (one != null) {
            //获取当天技术值班人员
            StaffDto staff = DbChain.table(SYS_USER).select(SYS_USER.PHONE_NUMBER, STAFF.NAME).from(SYS_USER)
                    .leftJoin(STAFF).on(STAFF.USER_ID.eq(SYS_USER.ID))
                    .where(STAFF.ID.eq(one.getTechnologyStaffId())).oneAs(StaffDto.class);
            //技术售后群提醒
            try {
                webHookSendHandler.webHookSendText(WebHookKeyConstant.ORDER_INFO_BOT, Collections.singletonList(staff.getPhoneNumber()),
                        "===今日值班" + staff.getName() + "==="
                        , false);
            } catch (IOException e) {
                throw new ServiceException(e.getMessage());
            }
        }
    }
}
