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.log.annotation.Log;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.oa.domain.OaApproval;
import com.usky.oa.domain.OaDocument;
import com.usky.oa.domain.OaFormDefinition;
import com.usky.oa.domain.OaQjdDocument;
import com.usky.oa.mapper.OaApprovalMapper;
import com.usky.oa.mapper.OaDocumentMapper;
import com.usky.oa.mapper.OaFormDefinitionMapper;
import com.usky.oa.mapper.OaQjdDocumentMapper;
import com.usky.oa.service.OaQjdDocumentService;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.oa.service.enums.OaBuiltInDocument;
import com.usky.oa.service.utils.OaSendMessageCenter;
import lombok.extern.slf4j.Slf4j;
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 org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 请假单据表 服务实现类
 * </p>
 *
 * @author fu
 * @since 2024-12-10
 */
@Slf4j
@Service
public class OaQjdDocumentServiceImpl extends AbstractCrudService<OaQjdDocumentMapper, OaQjdDocument> implements OaQjdDocumentService {

    @Autowired
    private OaQjdDocumentMapper oaQjdDocumentMapper;

    @Autowired
    private OaFormDefinitionMapper oaFormDefinitionMapper;

    @Autowired
    private OaDocumentMapper oaDocumentMapper;

    @Autowired
    private OaApprovalMapper oaApprovalMapper;

    @Autowired
    private OaSendMessageCenter oaSendMessageCenter;

    @Override
    public void addQjDocument(OaQjdDocument oaQjdDocument) {

        // 校验表单数据
        validateOaQjDocument(oaQjdDocument);

        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);

        LambdaQueryWrapper<OaFormDefinition> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(OaFormDefinition::getFormSign).eq(OaFormDefinition::getId, oaQjdDocument.getFormId());
        OaFormDefinition oaFormDefinition = oaFormDefinitionMapper.selectOne(queryWrapper);
        String sign = oaFormDefinition.getFormSign();
        String docNo = sign + "-" + formattedDate;

        // 插入请假表数据
        oaQjdDocument.setDocNo(docNo);
        oaQjdDocument.setProposer(userId);
        oaQjdDocument.setCreateBy(username);
        oaQjdDocument.setCreateTime(now);
        oaQjdDocument.setDeptId(deptId);
        oaQjdDocument.setTenantId(tenantId);
        oaQjdDocumentMapper.insert(oaQjdDocument);

        // 插入单据表数据
        OaDocument oaDocument = new OaDocument();
        oaDocument.setFormId(oaQjdDocument.getFormId());
        oaDocument.setType(sign);
        oaDocument.setDocNo(docNo);
        oaDocument.setProposer(userId);
        oaDocument.setDocStatus(oaQjdDocument.getDocStatus());
        oaDocument.setCreateBy(username);
        oaDocument.setCreateTime(oaQjdDocument.getCreateTime());
        oaDocument.setDeptId(deptId);
        oaDocument.setTenantId(tenantId);
        oaDocumentMapper.insert(oaDocument);
    }

    @Override
    public void updateQjDocument(OaQjdDocument oaQjdDocument) {

        if (StringUtils.isBlank(oaQjdDocument.getDocNo())) {
            throw new BusinessException("更新请假单据ID异常");
        }

        validateOaQjDocument(oaQjdDocument);
        String username = SecurityUtils.getUsername();
        LocalDateTime now = LocalDateTime.now();
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Integer tenantId = SecurityUtils.getTenantId();
        Long userId = SecurityUtils.getUserId();

        oaQjdDocument.setUpdateBy(username);
        oaQjdDocument.setUpdateTime(now);
        oaQjdDocumentMapper.updateById(oaQjdDocument);

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

    /**
     * @description: 校验请假单据表数据
     * @author: fyc
     * @email yuchuan.fu@chinausky.com
     * @date: 2024/12/27 10:04
     * @param: [oaQjDocument]
     * @return: void
     **/
    private void validateOaQjDocument(OaQjdDocument oaQjdDocument) {

        if (oaQjdDocument.getFormId() == null || oaQjdDocument.getFormId() <= 0) {
            throw new BusinessException("表单ID不能为空或小于等于0");
        }

        if (StringUtils.isBlank(oaQjdDocument.getType())) {
            throw new BusinessException("请假类型不能为空");
        }

        if (oaQjdDocument.getType().length() > 4) {
            throw new BusinessException("请假类型长度不能超过4个字符");
        }

        if (oaQjdDocument.getStartTime() == null || oaQjdDocument.getEndTime() == null) {
            throw new BusinessException("请假开始时间或结束时间不能为空");
        }

        if (oaQjdDocument.getStartTime().isAfter(oaQjdDocument.getEndTime())) {
            throw new BusinessException("请假开始时间不能大于结束时间");
        }

        if (oaQjdDocument.getDuration() == null || oaQjdDocument.getDuration() <= 0) {
            throw new BusinessException("请假时长不能为空或小于等于0");
        }

        if (StringUtils.isBlank(oaQjdDocument.getReason())) {
            throw new BusinessException("请假原因不能为空");
        }

        if (oaQjdDocument.getReason().length() > 255) {
            throw new BusinessException("请假原因超出字数限制，请重试");
        }

        if (oaQjdDocument.getImage() != null && oaQjdDocument.getImage().length() > 500) {
            throw new BusinessException("上传图片数量超出限制，请重试");
        }
    }

    @Override
    public void delQjDocument(String docNo) {

        if (StringUtils.isBlank(docNo)) {
            throw new BusinessException("请假单据编号不能为空！");
        }

        LambdaQueryWrapper<OaQjdDocument> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(OaQjdDocument::getDocNo, docNo);
        oaQjdDocumentMapper.delete(queryWrapper);

        LambdaQueryWrapper<OaDocument> deleteWrapper = Wrappers.lambdaQuery();
        deleteWrapper.eq(OaDocument::getDocNo, docNo);
        oaDocumentMapper.delete(deleteWrapper);
    }
}
