package jnpf.attendance.service.handle.notice;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import jnpf.attendance.antifreeze.UserAntifreeze;
import jnpf.attendance.service.AttendanceUserSettingService;
import jnpf.base.UserInfo;
import jnpf.constants.AttendanceConstant;
import jnpf.enums.attendance.*;
import jnpf.model.attendance.model.JumpUrl;
import jnpf.model.attendance.model.ShiftChangModel;
import jnpf.model.attendance.vo.attendance.ApproveBaseImVo;
import jnpf.model.attendance.vo.attendance.ApproveImVo;
import jnpf.model.attendance.model.SystemNoticeStrategy;
import jnpf.model.attendance.vo.UserSettingVo;
import jnpf.permission.model.user.PartUserInfoVo;
import jnpf.util.DateDetail;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

import static jnpf.constants.AttendanceConstant.*;

/**
 * @Author huanglinpan
 * @Date 2024/8/12 10:58
 * @Version 1.0 （版本号）
 */
@Component(AttendanceConstant.APPROVE)
@Slf4j
public class AttendanceApproveNotice implements AttendanceNotice<ApproveBaseImVo,ApproveImVo>{

    @Resource
    private AttendanceUserSettingService attendanceUserSettingService;

    @Override
    public Boolean isPass(ApproveImVo approveImVo) {
        if (!approveImVo.getAttendanceNoticeEnum().equals(AttendanceNoticeEnum.APPROVE) && !approveImVo.getAttendanceNoticeEnum().equals(AttendanceNoticeEnum.JOIN_GROUP)) {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    @Override
    public List<ApproveBaseImVo> generatingData(ApproveImVo approveImVo) {
        List<ApproveBaseImVo> list = new ArrayList<>();
        list.add(approveImVo.getApproveBaseImVo());
        return list;
    }

    @Override
    public List<String> getRecipient(ApproveImVo approveImVo) {
        List<String> list = checkSetting(approveImVo.getUserIds(),UserSettingEnum.ATTENDANCE_SETTING_MESSAGE_RECEIVE.getCode());
        if(null !=  approveImVo.getType() && Objects.equals(AttendanceNoticeEnum.JOIN_GROUP.getCode(), approveImVo.getType())) {
            // 处理被借调人信息
            return checkSetting(list,UserSettingEnum.ATTENDANCE_SETTING_ATTENDANCE_GROUP_JOIN_LEAVE_REMINDER.getCode());
        }
        return list;
    }

    @NotNull
    private List<String> checkSetting(List<String> userIds, String code) {
        // 校验接收人是否打开配置
        List<UserSettingVo> settingList = attendanceUserSettingService.getSettingList(userIds, UserSettingTypeEnum.USER.getCode(), code);
        Map<String, UserSettingVo> map = settingList.stream().collect(Collectors.toMap(UserSettingVo::getAssociationId, Function.identity()));
        List<String> list = new ArrayList<>();
        userIds.forEach(id -> {
            UserSettingVo userSettingVo = map.get(id);
            if (null == userSettingVo) {
                list.add(id);
            }else {
                // 检查是否打开
                if (1 == userSettingVo.getStatus()) {
                    list.add(id);
                }
            }
        });
        return list;
    }

    @Override
    public SystemNoticeStrategy setSystemNoticeStrategy(ApproveImVo approveImVo, String noticeId) {
        ArrayList<JumpUrl> objects = CollUtil.newArrayList();
        // 特殊处理借调审批被借调用户看到的URL的参数
        log.error("noticeId:{},approveImVo.getApproveBaseImVo().getUrl():{}",noticeId,approveImVo.getApproveBaseImVo().getUrl());
        String url = APPROVE_SECONDED_URL.equals(approveImVo.getApproveBaseImVo().getUrl()) ? String.format(APPROVE_SECONDED_URL, noticeId) :  approveImVo.getApproveBaseImVo().getUrl();
        log.error("url:{}",url);
        objects.add(JumpUrl.builder().url(url).urlName(ATTENDANCE_NOTICE_DETAIL_BUTTON_NAME).color(COLOR_BLACK).build());
        return SystemNoticeStrategy.builder()
                .title(approveImVo.getApproveBaseImVo().getTitle())
                .noticeModuleEnum(NoticeModuleEnum.KQ_SP)
                .jumpUrls(objects)
                .build();
    }

    @Override
    public String getContext(List<ApproveBaseImVo> data) {
        if (CollUtil.isEmpty(data)) {
            return null;
        }
        ApproveBaseImVo approveBaseImVo = data.get(0);
        // 通过/拒绝的消息有操作者
        String startStr = null != approveBaseImVo.getCreateUserName() ? "操作者：" + approveBaseImVo.getCreateUserName() + "</br>": "";
        if (Objects.equals(ApprovalSettingTypeEnum.LEAVE.getCode(), approveBaseImVo.getType())){
            //开始时间：2024年5月16日 16:23
            //结束时间：2024年5月17日 09:00
            // 考勤V1.6 加入请假类型 小时类维持以上不变，天类： 开始时间：2024年5月16日 结束时间：2024年5月17日   半天类：2024年5月16日 上半天 结束时间：2024年5月17日 下半天
            Integer unit = approveBaseImVo.getUnit();
            if (LeaveUnitEnum.HOUR.getCode().equals(unit)){
                return  startStr +
                        "开始时间：" + DateUtil.format(approveBaseImVo.getStartTime(), "yyyy-MM-dd HH:mm") + "</br>" +
                        "结束时间：" + DateUtil.format(approveBaseImVo.getEndTime(), "yyyy-MM-dd HH:mm");
            }else if (LeaveUnitEnum.DAY.getCode().equals(unit)){
                return  startStr +
                        "开始时间：" + DateUtil.format(approveBaseImVo.getStartTime(), "yyyy-MM-dd") + "</br>" +
                        "结束时间：" + DateUtil.format(approveBaseImVo.getEndTime(), "yyyy-MM-dd");
            }else {
                return startStr +
                        "开始时间：" + DateUtil.format(approveBaseImVo.getStartTime(), "yyyy-MM-dd ") + dayStr(approveBaseImVo.getStartTimeType()) + "</br>" +
                        "结束时间：" + DateUtil.format(approveBaseImVo.getEndTime(), "yyyy-MM-dd ")+ dayStr(approveBaseImVo.getEndTimeType());
            }
        }
        if (Objects.equals(ApprovalSettingTypeEnum.OVERTIME.getCode(), approveBaseImVo.getType())){
            //选择日期：2024年5月16日
            //开始时间：22:00
            //结束时间：次日08:00
            // 结束时间次日处理
            StringBuffer end = new StringBuffer();
            if (!DateUtil.format(approveBaseImVo.getStartTime(), "yyyy-MM-dd").equals(DateUtil.format(approveBaseImVo.getEndTime(), "yyyy-MM-dd"))){
                end.append("次日");
            }
            end.append(DateUtil.format(approveBaseImVo.getEndTime(), "HH:mm")).append("</br>");
            return  startStr +
                    "选择日期：" + DateUtil.format(approveBaseImVo.getStartTime(), "yyyy-MM-dd") + "</br>" +
                    "开始时间：" + DateUtil.format(approveBaseImVo.getStartTime(), "HH:mm") + "</br>" +
                    "结束时间：" + end;
        }
        if (Objects.equals(ApprovalSettingTypeEnum.GO_OUT.getCode(), approveBaseImVo.getType())){
            //开始时间：2024年5月16日
            //结束时间：2024年5月17日
            //时长：2天
            return  startStr +
                    "开始时间：" + DateUtil.format(approveBaseImVo.getStartTime(), "yyyy-MM-dd") + "</br>" +
                    "结束时间：" + DateUtil.format(approveBaseImVo.getEndTime(), "yyyy-MM-dd") + "</br>" +
                    "时长：" + approveBaseImVo.getDuration();
        }

        if (Objects.equals(ApprovalSettingTypeEnum.BUSINESS_TRIP.getCode(), approveBaseImVo.getType())){
            // 出发地：地点名称地点名称地点名称地点名称
            //目的地：地点名称地点名称地点名称地点名称
            return  startStr +
                    "出发地：" + approveBaseImVo.getDeparture() + "</br>" +
                    "目的地：" + approveBaseImVo.getDestination();
        }

        if (Objects.equals(ApprovalSettingTypeEnum.SECONDED.getCode(), approveBaseImVo.getType())){
            //借调开始时间：2024年5月16日 16:23
            //借调结束时间：2024年5月17日 09:00
            //借调考勤组：小露测试考勤组
            //被借调考勤组：小露验收考勤组
            return  startStr +
                    "借调开始时间：" + DateUtil.format(approveBaseImVo.getStartTime(), "yyyy-MM-dd HH:mm") + "</br>" +
                    "借调结束时间：" + DateUtil.format(approveBaseImVo.getEndTime(), "yyyy-MM-dd HH:mm") + "</br>" +
                    "借调考勤组：" + approveBaseImVo.getGroupName()  + "</br>" +
                    "被借调考勤组：" + approveBaseImVo.getSecondedGroupName();
        }
        if (Objects.equals(ApprovalSettingTypeEnum.OUT.getCode(), approveBaseImVo.getType())) {

            return startStr
                    + "发起时间：" + DateDetail.getDate2Str(approveBaseImVo.getCreateTime(), DateDetail.DF20) + "</br>"
                    + "考勤点：" + approveBaseImVo.getAddress();
        }
        if (Objects.equals(ApprovalSettingTypeEnum.ROUTINE.getCode(), approveBaseImVo.getType())) {

            String str = startStr + "补卡时间：" + approveBaseImVo.getRuleTime() + "</br>";
            if (StringUtils.isEmpty(startStr)) {
                str += "出勤结果：" + approveBaseImVo.getResult();
            }
            return str;
        }
        if (Objects.equals(ApprovalSettingTypeEnum.ACTION_RESULT.getCode(), approveBaseImVo.getType())) {

            return startStr
                    + "变更人员：" + approveBaseImVo.getSecondedUsersName() + "</br>"
                    + "变更时间：" + approveBaseImVo.getRuleTime() + "</br>"
                    + "出勤结果：" + approveBaseImVo.getAfterResult() + "</br>"
                    + "处理结果：" + approveBaseImVo.getResult();
        }
        return null;
    }

    private static String dayStr(Integer type) {
        if (1 == type){
            return "上半天";
        }else {
            return "下半天";
        }
    }


}
