package com.qmth.teachcloud.mark.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import javax.annotation.Resource;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.boot.core.exception.ParameterException;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
import com.qmth.teachcloud.common.service.TeachcloudCommonService;
import com.qmth.teachcloud.mark.entity.MarkDocument;
import com.qmth.teachcloud.mark.entity.MarkPaper;
import com.qmth.teachcloud.mark.entity.ScanPackage;
import com.qmth.teachcloud.mark.enums.DocumentType;
import com.qmth.teachcloud.mark.mapper.MarkDocumentMapper;
import com.qmth.teachcloud.mark.service.MarkDocumentService;
import com.qmth.teachcloud.mark.service.MarkFileService;
import com.qmth.teachcloud.mark.service.MarkPaperService;
import com.qmth.teachcloud.mark.service.ScanPackageService;

/**
 * <p>
 * 考试科目表 服务实现类
 * </p>
 *
 * @author xf
 * @since 2023-09-22
 */
@Service
public class MarkDocumentServiceImpl extends ServiceImpl<MarkDocumentMapper, MarkDocument> implements MarkDocumentService {
    @Resource
    private MarkFileService markFileService;
    @Resource
    private TeachcloudCommonService teachcloudCommonService;
    @Resource
    private MarkPaperService markPaperService;
    @Resource
    private ScanPackageService scanPackageService;

    @Override
    public List<MarkDocument> listByExamIdAndPaperNumber(Long examId, String paperNumber) {
        QueryWrapper<MarkDocument> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MarkDocument::getExamId, examId)
                .eq(MarkDocument::getPaperNumber, paperNumber);
        List<MarkDocument> list = this.list(queryWrapper);
        list.sort((d1,d2)->{
            return d1.getType().getValue()-d2.getType().getValue();
        });
        for (MarkDocument d : list) {
            d.setFilePath(teachcloudCommonService.filePreview(d.getFilePath()));
        }
        return list;
    }

    @Override
    public String importById(Long id, MultipartFile file, String md5) {
        MarkDocument document = this.getById(id);
        if (document == null) {
            throw ExceptionResultEnum.ERROR.exception("文档不存在");
        }
        if (document.getType().equals(DocumentType.CUSTOM)
                || document.getType().equals(DocumentType.SYLLABUS)
                || document.getType().equals(DocumentType.PROCESS_SCORE)
                || document.getType().equals(DocumentType.PAPER_REPORT)
                || document.getType().equals(DocumentType.CHECK_IN)) {
            try {
                String fileMd5 = DigestUtils.md5Hex(file.getBytes());
                if (!Objects.equals(fileMd5, md5)) {
                    throw ExceptionResultEnum.MD5_EQUALS_FALSE.exception();
                }
                String format = FilenameUtils.getExtension(file.getOriginalFilename());
                String name = document.getType().getName();
                if (document.getType().equals(DocumentType.CUSTOM)) {
                    name = document.getName();
                }
                String path = markFileService.uploadDocument(file.getInputStream(),
                        md5, document.getExamId(), document.getPaperNumber(), String.valueOf(document.getType().getValue()), document.getName(), format);
                UpdateWrapper<MarkDocument> updateWrapper = new UpdateWrapper<>();
                updateWrapper.lambda().set(MarkDocument::getFilePath, path)
                        .set(MarkDocument::getFileCount, 1)
                        .eq(MarkDocument::getId, id);
                this.update(updateWrapper);
                return teachcloudCommonService.filePreview(path);
            } catch (IOException e) {
                log.error(SystemConstant.LOG_ERROR, e);
                throw new ParameterException("上传失败", e);
            }
        } else {
            throw ExceptionResultEnum.ERROR.exception("文档类型不正确");
        }
    }

    @Override
    public void deleteById(Long id) {
        MarkDocument document = this.getById(id);
        if (document == null) {
            throw ExceptionResultEnum.ERROR.exception("文档不存在");
        }
        if (!document.getType().equals(DocumentType.CUSTOM)) {
            throw ExceptionResultEnum.ERROR.exception("文档类型不正确");
        }
        this.removeById(id);
    }

    @Override
    public String save(Long examId, String paperNumber, String documentName, MultipartFile file, String md5) {
        MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
        if (markPaper == null || !markPaper.getStatus().equals(MarkPaperStatus.FINISH)) {
            throw ExceptionResultEnum.ERROR.exception("评卷未结束或试卷不存在");
        }
        QueryWrapper<MarkDocument> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MarkDocument::getExamId, examId)
                .eq(MarkDocument::getPaperNumber, paperNumber)
                .eq(MarkDocument::getName, documentName);
        MarkDocument document = this.getOne(queryWrapper);
        if (document != null) {
            throw ExceptionResultEnum.ERROR.exception(documentName + "已存在");
        }
        try {
            String fileMd5 = DigestUtils.md5Hex(file.getBytes());
            if (!Objects.equals(fileMd5, md5)) {
                throw ExceptionResultEnum.MD5_EQUALS_FALSE.exception();
            }
            document = new MarkDocument();
            Long id = SystemConstant.getDbUuid();
            document.setId(id);
            document.setExamId(examId);
            document.setPaperNumber(paperNumber);
            document.setCourseCode(markPaper.getCourseCode());
            document.setCourseName(markPaper.getCourseName());
            document.setType(DocumentType.CUSTOM);
            document.setName(documentName);
            document.setFileCount(1);
            String format = FilenameUtils.getExtension(file.getOriginalFilename());
            String name = document.getType().getName();
            if (document.getType().equals(DocumentType.CUSTOM)) {
                name = document.getName();
            }
            String path = markFileService.uploadDocument(file.getInputStream(),
                    md5, examId, paperNumber, String.valueOf(document.getType().getValue()), documentName, format);
            document.setFilePath(path);
            this.save(document);
            return teachcloudCommonService.filePreview(path);
        } catch (IOException e) {
            log.error(SystemConstant.LOG_ERROR, e);
            throw new ParameterException("文件上传失败", e);
        }
    }

    @Override
    public void initMarkDocument(MarkPaper markPaper) {
            List<MarkDocument> markDocuments = new ArrayList<>();
            for (DocumentType documentType : DocumentType.getOptionList(false)) {
                MarkDocument markDocument = null;
                if(!DocumentType.CUSTOM.equals(documentType)){
                    QueryWrapper<MarkDocument> queryWrapper = new QueryWrapper<>();
                    queryWrapper.lambda().eq(MarkDocument::getExamId, markPaper.getExamId())
                            .eq(MarkDocument::getPaperNumber, markPaper.getPaperNumber())
                            .eq(MarkDocument::getType, documentType);
                    markDocument =  this.getOne(queryWrapper);
                }
                if(markDocument == null){
                    markDocument = new MarkDocument(markPaper.getExamId(), markPaper.getCourseCode(), markPaper.getCourseName(), markPaper.getPaperNumber(), documentType, documentType.getName(), 0);
                }
                if (documentType.equals(DocumentType.PAPER)) {
                    if (StringUtils.isNotBlank(markPaper.getPaperFilePath())) {
                        markDocument.setFileCount(1);
                        markDocument.setFilePath(markPaper.getPaperFilePath());
                    }
                } else if (documentType.equals(DocumentType.ANSWER)) {
                    if (StringUtils.isNotBlank(markPaper.getAnswerFilePath())) {
                        markDocument.setFileCount(1);
                        markDocument.setFilePath(markPaper.getAnswerFilePath());
                    }
                } else if (documentType.equals(DocumentType.PAPER_REPORT)) {
//                    markDocument.setFileCount(1);
                } else if (documentType.equals(DocumentType.APPROVE_RECORD)) {
                    markDocument.setFileCount(1);
                } else if (documentType.equals(DocumentType.SCORE)) {
                    markDocument.setFileCount(1);
                } else if (documentType.equals(DocumentType.SCORE_REPORT)) {
                    markDocument.setFileCount(1);
                } else if (documentType.equals(DocumentType.SHEET)) {
                    markDocument.setFileCount(markPaper.getUploadCount());
//                } else if (documentType.equals(DocumentType.TRACK)) {
//                    markDocument.setFileCount(markPaper.getUploadCount());
                } else if (documentType.equals(DocumentType.SIGN)) {
                    List<ScanPackage> scanPackageList = scanPackageService.listByExamIdAndCoursePaperIdAndPackageCode(markPaper.getExamId(), markPaper.getCoursePaperId(), null);
                    markDocument.setFileCount(scanPackageList.size());
                } else if (documentType.equals(DocumentType.CHECK_IN)) {

                }
                markDocuments.add(markDocument);
            }
            this.saveOrUpdateBatch(markDocuments);
    }
}
