package com.sunxung.factoring.service.fundmanagement.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.dict.impl.FileModuleDict;
import com.sunxung.factoring.dict.impl.FinancialCustomerStatusDict;
import com.sunxung.factoring.entity.fundmanagement.*;
import com.sunxung.factoring.entity.fundmanagement.vo.FinancialBasicFileVo;
import com.sunxung.factoring.entity.fundmanagement.vo.FinancialBasicVo;
import com.sunxung.factoring.entity.fundmanagement.vo.FinancialCustomerVo;
import com.sunxung.factoring.entity.project.vo.BusinessProcessingTaskVo;
import com.sunxung.factoring.entity.project.vo.SearchBusinessProcessingTask;
import com.sunxung.factoring.entity.sys.Dictionary;
import com.sunxung.factoring.entity.sys.FileStorage;
import com.sunxung.factoring.mapper.fundmanagement.FinancialCustomerMapper;
import com.sunxung.factoring.service.fundmanagement.*;
import com.sunxung.factoring.service.project.BusinessAssigneeService;
import com.sunxung.factoring.service.sys.DictionaryService;
import com.sunxung.factoring.service.sys.FileStorageService;
import com.sunxung.factoring.service.sys.ISysAttachmentRefService;
import com.sunxung.factoring.service.sys.dto.AttachmentDto;
import com.sunxung.factoring.service.sys.flowable.FlowableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author Yafan Wang
 * @Date 2023/2/9 16:15
 */
@Service("financialCustomerService")
public class FinancialCustomerInfoServiceImpl extends ServiceImpl<FinancialCustomerMapper, FinancialCustomerInfo> implements FinancialCustomerInfoService {

    @Autowired
    private FinancialCustomerMapper financialCustomerMapper;
    @Autowired
    private DictionaryService dictionaryService;
    @Autowired
    private ISysAttachmentRefService iSysAttachmentRefService;
    @Autowired
    private FlowableService flowableService;
    @Autowired
    private BusinessAssigneeService assigneeService;
    @Autowired
    private FinancialBasicFileInfoService financialBasicFileInfoService;
    @Autowired
    private FinancialBasicFileDictionaryService financialBasicFileDictionaryService;
    @Autowired
    private FinancialBasicFileHisInfoService financialBasicFileHisInfoService;
    @Autowired
    private FinancialCustomerHisInfoService financialCustomerHisInfoService;
    @Autowired
    private FileStorageService fileStorageService;

    @Override
    public void downloadAllFile(HttpServletResponse response, Long id) {
        FinancialCustomerVo customerVo = findVoById(id);
        List<FinancialBasicFileInfo> basicFileInfoList = financialBasicFileInfoService.list(new QueryWrapper<FinancialBasicFileInfo>()
                .eq("financial_customer_info_id", id));
        List<FileStorage> fileStorageList = new ArrayList<>();
        List<File> fileList = new ArrayList<>();
        //查找所有的文件
        for (FinancialBasicFileInfo financialBasicFileInfo : basicFileInfoList) {
            AttachmentDto attachmentDto = AttachmentDto.builder()
                    .setEntityId(financialBasicFileInfo.getId())
                    .setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_CUSTOMER_BASIC_FILE)
                    .build();
            fileStorageList.addAll(iSysAttachmentRefService.getFiles(attachmentDto));
        }
        fileStorageService.renameFileStorageList(fileStorageList);
        String name = customerVo.getCustomerName();
        //文件打包下载
        fileStorageService.downloadZipFile(fileStorageList, name, FileModuleDict.ChildEnum.FINANCIAL_ZIP_FILE, response);
    }

    @Override
    public FinancialCustomerVo editBasicFile(Long financialCustomerId) {
        FinancialCustomerVo customerVo = findVoById(financialCustomerId);
        List<FinancialBasicFileVo> basicFileVos = new ArrayList<>();
        basicFileVos = financialCustomerMapper.findByFinancialCustomerId(financialCustomerId);
        if (basicFileVos != null && basicFileVos.size() > 0) {
            for (FinancialBasicFileVo basicFileVo : basicFileVos) {
                //附件信息注入
                AttachmentDto attachmentDto = AttachmentDto.builder()
                        .setEntityId(basicFileVo.getId())
                        .setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_CUSTOMER_BASIC_FILE)
                        .build();
                List<FileStorage> fileStorages = iSysAttachmentRefService.getFiles(attachmentDto);
                basicFileVo.setFileStorageList(fileStorages);
            }
        } else {
            List<FinancialBasicFileDictionary> fileDictionaries = financialBasicFileDictionaryService
                    .list(new QueryWrapper<FinancialBasicFileDictionary>().eq("delete_status", 0).orderByAsc("gradation"));
            for (FinancialBasicFileDictionary fileDictionary : fileDictionaries) {
                FinancialBasicFileVo financialBasicFileVo = new FinancialBasicFileVo(fileDictionary);
                List<FileStorage> fileStorages = new ArrayList<>();
                financialBasicFileVo.setFileStorageList(fileStorages);
                basicFileVos.add(financialBasicFileVo);
            }
        }
        customerVo.setFinancialBasicFileVos(basicFileVos);
        return customerVo;
    }

    @Override
    public void claimFinancialCustomerTask(String taskId) {
        ArrayList<String> roleNames = new ArrayList<>();
        roleNames.add(ConstantUtil.REFINANCING_OPERATION_OWNER);
        roleNames.add(ConstantUtil.PROJECT_MANAGER);
        roleNames.add(ConstantUtil.FINANCIAL_MANAGER);
        flowableService.claimTask(taskId, ThreadLocalUtil.getUserId(), roleNames);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doEditBasicFile(FinancialBasicVo financialBasicVo) {
        FinancialCustomerInfo financialCustomerInfo = financialCustomerMapper.selectById(financialBasicVo.getFinancialCustomerInfoId());
        financialCustomerInfo.setTaskId(financialBasicVo.getTaskId());
        List<FinancialBasicFileVo> financialBasicFileVoList = financialBasicVo.getBasicFiles();
        if (financialBasicFileVoList != null && financialBasicFileVoList.size() > 0) {
            financialBasicFileInfoService.remove(new QueryWrapper<FinancialBasicFileInfo>().eq("financial_customer_info_id", financialBasicVo.getFinancialCustomerInfoId()));
            for (FinancialBasicFileVo financialBasicFileVo : financialBasicFileVoList) {
                FinancialBasicFileInfo fileInfo = new FinancialBasicFileInfo(financialBasicFileVo, financialBasicVo.getFinancialCustomerInfoId());
                fileInfo.setId(financialBasicFileVo.getId());
                fileInfo.setFinancialCustomerInfoId(financialBasicVo.getFinancialCustomerInfoId());
                financialBasicFileInfoService.save(fileInfo);
                //附件全删全进
                AttachmentDto attachmentDto = AttachmentDto.builder()
                        .setEntityId(fileInfo.getId())
                        .setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_CUSTOMER_BASIC_FILE)
                        .build();
                iSysAttachmentRefService.removeRef(attachmentDto);
                if (financialBasicFileVo.getFileStorageIdList() != null && financialBasicFileVo.getFileStorageIdList().size() > 0) {
                    iSysAttachmentRefService.saveRef(financialBasicFileVo.getFileStorageIdList(), attachmentDto);
                }
            }
            //提交开启流程
            if (financialBasicVo.getSubmit() == 1) {
                //新增历史
                completeProcess(financialCustomerInfo);
            }
        }
    }

    @Override
    public List<BusinessProcessingTaskVo> findMyCompletedList(SearchBusinessProcessingTask search) {
        List<BusinessProcessingTaskVo> list = financialCustomerMapper.findMyCompletedList(search);
        if (list != null) {
            for (BusinessProcessingTaskVo businessProcessingTaskVo : list) {
                businessProcessingTaskVo.setStatus(dictionaryService.get(businessProcessingTaskVo.getStatus().getId()));
            }
        }
        return list;
    }

    @Override
    public List<BusinessProcessingTaskVo> findAllList(SearchBusinessProcessingTask search) {
        List<BusinessProcessingTaskVo> allList = financialCustomerMapper.findAllList(search);
        if (allList != null) {
            for (BusinessProcessingTaskVo businessProcessingTaskVo : allList) {
                businessProcessingTaskVo.setStatus(dictionaryService.get(businessProcessingTaskVo.getStatus().getId()));
            }
        }
        return allList;
    }

    @Override
    public FinancialCustomerInfo get(Long id) {
        FinancialCustomerVo customerVo = findVoById(id);
        FinancialCustomerInfo customerInfo = new FinancialCustomerInfo();
        if (customerVo != null) {
            customerInfo.setCustomerName(customerVo.getCustomerName());
            customerInfo.setInstitutionName(customerVo.getInstitutionName());
            customerInfo.setStatusDictionary(customerVo.getStatus());
            customerInfo.setGmtCreate(customerVo.getGmtCreate());
            customerInfo.setGmtModified(customerVo.getGmtModified());
            customerInfo.setId(id);
        }
        return customerInfo;
    }

    @Override
    public FinancialCustomerVo getView(Long id) {
        FinancialCustomerVo customerVo = findHisVoById(id);
        List<FinancialBasicFileHisInfo> basicFileHistorys = financialBasicFileHisInfoService.list(new QueryWrapper<FinancialBasicFileHisInfo>()
                .eq("financial_customer_his_info_id", id));
        ArrayList<FinancialBasicFileVo> basicFileVoList = new ArrayList<>();
        if (basicFileHistorys != null && basicFileHistorys.size() > 0) {
            for (FinancialBasicFileHisInfo basicFileHistory : basicFileHistorys) {
                FinancialBasicFileVo basicFileVo = autoFinancialBasicFileVo(basicFileHistory);
                basicFileVoList.add(basicFileVo);
            }
        }
        customerVo.setFinancialBasicFileVos(basicFileVoList);
        return customerVo;
    }

    @Override
    public FinancialCustomerVo findVoById(Long id) {
        FinancialCustomerVo customerVo = financialCustomerMapper.findVoById(id);
        if (customerVo != null) {
            Dictionary status = dictionaryService.get(customerVo.getStatus().getId());
            customerVo.setStatus(status);
        }
        return customerVo;
    }

    @Override
    public FinancialCustomerVo findHisVoById(Long id) {
        FinancialCustomerVo customerVo = financialCustomerMapper.findHisVoById(id);
        if (customerVo != null) {
            Dictionary status = dictionaryService.get(customerVo.getStatus().getId());
            customerVo.setStatus(status);
        }
        return customerVo;
    }

    /**
     * 填充状态
     **/
    public void autoStatus(FinancialCustomerVo financialCustomerVo) {
        if (financialCustomerVo.getStatus().getId() != null) {
            Dictionary statusDic = dictionaryService.get(financialCustomerVo.getStatus().getId());
            financialCustomerVo.setStatus(statusDic);
        }
    }

    public void autoStatus(FinancialCustomerInfo financialCustomer) {
        if (financialCustomer.getCustomerStatus() != null) {
            Dictionary statusDic = dictionaryService.get(financialCustomer.getCustomerStatus());
            financialCustomer.setStatusDictionary(statusDic);
        }
    }

    /****
     * 填充基础资料信息
     * @param basicFileHistory
     * @return
     */
    public FinancialBasicFileVo autoFinancialBasicFileVo(FinancialBasicFileHisInfo basicFileHistory) {
        FinancialBasicFileDictionary fileDictionary = financialBasicFileDictionaryService.getById(basicFileHistory.getFinancialBasicFileDicInfoId());
        FinancialBasicFileVo financialBasicFileVo = null;
        if (fileDictionary != null) {
            financialBasicFileVo = new FinancialBasicFileVo(fileDictionary);
            AttachmentDto attachmentDto = AttachmentDto.builder()
                    .setEntityId(basicFileHistory.getId())
                    .setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_CUSTOMER_BASIC_HIS_FILE)
                    .build();
            List<FileStorage> files = iSysAttachmentRefService.getFiles(attachmentDto);
            financialBasicFileVo.setFileStorageList(files);
        }
        return financialBasicFileVo;
    }

    //流程处理
    private void completeProcess(FinancialCustomerInfo financialCustomerInfo) {
        FinancialCustomerVo customerVo = findVoById(financialCustomerInfo.getId());
        //完成流程第一步基础资料附件上传，开启资方审核
        Map<String, Object> procVariables = new HashMap<>();
        procVariables.put(ConstantUtil.FINANCIAL_CUSTOMER_APPROVAL_ASSIGNEE,
                assigneeService.getIdByBusiness(financialCustomerInfo.getId(), ConstantUtil.FINANCIAL_CUSTOMER_PROCESS, ConstantUtil.ASSIGNEE_FINANCIAL_BACKER));
        Map<String, Object> msgVariables = new HashMap<>();
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "客户名称：" + customerVo.getCustomerName());
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "客户名称为“" + customerVo.getCustomerName() + "”的客户信息已经进入“"
                        + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.FINANCIAL_CUSTOMER_PROCESS) + "—formBusiness”阶段，"
                        + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
        FinancialCustomerHisInfo customerHisInfo = addHistoryFinancialBasicFile(financialCustomerInfo);
        Dictionary status = dictionaryService.getByCode(FinancialCustomerStatusDict.ChildEnum.FINANCIAL_CUSTOMER_UNDER_APPROVAL.getCode());
        financialCustomerInfo.setCustomerStatus(status.getId());
        financialCustomerMapper.updateById(financialCustomerInfo);
        Boolean result = flowableService.completeMyTask(financialCustomerInfo.getTaskId(), financialCustomerInfo, procVariables,
                ConstantConversionUtil.processApprovalResult.get("pass"), customerHisInfo.getId(), msgVariables, ConstantUtil.FINANCIAL_CUSTOMER_PROCESS);
        if (result == null || !result) {
            throw new ValidatorException(CodeUtil.FAIL, "基础资料提交时出错啦！");
        }
    }

    private FinancialCustomerHisInfo addHistoryFinancialBasicFile(FinancialCustomerInfo financialCustomerInfo) {
        FinancialCustomerHisInfo customerHisInfo = new FinancialCustomerHisInfo();
        customerHisInfo.setFinancialCustomerInfoId(financialCustomerInfo.getId());
        financialCustomerHisInfoService.save(customerHisInfo);
        List<FinancialBasicFileInfo> basicFileInfos = financialBasicFileInfoService.list(new QueryWrapper<FinancialBasicFileInfo>().eq("financial_customer_info_id", financialCustomerInfo.getId()));
        for (FinancialBasicFileInfo basicFileInfo : basicFileInfos) {
            AttachmentDto attachmentDto = AttachmentDto.builder()
                    .setEntityId(basicFileInfo.getId())
                    .setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_CUSTOMER_BASIC_FILE)
                    .build();
            List<FileStorage> oldFiles = iSysAttachmentRefService.getFiles(attachmentDto);
            FinancialBasicFileHisInfo history = new FinancialBasicFileHisInfo();
            history.setFinancialBasicFileDicInfoId(basicFileInfo.getFinancialBasicFileDicInfoId());
            //保存历史
            history.setFinancialCustomerHisInfoId(customerHisInfo.getId());
            financialBasicFileHisInfoService.save(history);
            AttachmentDto attachmentDtoHis = AttachmentDto.builder()
                    .setEntityId(history.getId())
                    .setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_CUSTOMER_BASIC_HIS_FILE)
                    .build();
            iSysAttachmentRefService.saveFileAndRefHis(oldFiles, attachmentDtoHis);
        }
        return customerHisInfo;
    }


}
