package jnpf.attendance.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.google.common.collect.Maps;
import jnpf.attendance.mapper.AttendanceHolidaySettingMapper;
import jnpf.attendance.service.AttendanceGroupService;
import jnpf.attendance.service.AttendanceHolidaySettingService;
import jnpf.base.UserInfo;
import jnpf.base.service.SuperServiceImpl;
import jnpf.entity.AttendanceGroup;
import jnpf.entity.attendance.AttendanceHolidaySettingEntity;
import jnpf.model.attendance.dto.AttendanceHolidaySettingDto;
import jnpf.model.attendance.vo.AttendanceHolidaySettingVo;
import jnpf.util.RandomUtil;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 考勤配置-假日设置 服务实现类
 * </p>
 *
 * @author ahua
 * @since 2023-11-29
 */
@Service
@Slf4j
public class AttendanceHolidaySettingServiceImpl extends SuperServiceImpl<AttendanceHolidaySettingMapper, AttendanceHolidaySettingEntity> implements AttendanceHolidaySettingService {

    @Autowired
    private AttendanceGroupService attendanceGroupService;

    @Override
    public PageDTO<AttendanceHolidaySettingVo> page(String groupId, String name, Integer paidSalaryEnable, Integer page, Integer size) {
        List<AttendanceGroup> attendanceGroups = attendanceGroupService.queryDropList();
        Map<String, AttendanceGroup> collect = attendanceGroups.stream().collect(Collectors.toMap(AttendanceGroup::getId, group -> group));
        Map<String, String> groupIdToParent = attendanceGroups.stream().collect(Collectors.toMap(AttendanceGroup::getId, groupVo -> StringUtil.isBlank(groupVo.getParentId()) ? "-1" : groupVo.getParentId()));
        PageDTO<AttendanceHolidaySettingVo> attendanceFestivalSettingVoPageDTO = upPage(groupId, groupIdToParent, collect, name, paidSalaryEnable, page, size);
        if (Objects.isNull(attendanceFestivalSettingVoPageDTO)) {
            return new PageDTO<>(page, size);
        }
        return attendanceFestivalSettingVoPageDTO;
    }

    private PageDTO<AttendanceHolidaySettingVo> upPage(String groupId, Map<String, String> groupIdToParent, Map<String, AttendanceGroup> collect, String name, Integer paidSalaryEnable, Integer page, Integer size) {
        if (StringUtil.isEmpty(groupId)) {
            return null;
        }
        AttendanceGroup attendanceGroup = collect.get(groupId);
        if (Objects.isNull(attendanceGroup)) {
            return null;
        }
        if (Objects.equals(attendanceGroup.getHolidaySetting(), 1)) {
            PageDTO<AttendanceHolidaySettingEntity> page1 = lambdaQuery().eq(AttendanceHolidaySettingEntity::getGroupId, groupId)
                    .like(StringUtil.isNotEmpty(name), AttendanceHolidaySettingEntity::getName, name)
                    .eq(AttendanceHolidaySettingEntity::getDeleteMark, Boolean.FALSE)
                    .eq(Objects.nonNull(paidSalaryEnable), AttendanceHolidaySettingEntity::getPaidSalaryEnable, paidSalaryEnable)
                    .orderByAsc(AttendanceHolidaySettingEntity::getCreatorTime)
                    .page(new PageDTO(page, size));
            return (PageDTO<AttendanceHolidaySettingVo>) page1.convert(x -> BeanUtil.toBean(x, AttendanceHolidaySettingVo.class));
        }
        return upPage(groupIdToParent.get(groupId), groupIdToParent, collect, name, paidSalaryEnable, page, size);
    }

    @Override
    public AttendanceHolidaySettingVo getOne(String id) {
        return BeanUtil.toBean(getById(id), AttendanceHolidaySettingVo.class);
    }

    @Override
    public void del(String id) {
        lambdaUpdate().set(AttendanceHolidaySettingEntity::getDeleteMark, Boolean.TRUE)
                .set(AttendanceHolidaySettingEntity::getDeleteUserId, UserProvider.getLoginUserId())
                .set(AttendanceHolidaySettingEntity::getDeleteTime, new Date())
                .eq(AttendanceHolidaySettingEntity::getId, id)
                .update();
    }

    @Override
    public void initHolidaySetting(String groupId) {
        List<AttendanceHolidaySettingEntity> list = lambdaQuery().eq(AttendanceHolidaySettingEntity::getGroupId, groupId)
                .eq(AttendanceHolidaySettingEntity::getDeleteMark, Boolean.FALSE)
                .list();
        if (CollUtil.isNotEmpty(list)) {
            return;
        }
        List<AttendanceGroup> attendanceGroups = attendanceGroupService.queryDropList();
        Map<String, List<AttendanceHolidaySettingEntity>> enableBaseSetting = getAllFestivalSetting(CollUtil.newArrayList(groupId), attendanceGroups);
        List<AttendanceHolidaySettingEntity> attendanceBaseSettings = enableBaseSetting.get(groupId);
        if (CollUtil.isNotEmpty(attendanceBaseSettings)) {
            attendanceBaseSettings.forEach(attendanceBaseSetting -> {
                attendanceBaseSetting.setId(RandomUtil.uuId());
                attendanceBaseSetting.setGroupId(groupId);
                attendanceBaseSetting.setCreatorTime(new Date());
                attendanceBaseSetting.setCreatorUserId(UserProvider.getLoginUserId());
            });
            saveBatch(attendanceBaseSettings);
        }
    }

//    @Override
//    @Deprecated(since = "在2.0中已过期", forRemoval = true)
//    public void autoGrantBalance(String tenantId) {
//        log.error("开始假日自动发放劵");
//        List<AttendanceGroup> attendanceGroups = attendanceGroupService.queryDropList();
//        List<String> groupIds = attendanceGroups.stream().map(AttendanceGroup::getId).collect(Collectors.toList());
//        Map<String, List<AttendanceHolidaySettingEntity>> enableFestivalSetting = getEnableFestivalSetting(groupIds, attendanceGroups);
//        List<AttendanceGroupUser> attendanceGroupUsers = attendanceUserService.queryByUsersGroupIds(groupIds);
//        if (attendanceGroupUsers.isEmpty()){
//            return;
//        }
//        Map<String, List<AttendanceGroupUser>> collect = attendanceGroupUsers.stream().collect(Collectors.groupingBy(AttendanceGroupUser::getGroupId));
//        List<String> userIds = attendanceGroupUsers.stream().map(AttendanceGroupUser::getUserId).distinct().collect(Collectors.toList());
//        //查询工龄及司龄
//        List<QueryCompanyAgeDto> queryCompanyAgeDtos = ftbPersonnelsStaffRosterService.queryCompanyAge(userIds);
//        Map<String, QueryCompanyAgeDto> companyDtoMap = queryCompanyAgeDtos.stream().collect(Collectors.toMap(QueryCompanyAgeDto::getUserId, vo -> vo));
//        enableFestivalSetting.forEach((groupId, list) -> {
//            List<AttendanceGroupUser> attendanceGroupUsers1 = collect.get(groupId);
//            if (CollUtil.isEmpty(attendanceGroupUsers1)) {
//                return;
//            }
//            if (CollUtil.isEmpty(list)) {
//                return;
//            }
//            list.forEach(setting -> {
//                if (!Objects.equals(setting.getGiveType(), 1)) {
//                    return;
//                }
//                attendanceGroupUsers1.forEach(user -> {
//                    QueryCompanyAgeDto companyAge = companyDtoMap.get(user.getUserId());
//                    Date date = DateUtil.getDayBegin();
//                    Date dateByMonthAndDay;
//                    if (setting.getGiveDateType() == 1) {
//                        dateByMonthAndDay = DateDetail.getDateByMonthAndDay(date, date.getMonth() + 1, setting.getGiveDateDay());
//                    } else if (setting.getGiveDateType() == 2) {
//                        dateByMonthAndDay = DateDetail.getDateByMonthAndDay(date, setting.getGiveDateMonth(), setting.getGiveDateDay());
//                    } else if (setting.getGiveDateType() == 3) {
//                        //生日日期
//                        if (StringUtil.isEmpty(companyAge.getBirthday())) {
//                            return;
//                        }
//                        Date birthday = DateUtil.stringToDates(companyAge.getBirthday());
//                        dateByMonthAndDay = DateDetail.getDateByMonthAndDay(date, birthday.getMonth() + 1, cn.hutool.core.date.DateUtil.dayOfMonth(birthday));
//                    } else {
//                        //入职日期
//                        if (StringUtil.isEmpty(companyAge.getActualStartDate())) {
//                            return;
//                        }
//                        Date entryDate = DateUtil.stringToDates(companyAge.getActualStartDate());
//                        dateByMonthAndDay = DateDetail.getDateByMonthAndDay(date, entryDate.getMonth() + 1, cn.hutool.core.date.DateUtil.dayOfMonth(entryDate));
//                    }
//                    if (date.compareTo(dateByMonthAndDay) != 0) {
//                        return;
//                    }
//                    if (setting.getExpiresType() == 1) {
//                        Integer expiresDay = setting.getExpiresDayNumber();
//                        date = DateUtil.dateAddDays(date, expiresDay);
//                    } else if (Objects.equals(setting.getExpiresType(), 2)) {
//                        date = DateDetail.getDateByMonthAndDay(date, setting.getExpiresMonth(), setting.getExpiresDay());
//                    } else {
//                        date = null;
//                    }
//                    BigDecimal dayNum = new BigDecimal(setting.getDayNumber());
//                    if (Objects.equals(setting.getDayType(), 2)) {
//                        Long entryYear = Objects.isNull(companyAge) || companyAge.getConpanyAge() == 0 ? 0 :  companyAge.getConpanyAge()/ 365;
//                        Long workYear = Objects.isNull(companyAge) ? 0 : companyAge.getWorkerAge();
//                        dayNum = new BigDecimal(setting.getDayNumber() + workYear * setting.getYoeMultiple() + entryYear * setting.getYosMultiple());
//                    }
//                    log.error("考勤组[{}]人员[{}]假日[{}]自动发放劵[{}]", user.getGroupId(), user.getUserId(), setting.getName(), dayNum);
//                    attendanceBalanceRecordMapper.grantBalance(RandomUtil.uuId(), user.getUserId(), setting.getName(), dayNum, date, 2, 0, null, setting.getPaidSalaryEnable(), 2, setting.getId());
//                });
//            });
//        });
//        log.error("假日自动发放劵结束");
//    }
    @Override
    public Map<String, List<AttendanceHolidaySettingEntity>> getEnableFestivalSetting(List<String> groupIds, List<AttendanceGroup> attendanceGroupVos) {
        return getFestivalSetting(groupIds,attendanceGroupVos,Boolean.TRUE);
    }

    private Map<String, List<AttendanceHolidaySettingEntity>> getAllFestivalSetting(List<String> groupIds, List<AttendanceGroup> attendanceGroupVos) {
        return getFestivalSetting(groupIds,attendanceGroupVos,Boolean.FALSE);
    }

    private Map<String, List<AttendanceHolidaySettingEntity>> getFestivalSetting(List<String> groupIds, List<AttendanceGroup> attendanceGroupVos, Boolean isFilterDisable) {
        List<AttendanceHolidaySettingEntity> list = lambdaQuery().eq(isFilterDisable,AttendanceHolidaySettingEntity::getEnable, Boolean.TRUE)
                .eq(AttendanceHolidaySettingEntity::getDeleteMark, Boolean.FALSE)
                .list();
        Map<String, Boolean> collect1 = attendanceGroupVos.stream().collect(Collectors.toMap(AttendanceGroup::getId, group -> group.getHolidaySetting() == 1));
        Map<String, List<AttendanceHolidaySettingEntity>> collect = list.stream().filter(base -> collect1.getOrDefault(base.getGroupId(), Boolean.FALSE)).collect(Collectors.groupingBy(AttendanceHolidaySettingEntity::getGroupId));
        Map<String, List<AttendanceHolidaySettingEntity>> map = Maps.newHashMap();
        Map<String, String> groupIdToParent = attendanceGroupVos.stream().collect(Collectors.toMap(AttendanceGroup::getId, groupVo -> StringUtil.isBlank(groupVo.getParentId()) ? "-1" : groupVo.getParentId()));
        groupIds.forEach(groupId -> map.put(groupId, findNextBaseSetting(collect, groupIdToParent, groupId)));
        return map;
    }

    private List<AttendanceHolidaySettingEntity> findNextBaseSetting(Map<String, List<AttendanceHolidaySettingEntity>> collect, Map<String, String> groupIdToParent, String groupId) {
        if (StringUtil.isBlank(groupId)) {
            return CollUtil.newArrayList();
        }
        if (!collect.containsKey(groupId)) {
            return findNextBaseSetting(collect, groupIdToParent, groupIdToParent.get(groupId));
        }
        return collect.get(groupId);
    }

    @Override
    public void save(AttendanceHolidaySettingDto dto) {
        AttendanceHolidaySettingEntity attendanceHolidaySettingEntity = BeanUtil.toBean(dto, AttendanceHolidaySettingEntity.class);
        UserInfo user = UserProvider.getUser();
        if (StringUtil.isEmpty(attendanceHolidaySettingEntity.getId())) {
            List<AttendanceHolidaySettingEntity> list = lambdaQuery()
                    .eq(AttendanceHolidaySettingEntity::getName, dto.getName())
                    .eq(AttendanceHolidaySettingEntity::getGroupId,dto.getGroupId())
                    .eq(AttendanceHolidaySettingEntity::getDeleteMark, Boolean.FALSE)
                    .list();
            Assert.isFalse(CollUtil.isNotEmpty(list),"假日名称不能重复");
            attendanceHolidaySettingEntity.setCreatorUserId(user.getUserId());
            attendanceHolidaySettingEntity.setCreatorTime(new Date());
            attendanceHolidaySettingEntity.setTenantId(user.getTenantId());
        } else {
            attendanceHolidaySettingEntity.setLastModifyTime(new Date());
            attendanceHolidaySettingEntity.setLastModifyUserId(user.getUserId());
        }
        saveOrUpdate(attendanceHolidaySettingEntity);
    }

    @Override
    public void changeStatus(String id, Integer enable) {
        lambdaUpdate().eq(AttendanceHolidaySettingEntity::getId, id)
                .set(AttendanceHolidaySettingEntity::getEnable, enable)
                .update();
    }
}
