package jnpf.attendance.service.handle.notice;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jnpf.attendance.antifreeze.UserAntifreeze;
import jnpf.attendance.service.AttendanceShiftNameSettingService;
import jnpf.attendance.service.AttendanceShiftSettingPeriodService;
import jnpf.base.UserInfo;
import jnpf.constants.AttendanceConstant;
import jnpf.entity.attendance.AttendanceShiftNameEntity;
import jnpf.entity.attendance.AttendanceShiftSettingPeriodEntity;
import jnpf.enums.attendance.AttendanceTypeEnum;
import jnpf.enums.attendance.NoticeModuleEnum;
import jnpf.enums.attendance.UserSettingEnum;
import jnpf.model.attendance.model.JumpUrl;
import jnpf.model.attendance.model.ShiftChangModel;
import jnpf.model.attendance.model.ShiftChangeNoticeModel;
import jnpf.model.attendance.model.SystemNoticeStrategy;
import jnpf.model.attendance.vo.AttendanceShiftSettingPeriodVo;
import jnpf.model.attendance.vo.DailyRuleResultVo;
import jnpf.permission.model.user.PartUserInfoVo;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

import static jnpf.constants.AttendanceConstant.*;

@Component(AttendanceConstant.SHIFT_CHANG)
@Slf4j
public class ShiftChangAttendanceNotice implements AttendanceNotice<ShiftChangModel, ShiftChangeNoticeModel> {
    @Autowired
    private UserAntifreeze userAntifreeze;
    @Autowired
    private AttendanceShiftNameSettingService attendanceShiftNameSettingService;
    @Autowired
    private AttendanceShiftSettingPeriodService attendanceShiftSettingPeriodService;
    @Autowired
    private AttendanceNoticeHandler attendanceNoticeHandler;

    @Override
    public Boolean isPass(ShiftChangeNoticeModel attendanceNoticeModel) {
        return attendanceNoticeHandler.checkBeforeCondition(attendanceNoticeModel.getUserId(), UserSettingEnum.ATTENDANCE_SETTING_MESSAGE_RECEIVE,
                UserSettingEnum.ATTENDANCE_SETTING_CLASS_CHANGE_REMINDER);
    }

    @Override
    public List<ShiftChangModel> generatingData(ShiftChangeNoticeModel attendanceNoticeModel) {
        List<ShiftChangModel> shiftChangModels = CollUtil.newArrayList();
        //查询时段数据
        List<DailyRuleResultVo> dailyRuleResultVos = attendanceNoticeModel.getDailyRuleResultVos();
        List<String> collect = dailyRuleResultVos.stream().map(DailyRuleResultVo::getFromShiftId).filter(StringUtil::isNotEmpty).collect(Collectors.toList());
        List<String> collect1 = dailyRuleResultVos.stream().map(DailyRuleResultVo::getToShiftId).filter(StringUtil::isNotEmpty).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(collect1)) {
            collect.addAll(collect1);
        }
        List<AttendanceShiftSettingPeriodEntity> list1 = CollUtil.isEmpty(collect1) ? CollUtil.newArrayList() : attendanceShiftSettingPeriodService.list(new LambdaQueryWrapper<AttendanceShiftSettingPeriodEntity>()
                .in(AttendanceShiftSettingPeriodEntity::getShiftId, collect1).eq(AttendanceShiftSettingPeriodEntity::getDeleteMark, Boolean.FALSE));
        List<AttendanceShiftSettingPeriodVo> attendanceShiftSettingPeriodVos = BeanUtil.copyToList(list1, AttendanceShiftSettingPeriodVo.class);
        Map<String, List<AttendanceShiftSettingPeriodVo>> periodMap = attendanceShiftSettingPeriodVos.stream().collect(Collectors.groupingBy(AttendanceShiftSettingPeriodVo::getShiftId));
        List<AttendanceShiftNameEntity> attendanceShiftNameEntities = CollUtil.isEmpty(collect) ? CollUtil.newArrayList() : attendanceShiftNameSettingService.listByIds(collect);
        Map<String, AttendanceShiftNameEntity> shiftMap = attendanceShiftNameEntities.stream().collect(Collectors.toMap(AttendanceShiftNameEntity::getId, entity -> entity));
        dailyRuleResultVos.stream().collect(Collectors.groupingBy(DailyRuleResultVo::getDate)).forEach((day, dailyRuleVos) -> {
            //旧班次名称
            String oldShiftName = "";
            //新班次名称
            String newShiftName = "";
            //新班次时间
            String newShift = "";

            Map<Integer, List<DailyRuleResultVo>> collect2 = dailyRuleVos.stream()
                    .sorted(Comparator.comparing(vo -> Objects.isNull(vo.getToSchedulesType()) ? 1 : vo.getToSchedulesType()))
                    .collect(Collectors.groupingBy(vo -> Objects.isNull(vo.getToSchedulesType()) ? 1 : vo.getToSchedulesType()));
            int size = collect2.size();
            int i = 0;
            for (Map.Entry<Integer, List<DailyRuleResultVo>> stringListEntry : collect2.entrySet()) {
                DailyRuleResultVo dailyRuleVo = stringListEntry.getValue().get(0);
                AttendanceShiftNameEntity toShiftEntity = shiftMap.getOrDefault(dailyRuleVo.getToShiftId(), null);
                newShiftName += (newShiftName.length() > 0 ? " | " : "") + (Objects.equals(dailyRuleVo.getToType(), AttendanceTypeEnum.ORDINARY.getCode()) ? Objects.isNull(toShiftEntity) ? "" : toShiftEntity.getShortName() : Objects.isNull(dailyRuleVo.getToType()) ? "" : AttendanceTypeEnum.getMsg(dailyRuleVo.getToType()));
                List<AttendanceShiftSettingPeriodVo> attendanceShiftSettingPeriodVos1 = periodMap.get(dailyRuleVo.getToShiftId());
                if (CollUtil.isEmpty(attendanceShiftSettingPeriodVos1) || !Objects.equals(dailyRuleVo.getToType(), AttendanceTypeEnum.ORDINARY.getCode())) {
                    i++;
                    continue;
                }
                if (size < 2) {
                    for (AttendanceShiftSettingPeriodVo attendanceShiftSettingPeriodVo : attendanceShiftSettingPeriodVos1) {
                        newShift += (newShift.length() > 0 ? " | " : "") + attendanceShiftSettingPeriodVo.getInPoint() + "至" + attendanceShiftSettingPeriodVo.getOutPoint();
                    }
                    continue;
                }
                if (i == 0) {
                    AttendanceShiftSettingPeriodVo attendanceShiftSettingPeriodVo = attendanceShiftSettingPeriodVos1.stream().findFirst().orElse(null);
                    newShift = attendanceShiftSettingPeriodVo.getInPoint() + "至" + attendanceShiftSettingPeriodVo.getOutPoint();
                } else {
                    AttendanceShiftSettingPeriodVo attendanceShiftSettingPeriodVo = attendanceShiftSettingPeriodVos1.stream().reduce((p1, p2) -> p2).orElse(null);
                    newShift += (newShift.length() > 0 ? " | " : "") + attendanceShiftSettingPeriodVo.getInPoint() + "至" + attendanceShiftSettingPeriodVo.getOutPoint();
                }
                i++;
            }
            Map<Integer, List<DailyRuleResultVo>> collect3 = dailyRuleVos.stream()
                    .sorted(Comparator.comparing(vo -> Objects.isNull(vo.getFromSchedulesType()) ? 1 : vo.getFromSchedulesType()))
                    .collect(Collectors.groupingBy(vo -> Objects.isNull(vo.getFromSchedulesType()) ? 1 : vo.getFromSchedulesType()));
            for (Map.Entry<Integer, List<DailyRuleResultVo>> stringListEntry : collect3.entrySet()) {
                DailyRuleResultVo dailyRuleVo = stringListEntry.getValue().stream().findFirst().orElse(null);
                if (collect2.containsKey(stringListEntry.getKey())) {
                    List<DailyRuleResultVo> dailyRuleResultVos1 = collect2.get(stringListEntry.getKey());
                    List<DailyRuleResultVo> collect4 = dailyRuleResultVos1.stream().filter(result -> StringUtil.equals(result.getToId(), dailyRuleVo.getFromId())).collect(Collectors.toList());
                    if (CollUtil.isNotEmpty(collect4)) {
                        continue;
                    }
                }

                AttendanceShiftNameEntity fromShiftEntity = shiftMap.getOrDefault(dailyRuleVo.getFromShiftId(), null);
                oldShiftName += (oldShiftName.length() > 0 ? " | " : "") + (Objects.equals(dailyRuleVo.getFromType(), AttendanceTypeEnum.ORDINARY.getCode()) && Objects.nonNull(fromShiftEntity) ? fromShiftEntity.getShortName() : Objects.isNull(dailyRuleVo.getFromType()) ? "" : AttendanceTypeEnum.getMsg(dailyRuleVo.getFromType()));
            }
            shiftChangModels.add(ShiftChangModel.builder().day(day).oldShiftName(oldShiftName).newShiftName(newShiftName).newShift(newShift).build());
        });
        return shiftChangModels.stream().sorted(Comparator.comparing(ShiftChangModel::getDay)).collect(Collectors.toList());
    }

    @Override
    public List<String> getRecipient(ShiftChangeNoticeModel attendanceNoticeModel) {
        return CollUtil.newArrayList(attendanceNoticeModel.getUserId());
    }

    @Override
    public SystemNoticeStrategy setSystemNoticeStrategy(ShiftChangeNoticeModel attendanceNoticeModel, String noticeId) {
        ArrayList<JumpUrl> objects = CollUtil.newArrayList();
        objects.add(JumpUrl.builder().url(String.format(ATTENDANCE_NOTICE_SHIFT_CHANGE_DETAIL_URL, noticeId)).urlName(ATTENDANCE_NOTICE_DETAIL_BUTTON_NAME).color(COLOR_BLACK).build());
        objects.add(JumpUrl.builder().url(ATTENDANCE_NOTICE_CLICK_URL).urlName(ATTENDANCE_NOTICE_TO_CLICK).color(COLOR_BLUE).build());
        return SystemNoticeStrategy.builder()
                .title(ATTENDANCE_NOTICE_SHIFT_CHANGE_TITLE)
                .noticeModuleEnum(NoticeModuleEnum.BC_BD)
                .jumpUrls(objects)
                .build();
    }

    @Override
    public String getContext(List<ShiftChangModel> data) {
        if (CollUtil.isEmpty(data)) {
            return null;
        }
        UserInfo user = UserProvider.getUser();
        List<PartUserInfoVo> allByIds = userAntifreeze.getAllByIds(CollUtil.newArrayList(user.getUserId()), user.getTenantId());
        if (CollUtil.isEmpty(allByIds)) {
            log.error("请求用户服务失败或者未查询到当前用户数据：{}", user.getUserId());
            return null;
        }
        PartUserInfoVo partUserInfoVo = allByIds.stream().findFirst().orElse(null);
        StringBuffer stringBuffer = new StringBuffer();
        if (Objects.isNull(partUserInfoVo)) {
            stringBuffer.append("操作人：无</br>");
        } else {
            stringBuffer.append("操作人：").append(partUserInfoVo.getRealName()).append("(").append(StringUtil.isEmpty(partUserInfoVo.getOrganizeName()) ? "暂无" : partUserInfoVo.getOrganizeName()).append("-").append(StringUtil.isEmpty(partUserInfoVo.getPositionName()) ? "暂无" : partUserInfoVo.getPositionName()).append(")</br>");
        }
        if (data.size() > 1) {
            stringBuffer.append("变更日期：").append(StringUtil.join(data.stream().map(shiftChangModel1 -> DateUtil.format(shiftChangModel1.getDay(), "yyyy.MM.dd")).collect(Collectors.toList()), "、")).append("</br>");
            return stringBuffer.toString();
        }
        ShiftChangModel shiftChangModel = data.stream().findFirst().orElse(null);
        stringBuffer.append("变更日期：").append(DateUtil.format(shiftChangModel.getDay(), "yyyy.MM.dd")).append("</br>");
        stringBuffer.append("新班次名称：").append(StringUtil.isEmpty(shiftChangModel.getNewShiftName()) ? "无" : shiftChangModel.getNewShiftName()).append("</br>");
        stringBuffer.append("新班次时间：").append(StringUtil.isEmpty(shiftChangModel.getNewShift()) ? "无" : shiftChangModel.getNewShift());
        return stringBuffer.toString();
    }

}
