package com.usky.oa.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.oa.domain.OaApproval;
import com.usky.oa.domain.OaDocument;
import com.usky.oa.domain.OaJbdDocument;
import com.usky.oa.mapper.OaApprovalMapper;
import com.usky.oa.mapper.OaDocumentMapper;
import com.usky.oa.mapper.OaJbdDocumentMapper;
import com.usky.oa.service.OaJbdDocumentService;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.oa.service.enums.OaBuiltInDocument;
import com.usky.oa.service.utils.OaSendMessageCenter;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 加班单据表 服务实现类
 * </p>
 *
 * @author fu
 * @since 2025-01-02
 */
@Service
public class OaJbdDocumentServiceImpl extends AbstractCrudService<OaJbdDocumentMapper, OaJbdDocument> implements OaJbdDocumentService {

    @Autowired
    private OaJbdDocumentMapper oaJbdDocumentMapper;

    @Autowired
    private OaDocumentMapper oaDocumentMapper;

    @Autowired
    private OaApprovalMapper oaApprovalMapper;

    @Autowired
    private OaSendMessageCenter oaSendMessageCenter;

    @Override
    public void add(OaJbdDocument oaJbdDocument) {
        Long userId = SecurityUtils.getUserId();
        String username = SecurityUtils.getUsername();
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Integer tenantId = SecurityUtils.getTenantId();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHHmmss");
        LocalDateTime now = LocalDateTime.now();
        String formattedDate = now.format(formatter);
        String sign = OaBuiltInDocument.JBD.getSign();
        String docNo = sign + "-" + formattedDate;

        validateOaJbDocument(oaJbdDocument);

        oaJbdDocument.setDocNo(docNo);
        oaJbdDocument.setAccountingMethod(0);
        oaJbdDocument.setProposer(userId);
        oaJbdDocument.setCreateBy(username);
        oaJbdDocument.setCreateTime(now);
        oaJbdDocument.setDeptId(deptId);
        oaJbdDocument.setTenantId(tenantId);
        oaJbdDocumentMapper.insert(oaJbdDocument);

        OaDocument oaDocument = new OaDocument();
        oaDocument.setFormId(oaJbdDocument.getFormId());
        oaDocument.setType(sign);
        oaDocument.setDocNo(docNo);
        oaDocument.setProposer(userId);
        oaDocument.setDocStatus(oaJbdDocument.getDocStatus());
        oaDocument.setCreateBy(username);
        oaDocument.setCreateTime(oaJbdDocument.getCreateTime());
        oaDocument.setDeptId(deptId);
        oaDocument.setTenantId(tenantId);
        oaDocumentMapper.insert(oaDocument);
    }

    @Override
    public void update(OaJbdDocument oaJbdDocument) {
        if (StringUtils.isBlank(oaJbdDocument.getDocNo())) {
            throw new BusinessException("更新单据编号传参异常！");
        }

        LocalDateTime now = LocalDateTime.now();
        Long userId = SecurityUtils.getUserId();

        validateOaJbDocument(oaJbdDocument);
        oaJbdDocument.setUpdateBy(SecurityUtils.getUsername());
        oaJbdDocument.setUpdateTime(LocalDateTime.now());
        oaJbdDocumentMapper.updateById(oaJbdDocument);

        oaDocumentMapper.update(null, Wrappers.lambdaUpdate(OaDocument.class)
                .eq(OaDocument::getDocNo, oaJbdDocument.getDocNo())
                .set(OaDocument::getDocStatus, oaJbdDocument.getDocStatus())
                .set(OaDocument::getUpdateBy, oaJbdDocument.getUpdateBy())
                .set(OaDocument::getUpdateTime, oaJbdDocument.getUpdateTime())
        );
    }

    /**
     * @description: 验证加班单据参数
     * @author: fyc
     * @email yuchuan.fu@chinausky.com
     * @date: 2025/1/2 18:29
     * @param: [oaJbdDocument]
     * @return: void
     **/
    private void validateOaJbDocument(OaJbdDocument oaJbdDocument) {

        if (oaJbdDocument.getFormId() == null || oaJbdDocument.getFormId() <= 0) {
            throw new BusinessException("表单ID必须大于0！");
        }

        LocalDateTime startTime = oaJbdDocument.getStartTime();
        LocalDateTime endTime = oaJbdDocument.getEndTime();
        Integer duration = oaJbdDocument.getDuration();

        if (startTime == null || endTime == null || startTime.isAfter(endTime)) {
            throw new BusinessException("加班开始时间或结束时间输入异常！请确保开始时间不晚于结束时间");
        }

        if (duration == null || duration <= 0) {
            throw new BusinessException("加班时长必须大于0！");
        }

        if (StringUtils.isBlank(oaJbdDocument.getReason())) {
            throw new BusinessException("加班原因不能为空！");
        } else if (oaJbdDocument.getReason().length() > 255) {
            throw new BusinessException("加班原因超出字数限制，请重试！");
        }

        if (oaJbdDocument.getImage() == null) {
            throw new BusinessException("打卡记录及日报图片不能为空！");
        } else if (oaJbdDocument.getImage().length() > 500) {
            throw new BusinessException("上传图片数量超出限制，请重试！");
        }
    }

    @Override
    public void delByDocNo(String docNo) {
        Integer tenantId = SecurityUtils.getTenantId();
        Long userId = SecurityUtils.getUserId();

        LambdaQueryWrapper<OaJbdDocument> jbdDeleteWrapper = new LambdaQueryWrapper<>();
        jbdDeleteWrapper.eq(OaJbdDocument::getTenantId, tenantId)
                .eq(OaJbdDocument::getProposer, userId)
                .eq(OaJbdDocument::getDocNo, docNo);
        oaJbdDocumentMapper.delete(jbdDeleteWrapper);

        LambdaQueryWrapper<OaDocument> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(OaDocument::getTenantId, tenantId)
                .eq(OaDocument::getProposer, userId)
                .eq(OaDocument::getDocNo, docNo);
        oaDocumentMapper.delete(deleteWrapper);
    }

}
