package com.ruoyi.pay.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.pay.domain.PayAttendance;
import com.ruoyi.pay.mapper.PayAttendanceMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.pay.domain.bo.PayRequireAttendanceReportBo;
import com.ruoyi.pay.domain.vo.PayRequireAttendanceReportVo;
import com.ruoyi.pay.domain.PayRequireAttendanceReport;
import com.ruoyi.pay.mapper.PayRequireAttendanceReportMapper;
import com.ruoyi.pay.service.IPayRequireAttendanceReportService;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 应出勤报Service业务层处理
 *
 * @author ruoyi
 * @date 2025-05-12
 */
@RequiredArgsConstructor
@Service
public class PayRequireAttendanceReportServiceImpl implements IPayRequireAttendanceReportService {

    private final PayRequireAttendanceReportMapper baseMapper;
    private final PayAttendanceMapper attendanceMapper;
    /**
     * 查询应出勤报
     */
    @Override
    public PayRequireAttendanceReportVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询应出勤报列表
     */
    @Override
    public TableDataInfo<PayRequireAttendanceReportVo> queryPageList(PayRequireAttendanceReportBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PayRequireAttendanceReport> lqw = buildQueryWrapper(bo);
        Page<PayRequireAttendanceReportVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询应出勤报列表
     */
    @Override
    public List<PayRequireAttendanceReportVo> queryList(PayRequireAttendanceReportBo bo) {
        LambdaQueryWrapper<PayRequireAttendanceReport> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<PayRequireAttendanceReport> buildQueryWrapper(PayRequireAttendanceReportBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PayRequireAttendanceReport> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getTenantId() != null, PayRequireAttendanceReport::getTenantId, bo.getTenantId());
        lqw.eq(StringUtils.isNotBlank(bo.getYear()), PayRequireAttendanceReport::getYear, bo.getYear());
        lqw.eq(StringUtils.isNotBlank(bo.getMonth()), PayRequireAttendanceReport::getMonth, bo.getMonth());
        lqw.eq(bo.getEmployeeId() != null, PayRequireAttendanceReport::getEmployeeId, bo.getEmployeeId());
        lqw.like(StringUtils.isNotBlank(bo.getEmpName()), PayRequireAttendanceReport::getEmpName, bo.getEmpName());
        lqw.like(StringUtils.isNotBlank(bo.getDeptName()), PayRequireAttendanceReport::getDeptName, bo.getDeptName());
        lqw.eq(StringUtils.isNotBlank(bo.getRestType()), PayRequireAttendanceReport::getRestType, bo.getRestType());
        lqw.eq(bo.getRequireDays() != null, PayRequireAttendanceReport::getRequireDays, bo.getRequireDays());
        lqw.eq(bo.getAvtiveDays() != null, PayRequireAttendanceReport::getAvtiveDays, bo.getAvtiveDays());
        lqw.eq(bo.getAttendanceHours() != null, PayRequireAttendanceReport::getAttendanceHours, bo.getAttendanceHours());
        lqw.eq(bo.getOvertimeHours() != null, PayRequireAttendanceReport::getOvertimeHours, bo.getOvertimeHours());
        lqw.eq(bo.getHolidays() != null, PayRequireAttendanceReport::getHolidays, bo.getHolidays());
        lqw.eq(bo.getHolidayHours() != null, PayRequireAttendanceReport::getHolidayHours, bo.getHolidayHours());
        lqw.eq(bo.getLeaveDays() != null, PayRequireAttendanceReport::getLeaveDays, bo.getLeaveDays());
        return lqw;
    }

    /**
     * 新增应出勤报
     */
    @Override
    public Boolean insertByBo(PayRequireAttendanceReportBo bo) {
        PayRequireAttendanceReport add = BeanUtil.toBean(bo, PayRequireAttendanceReport.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改应出勤报
     */
    @Override
    public Boolean updateByBo(PayRequireAttendanceReportBo bo) {
        PayRequireAttendanceReport update = BeanUtil.toBean(bo, PayRequireAttendanceReport.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(PayRequireAttendanceReport entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除应出勤报
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public String importAttendanceReport(List<PayRequireAttendanceReportVo> attendanceReportList, boolean updateSupport, String date,Long tenantId) {
        if (null==attendanceReportList || attendanceReportList.size() == 0)
        {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        for (PayRequireAttendanceReportVo attendanceReport : attendanceReportList)
        {   //如果导入数据没有姓名则进行下一条
            if(attendanceReport.getEmpName()==null||attendanceReport.getEmpName().trim().equals("")){
                continue;
            }
            //应出勤天数，实际出勤天数，出勤小时数，加班小时数为null  则赋值0
            if(attendanceReport.getRequireDays()==null){
                attendanceReport.setRequireDays(Long.parseLong("0"));
            }
            if(attendanceReport.getAvtiveDays()==null){
                attendanceReport.setAvtiveDays(Long.parseLong("0"));
            }
            if(attendanceReport.getAttendanceHours()==null){
                attendanceReport.setAttendanceHours(new BigDecimal("0"));
            }
            if(attendanceReport.getOvertimeHours()==null){
                attendanceReport.setOvertimeHours(new BigDecimal("0"));
            }
            try
            {
                attendanceReport.setYear(date.split("-")[0]);
                attendanceReport.setMonth(date.split("-")[1]);
                String name = attendanceReport.getEmpName();
                //根据员工name查询员工id、部门id、部门名称

                PayAttendance info  =  attendanceMapper.selectEmpInfoByName(name);
                if(info==null){
                    throw new IOException("请先在员工表中添加员工："+name);
                }
                attendanceReport.setEmployeeId(info.getEmployeeId());
                attendanceReport.setDeptName(info.getDeptName());
                attendanceReport.setTenantId(tenantId);
                // 验证是否存在这个人的报告
                PayRequireAttendanceReportBo bo = BeanUtil.toBean(attendanceReport,PayRequireAttendanceReportBo.class);
                List<PayRequireAttendanceReportVo> r = this.queryList(bo);
                if (null==r||r.size()==0)
                {
                    this.insertByBo(bo);
                    successNum++;
                    if(updateSupport){
                        successMsg.append("<br/>" + successNum + attendanceReport.getEmpName()+ " 更新成功");
                    }else{
                        successMsg.append("<br/>" + successNum + attendanceReport.getEmpName()+ "导入成功");
                    }
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + attendanceReport.getEmpName() + " 已存在");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + attendanceReport.getEmpName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                System.err.println(msg+ e);
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "导入成功"+successNum+"条，导入失败" + failureNum + " 条，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
}
