package cn.com.poc.ai_data_audit.service.impl;

import cn.com.poc.ai_data_audit.constants.DataAuditConstants;
import cn.com.poc.ai_data_audit.dto.FileUploadConfirmDto;
import cn.com.poc.ai_data_audit.dto.FileUploadDto;
import cn.com.poc.ai_data_audit.dto.FileUploadReturnDto;
import cn.com.poc.ai_data_audit.entity.BizAiDataAuditFileEntity;
import cn.com.poc.ai_data_audit.service.BizAiDataAuditFileService;
import cn.com.poc.common.model.BizFileUploadRecordModel;
import cn.com.poc.common.service.BizFileUploadRecordService;
import cn.com.poc.common.service.RedisService;
import cn.com.poc.common.utils.BlContext;
import cn.com.poc.message.entity.AirportTaskCreateMessage;
import cn.com.poc.message.service.AirportProducerService;
import cn.com.yict.framemax.core.service.impl.BaseServiceImpl;
import cn.com.poc.ai_data_audit.service.BizAiDataAuditTaskService;
import cn.com.poc.ai_data_audit.model.BizAiDataAuditTaskModel;
import cn.com.poc.ai_data_audit.entity.BizAiDataAuditTaskEntity;
import cn.com.poc.ai_data_audit.convert.BizAiDataAuditTaskConvert;
import cn.com.poc.ai_data_audit.repository.BizAiDataAuditTaskRepository;
import cn.com.yict.framemax.data.model.PagingInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.List;
import javax.annotation.Resource;

import org.springframework.util.Assert;

@Service
public class BizAiDataAuditTaskServiceImpl extends BaseServiceImpl
        implements BizAiDataAuditTaskService {

    @Resource
    private BizAiDataAuditTaskRepository repository;
    @Resource
    private BizAiDataAuditFileService bizAiDataAuditFileService;

    @Resource
    private BizFileUploadRecordService bizFileUploadRecordService;

    @Override
    public BizAiDataAuditTaskEntity get(java.lang.Long id) throws Exception {
        Assert.notNull(id);
        BizAiDataAuditTaskModel model = this.repository.get(id);
        if (model == null) {
            return null;
        }
        if ("Y".equals(model.getIsDeleted())) {
            return null;
        }
        if (BlContext.getCurrentUser().getUserId().intValue() != model.getMemberId()) {
            return null;
        }
        return BizAiDataAuditTaskConvert.modelToEntity(model);
    }

    @Override
    public BizAiDataAuditTaskEntity getWithToken(java.lang.Long id) throws Exception {
        Assert.notNull(id);
        BizAiDataAuditTaskModel model = this.repository.get(id);
        if (model == null) {
            return null;
        }
        if ("Y".equals(model.getIsDeleted())) {
            return null;
        }
        return BizAiDataAuditTaskConvert.modelToEntity(model);
    }

    @Override
    public void delete(java.lang.Long id) throws Exception {
        Assert.notNull(id);
        BizAiDataAuditTaskEntity bizAiDataAuditTaskEntity = get(id);
        if (bizAiDataAuditTaskEntity == null) {
            throw new Exception("the task can not be found");
        }
        deletedById(id);
    }


    @Override
    public List<BizAiDataAuditTaskEntity> findByExample(BizAiDataAuditTaskEntity example, PagingInfo pagingInfo) throws Exception {
        List<BizAiDataAuditTaskEntity> result = new ArrayList<BizAiDataAuditTaskEntity>();
        BizAiDataAuditTaskModel model = new BizAiDataAuditTaskModel();
        if (example != null) {
            model = BizAiDataAuditTaskConvert.entityToModel(example);
        }
        model.setIsDeleted("N");
        List<BizAiDataAuditTaskModel> models = this.repository.findByExample(model, pagingInfo);
        if (CollectionUtils.isNotEmpty(models)) {
            result = models.stream().map(BizAiDataAuditTaskConvert::modelToEntity).collect(Collectors.toList());
        }
        return result;
    }

    public BizAiDataAuditTaskEntity save(BizAiDataAuditTaskEntity entity) throws Exception {
        Assert.notNull(entity);
        entity.setDataAuditTaskId(null);
        entity.setIsDeleted("N");
        BizAiDataAuditTaskModel model = BizAiDataAuditTaskConvert.entityToModel(entity);
        BizAiDataAuditTaskModel saveModel = this.repository.save(model);
        return BizAiDataAuditTaskConvert.modelToEntity(saveModel);
    }

    @Override
    public BizAiDataAuditTaskEntity update(BizAiDataAuditTaskEntity entity) throws Exception {
        Assert.notNull(entity);
        Assert.notNull(entity.getDataAuditTaskId(), "update pk can not be null");
        BizAiDataAuditTaskModel model = this.repository.get(entity.getDataAuditTaskId());

        if (entity.getDataAuditTaskName() != null) {
            model.setDataAuditTaskName(entity.getDataAuditTaskName());
        }
        if (entity.getAuditResult() != null) {
            model.setAuditResult(entity.getAuditResult());
        }
        if (entity.getMemberId() != null) {
            model.setMemberId(entity.getMemberId());
        }
        if (entity.getStatus() != null) {
            model.setStatus(entity.getStatus());
        }
        if (entity.getFileNum() != null) {
            model.setFileNum(entity.getFileNum());
        }
        if (entity.getIsDeleted() != null) {
            model.setIsDeleted(entity.getIsDeleted());
        }
        if (entity.getCreator() != null) {
            model.setCreator(entity.getCreator());
        }
        if (entity.getCreatedTime() != null) {
            model.setCreatedTime(entity.getCreatedTime());
        }
        if (entity.getModifier() != null) {
            model.setModifier(entity.getModifier());
        }
        if (entity.getModifiedTime() != null) {
            model.setModifiedTime(entity.getModifiedTime());
        }
        if (entity.getSysVersion() != null) {
            model.setSysVersion(entity.getSysVersion());
        }
        BizAiDataAuditTaskModel saveModel = this.repository.save(model);
        return BizAiDataAuditTaskConvert.modelToEntity(saveModel);
    }

    public void deletedById(java.lang.Long id) throws Exception {
        Assert.notNull(id);
        BizAiDataAuditTaskModel model = this.repository.get(id);
        if (model != null) {
            if ("N".equals(model.getIsDeleted())) {
                model.setIsDeleted("Y");
                this.repository.save(model);
            }
        }
    }

    @Override
    public void createDataAuditTask(String taskName, FileUploadConfirmDto fileUploadConfirmDto) throws Exception {
        if (CollectionUtils.isEmpty(fileUploadConfirmDto.getFileUploadReturnDtoList())) {
            throw new Exception("Please select the file you wish to upload!");
        }

        //匹配的文件
        List<FileUploadReturnDto> fileUploadReturnDtoList = fileUploadConfirmDto.getFileUploadReturnDtoList();
//        Map<String, String> fileCodeNameMap = fileUploadReturnDtoList.stream().filter(item->StringUtils.isNotBlank(item.getOrginalTemplateCode())).collect(Collectors.toMap(FileUploadReturnDto::getOrginalTemplateCode, FileUploadReturnDto::getUploadFileName));
//        Map<String, String> fileNameCodeMap = fileUploadReturnDtoList.stream().collect(Collectors.toMap(FileUploadReturnDto::getUploadFileName, FileUploadReturnDto::getOrginalTemplateCode));
//        Map<String, String> fileuploadNameCodeMap = fileUploadReturnDtoList.stream().collect(Collectors.toMap(FileUploadReturnDto::getUploadFileName, FileUploadReturnDto::getOrginalTemplateCode));

        String fileNameDoc1 = "";
        String fileNameDoc2 = "";

        for (FileUploadReturnDto fileUploadReturnDto : fileUploadReturnDtoList) {
            if ("DOC-01".equals(fileUploadReturnDto.getOrginalTemplateCode())) {
                fileNameDoc1 = fileUploadReturnDto.getUploadFileName();
            } else if ("DOC-02".equals(fileUploadReturnDto.getOrginalTemplateCode())) {
                fileNameDoc2 = fileUploadReturnDto.getUploadFileName();
            }
        }

        if (StringUtils.isBlank(fileNameDoc1) && StringUtils.isBlank(fileNameDoc2)) {
            throw new Exception("Work Permit Application Details or Work Permit Extension Details can not be null");
        }


        //上传的文件
        Map<String, String> fileMap = new HashMap<>();
        for (FileUploadDto fileUploadDto : fileUploadConfirmDto.getFileUploadDtoList()) {
            fileMap.put(fileUploadDto.getFileName(), fileUploadDto.getFileUrl());
        }

        //生成task
        BizAiDataAuditTaskModel model = new BizAiDataAuditTaskModel();
        model.setDataAuditTaskName(taskName);
        model.setMemberId(BlContext.getCurrentUser().getUserId().intValue());
        model.setStatus(DataAuditConstants.status.status_process);
        model.setFileNum(fileUploadConfirmDto.getFileUploadDtoList().size());
        BizAiDataAuditTaskModel savedModel = repository.save(model);

        List<BizAiDataAuditFileEntity> bizAiDataAuditFileEntityList = new ArrayList<BizAiDataAuditFileEntity>();
//        for (Map.Entry<String, String> entry : fileMap.entrySet()) {
//            BizAiDataAuditFileEntity bizAiDataAuditFileEntity = new BizAiDataAuditFileEntity();
//            bizAiDataAuditFileEntity.setTaskId(savedModel.getDataAuditTaskId());
//            bizAiDataAuditFileEntity.setOrginalTemplateCode(StringUtils.isBlank(fileuploadNameCodeMap.get(entry.getKey())) ? null : "other");
//            bizAiDataAuditFileEntity.setOrginalTemplateName(fileNameCodeMap.get(bizAiDataAuditFileEntity.getOrginalTemplateCode()));
//            bizAiDataAuditFileEntity.setUploadFileName(entry.getKey());
//            bizAiDataAuditFileEntity.setUploadFileUrl(entry.getValue());
//            bizAiDataAuditFileEntityList.add(bizAiDataAuditFileEntity);
//        }
//        BizFileUploadRecordModel example = new BizFileUploadRecordModel();
//        example.setId();
//        example.setFileName();
//        example.setFileUrl();
//        example.setCoverSheetUrl();
//        example.setMd5();
//        example.setModelState();
//        bizFileUploadRecordService.findByExample(null)


        for (FileUploadReturnDto fileUploadReturnDto : fileUploadReturnDtoList) {
            if (StringUtils.isBlank(fileUploadReturnDto.getUploadFileName())) {
                continue;
            }
            BizAiDataAuditFileEntity bizAiDataAuditFileEntity = new BizAiDataAuditFileEntity();
            bizAiDataAuditFileEntity.setOrginalTemplateName(fileUploadReturnDto.getOrginalTemplateName());
            bizAiDataAuditFileEntity.setTaskId(savedModel.getDataAuditTaskId());
            bizAiDataAuditFileEntity.setOrginalTemplateCode(fileUploadReturnDto.getOrginalTemplateCode());
            bizAiDataAuditFileEntity.setUploadFileName(fileUploadReturnDto.getUploadFileName());
            bizAiDataAuditFileEntity.setUploadFileUrl(fileMap.get(fileUploadReturnDto.getUploadFileName()));
//            bizAiDataAuditFileEntity.setDataAuditFileId();
            bizAiDataAuditFileEntityList.add(bizAiDataAuditFileEntity);
        }
        List<String> uploadFileUrlList = bizAiDataAuditFileEntityList.stream().map(item -> item.getUploadFileUrl()).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(uploadFileUrlList)) {
            List<BizFileUploadRecordModel> byFileLink = bizFileUploadRecordService.findByFileLink(uploadFileUrlList);
            Map<String, List<BizFileUploadRecordModel>> bizFileUploadRecordModelMap = byFileLink.stream().collect(Collectors.groupingBy(BizFileUploadRecordModel::getFileUrl));

            for (BizAiDataAuditFileEntity bizAiDataAuditFileEntity : bizAiDataAuditFileEntityList) {
                List<BizFileUploadRecordModel> bizFileUploadRecordModels = bizFileUploadRecordModelMap.get(bizAiDataAuditFileEntity.getUploadFileUrl());
                if (CollectionUtils.isNotEmpty(bizFileUploadRecordModels)) {
                    bizAiDataAuditFileEntity.setMd5(bizFileUploadRecordModels.get(0).getMd5());
                }
            }
        }
        bizAiDataAuditFileService.batchSavedFile(bizAiDataAuditFileEntityList);

        //任务推送
        pushTask(savedModel.getDataAuditTaskId());
    }

    @Resource
    private RedisService redisService;

    @Resource
    private AirportProducerService airportProducerService;

    private void pushTask(Long taskId) {
        // 配置Redis AI_DATA_AUDIT_TASK , 表示消息队列已经获取到任务 [用于定时任务(AiDataAuditScheduler)判断该任务下的 OCR任务是否已经全部完成] Push推送至队列 Get消费者获取到任务 Finish已结束
        redisService.set("AI_DATA_AUDIT_TASK:" + taskId, "Push");

        AirportTaskCreateMessage airportTaskCreateMessage = new AirportTaskCreateMessage();
        airportTaskCreateMessage.setTaskId(taskId);
        airportProducerService.createTask(airportTaskCreateMessage);
    }
}