package com.jeeplus.pubmodules.holiday.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.pubmodules.holiday.domain.Holiday;
import com.jeeplus.pubmodules.holiday.mapper.HolidayMapper;
import com.jeeplus.pubmodules.holiday.service.dto.HolidayDTO;
import com.jeeplus.sys.domain.WorkAttachmentInfo;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.feign.IWorkAttachmentApi;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.utils.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.xml.crypto.Data;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;

@Service
public class HolidayService {

    @Resource
    private HolidayMapper holidayMapper;

    public IPage<HolidayDTO> findPageList(HolidayDTO holidayDTO, Page<HolidayDTO> page) throws Exception {
        QueryWrapper<HolidayDTO> queryWrapper = QueryWrapperGenerator.buildQueryCondition(holidayDTO, HolidayDTO.class);
        queryWrapper.eq("a.del_flag",0);
        //请假类型
        if (StringUtils.isNotBlank(holidayDTO.getType())){
            queryWrapper.eq("a.type",holidayDTO.getType());
        }
        //请假人
        if (StringUtils.isNotBlank(holidayDTO.getCreateById())){
            queryWrapper.eq("a.create_by_id",holidayDTO.getCreateById());
        }
        //申请人部门
        if (StringUtils.isNotBlank(holidayDTO.getOfficeId())){
            queryWrapper.eq("so.id",holidayDTO.getOfficeId());
        }
        //申请时间
        if (holidayDTO.getDates() != null && holidayDTO.getDates().length > 0) {
            queryWrapper.between("a.start_day", holidayDTO.getDates()[0], holidayDTO.getDates()[1]);
        }
        IPage<HolidayDTO> pageList=holidayMapper.findPageList(queryWrapper,page);
        return pageList;
    }

    /**
     * 根据id查询数据
     * @param id
     * @return
     */
    public HolidayDTO findById(String id) {
        HolidayDTO holidayDTO=holidayMapper.findById(id);
        // 查询附件信息
        List<WorkAttachmentInfo> files = holidayMapper.findDtos(id);
        if (CollectionUtils.isNotEmpty(files)) {
            for (WorkAttachmentInfo i : files) {
                i.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(i.getBy()));
            }
            holidayDTO.setFiles(files);
        }
        return holidayDTO;
    }

    /**
     * 校验年假
     * @param holidayDTO
     * @return
     */
    public String checkType(HolidayDTO holidayDTO) {
        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken());
        //获取当前登录人入职时间
        HolidayDTO dto=holidayMapper.findByUserId(userDTO.getId());
        //判断当前登录人是否有入职时间
        if (ObjectUtils.isNotEmpty(dto)){
            Date date=dto.getContractStartDate();
            LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            LocalDate intime = LocalDate.of(localDate.getYear(), localDate.getMonth(), localDate.getDayOfMonth());
            //当前时间
            LocalDate now = LocalDate.now();
            //判断是否满一年
            long yearsPassed = ChronoUnit.YEARS.between(intime, now); // 计算经过的年数
            if (yearsPassed<1){
                return "入职不满一年,无法休年假";
            }
            //计算员工入职时间距离今年还剩多少天
            LocalDate inTime = LocalDate.of(now.getYear(), localDate.getMonth(), localDate.getDayOfMonth());
            LocalDate endDate = LocalDate.of(now.getYear(), 12, 31);
            long days = ChronoUnit.DAYS.between(inTime, endDate);
            //计算今年一共有多少天
            Calendar instance = Calendar.getInstance();
            instance.setTime(new Date());
            int daysInYear = instance.getActualMaximum(Calendar.DAY_OF_YEAR);
            //判断员工入职是否满10年
            long round=0;
            //员工请假时间
            double days1=0;
            if (ObjectUtil.isNotEmpty(holidayDTO.getDays())){
                days1=Double.parseDouble(holidayDTO.getDays());
            }else {
                return "请选择请假日期";
            }
            if (yearsPassed>=1 && yearsPassed<10){
                //(当年剩余的天数/当年一共天数)*5
                double yearDays=(double)days/daysInYear*5;
                round = Math.round(yearDays);
                if (days1>round){
                    return "已超出可休年假天数,当年可休年假天数为"+round+"天";
                }
            }else if (yearsPassed>=10){
                //(当年距离入职时间剩余的天数/当年一共天数)*10
                double yearDays=(double)days/daysInYear*10;
                round = Math.round(yearDays);
                if (days1>round){
                    return "已超出可休年假天数,当年可休年假天数为"+round+"天";
                }
            }
            //当前员工当年是否休过年假
            List<HolidayDTO> holidays = holidayMapper.selectByUserId(userDTO.getId());
            Double holiday=0.00;
            if (ObjectUtils.isNotEmpty(holidays)){
                for (HolidayDTO holiday1 : holidays) {
                    //获取已经休过的年假天数
                    holiday+=Double.parseDouble(holiday1.getDays());
                }
                //员工可休年假天数与已休年假天数比较 获取剩余年假天数
                double surplus=round-holiday;
                //如果剩余年假天数小于等于0
                if (surplus <= 0){
                    return "当年无剩余年假,无法再休年假";
                }else {
                    //判断本次年假天数是否大于剩余年假天数
                    if (days1>surplus){
                        return "本次年假时间超出剩余年假天数,剩余年假"+surplus+"天";
                    }
                }
            }else {
                //若当年未休过年假,则计算剩余年假
                holiday=round-days1;
                //如果剩余年假天数小于等于0
                if (holiday < 0){
                    return "已超出可休年假天数,可休年假天数"+holiday+"天";
                }
            }
            return "本次年假休息"+days1+"天,剩余年假"+holiday+"天";
        }
        return "您的入职信息不完善,请完善后再休年假";





    }

    /**
     * 新增或修改
     * @param holidayDTO
     * @return
     */
    public Holiday save(HolidayDTO holidayDTO) {
        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken());
        if (StringUtils.isNotBlank(holidayDTO.getId())){
            return update(holidayDTO,userDTO);
        }
        return add(holidayDTO,userDTO);
    }

    private Holiday update(HolidayDTO holidayDTO, UserDTO userDTO) {
        Holiday holiday = new Holiday();
        BeanUtils.copyProperties(holidayDTO,holiday);
        holiday.setUpdateById(userDTO.getId());
        holiday.setUpdateTime(new Date());
        holiday.setStartDay(holidayDTO.getStartDay());//开始日期
        holiday.setBeginTime(holidayDTO.getBeginTime());//开始时间
        holiday.setEndDay(holidayDTO.getEndDay());//结束日期
        holiday.setEndTime(holidayDTO.getEndTime());//结束时间
        holiday.setType(holidayDTO.getType());//请假类型
        holiday.setDays(holidayDTO.getDays());//请假时长
        holiday.setReason(holidayDTO.getReason());//请假原因
        holiday.setStatus(holidayDTO.getStatus());
        holidayMapper.updateByIdForApp(holiday);
        //修改附件
        if (CollectionUtils.isNotEmpty(holidayDTO.getFiles())){
            List<WorkAttachmentInfo> files = holidayDTO.getFiles();
            updateFiles(files, userDTO, holidayDTO.getId());
        }
        return holiday;
    }
    /**
     * 修改附件信息
     * @param list 待修改的附件列表
     * @param userDTO 当前登录用户
     * @param id 关联id
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateFiles(List<WorkAttachmentInfo> list, UserDTO userDTO, String id) {
        int j = 1;
        String names = new String();
        //表中存在，但是传过来不存在，说明已删除，表中数据也要删除
        for (WorkAttachmentInfo dto : list) {
            names = names + "," +dto.getUrl();
        }
        //查询保存的附件信息
        List<WorkAttachmentInfo> infoList = holidayMapper.findList(id);
        if (CollectionUtil.isNotEmpty(infoList)) {
            for (WorkAttachmentInfo i : infoList) {
                if (!names.contains(i.getUrl())) {
                    SpringUtil.getBean ( IWorkAttachmentApi.class ).deleteById(i.getId());
                }
            }
        }
        //保存信息
        for (WorkAttachmentInfo dto : list) {
            //判断是否存在
            Integer isExit = holidayMapper.findIsExit(id, dto.getName());
            if (isExit == 0) {
                WorkAttachmentInfo i = new WorkAttachmentInfo();
                //包含了url、size、name
                i.setId(UUID.randomUUID().toString().replace("-", ""));
//                i.getCreateBy().setId(userDTO.getId());
                i.setCreateTime(new Date());
//                i.getUpdateBy().setId(userDTO.getId());
                i.setUpdateTime(new Date());
                i.setDelFlag(0);
                i.setUrl(dto.getUrl());
                //文件类型处理
                String fileName = dto.getName();
                List<String> strings = Arrays.asList(fileName.split("\\."));
                // 检查文件名是否有后缀
                if (CollectionUtil.isNotEmpty(strings) && strings.size() > 1) {
                    // 获取最后一个部分作为文件类型
                    i.setType(strings.get(strings.size() - 1));
                } else {
                    // 如果没有后缀或文件名无效，设置一个默认类型或空
                    i.setType("");
                }
                i.setAttachmentId(id);
                i.setAttachmentName(dto.getName());
                i.setAttachmentFlag("jyHoliday");
                i.setFileSize(dto.getSize());
                i.setSort(j);
                Map<String,String> map = new HashMap<>();
                String workAttachment = JSON.toJSONString((i));
                String userDTOInfo = JSON.toJSONString((userDTO));
                map.put("workAttachment",workAttachment);
                map.put("userDTO",userDTOInfo);
                SpringUtil.getBean ( IWorkAttachmentApi.class ).insertWorkAttachment(map);
                j++;
            }
        }
    }

    private Holiday add(HolidayDTO holidayDTO, UserDTO userDTO) {
        Holiday holiday = new Holiday();
        //获取id
        String id = UUID.randomUUID().toString().replace("-", "");

        holiday.setId(id);
        holiday.setStartDay(holidayDTO.getStartDay());//开始日期
        holiday.setBeginTime(holidayDTO.getBeginTime());//开始时间
        holiday.setEndDay(holidayDTO.getEndDay());//结束日期
        holiday.setEndTime(holidayDTO.getEndTime());//结束时间
        holiday.setType(holidayDTO.getType());//请假类型
        holiday.setDays(holidayDTO.getDays());//请假时长
        holiday.setReason(holidayDTO.getReason());//请假原因
        holiday.setStatus(holidayDTO.getStatus());

        /**
         * 移动端保存所需
         */
        if (StringUtils.isNotBlank(holidayDTO.getUserId())) {
            holiday.setCreateById(holidayDTO.getUserId());
            holiday.setUpdateById(holidayDTO.getUserId());
            //根据用户id查询用户所属的租户id
            UserDTO dto = SpringUtil.getBean(IUserApi.class).getById(holidayDTO.getUserId());
            holiday.setTenantId(dto.getTenantDTO().getId());
        }
        holidayMapper.insert(holiday);
        //保存附件
        List<WorkAttachmentInfo> files = holidayDTO.getFiles();
        if (CollectionUtil.isNotEmpty(files)) {
            saveFiles(files, userDTO, id);
        }
        return holiday;
    }

    /**
     * 保存附件信息
     * @param list 待保存的附件列表
     * @param userDTO 当前登录用户
     * @param id 关联id
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveFiles(List<WorkAttachmentInfo> list, UserDTO userDTO, String id) {
        int j = 1;
        for (WorkAttachmentInfo dto : list) {
            WorkAttachmentInfo i = new WorkAttachmentInfo();
            //包含了url、size、name
            i.setId(UUID.randomUUID().toString().replace("-", ""));
//            i.getCreateBy().setId(userDTO.getId());
            i.setCreateTime(new Date());
//            i.getUpdateBy().setId(userDTO.getId());
            i.setUpdateTime(new Date());
            i.setDelFlag(0);
            i.setUrl(dto.getUrl());
            //文件类型处理
            String fileName = dto.getName();
            List<String> strings = Arrays.asList(fileName.split("\\."));
            // 检查文件名是否有后缀
            if (CollectionUtil.isNotEmpty(strings) && strings.size() > 1) {
                // 获取最后一个部分作为文件类型
                i.setType(strings.get(strings.size() - 1));
            } else {
                // 如果没有后缀或文件名无效，设置一个默认类型或空
                i.setType("");
            }
            i.setAttachmentId(id);
            i.setAttachmentName(dto.getName());
            i.setAttachmentFlag("jyHoliday");
            i.setFileSize(dto.getSize());
            i.setSort(j);
            Map<String,String> map = new HashMap<>();
            String workAttachment = JSON.toJSONString((i));
            String userDTOInfo = JSON.toJSONString((userDTO));
            map.put("workAttachment",workAttachment);
            map.put("userDTO",userDTOInfo);
            SpringUtil.getBean ( IWorkAttachmentApi.class ).insertWorkAttachment(map);
            j++;
        }
    }


    /*
    根据id修改状态
     */
    public void updateStatusById(HolidayDTO holidayDTO) {
        holidayMapper.updateStatusById(holidayDTO.getStatus(),holidayDTO.getId());
    }

    /**
     * 根据id进行删除
     * @param id
     * @return
     */
    public String deleteById(String id) {
        holidayMapper.deleteById(id);
        return "操作成功";
    }
}
