package com.yonge.cooleshow.biz.dal.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.microsvc.toolkit.common.tools.DownloadManager;
import com.microsvc.toolkit.common.tools.ThreadPool;
import com.microsvc.toolkit.middleware.excel.analysis.AnalysisContext;
import com.microsvc.toolkit.middleware.oss.OssPluginContext;
import com.microsvc.toolkit.middleware.oss.impl.TencentOssPlugin;
import com.yonge.cooleshow.biz.dal.entity.FileImportInfo;
import com.yonge.cooleshow.biz.dal.execl.analysis.TenantAccountRecordImportAnalysis;
import com.yonge.cooleshow.biz.dal.execl.entity.TenantAccountRecordImport;
import com.yonge.cooleshow.biz.dal.service.EasyExcelService;
import com.yonge.cooleshow.biz.dal.service.ExcelAnalyseCoreService;
import com.yonge.cooleshow.biz.dal.service.FileImportInfoService;
import com.yonge.cooleshow.biz.dal.service.TenantAccountRecordService;
import com.yonge.cooleshow.biz.dal.wrapper.FileImportInfoWrapper;
import com.yonge.toolset.base.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Excel解析服务
 * Created by Eric.Shang on 2023/4/26.
 */
@Slf4j
@Service
public class ExcelAnalyseCoreServiceImpl implements ExcelAnalyseCoreService {

    @Autowired
    private EasyExcelService easyExcelService;
    @Autowired
    private OssPluginContext ossPluginContext;

    @Autowired
    private FileImportInfoService fileImportInfoService;

    @Autowired
    private TenantAccountRecordService tenantAccountRecordService;

    /**
     * 异步读取数据
     *
     * @param wrapper FileImportInfoWrapper.FileImportInfo
     */
    @Override
    public void asyncAnalyseReadExcelData(FileImportInfoWrapper.FileImportInfo wrapper) {

        ThreadPool.getExecutor().submit(() -> {
            try {

                switch (wrapper.getDataType()) {
                    case TENANT: // 课件导入
                        readTenantExcelData(wrapper);
                        break;
                    default:
                        break;
                }

                // 数据入库完成，更新数据记录
                FileImportInfoWrapper.FileImportInfo importInfo = FileImportInfoWrapper.FileImportInfo
                        .builder()
                        .id(wrapper.getId())
                        .finishTime(DateTime.now().toDate())
                        .build();
                fileImportInfoService.update(importInfo);

            }catch (NotOfficeXmlFileException e) {
                throw new BizException("上传文件格式版本太低");
            }catch (Exception e) {
                log.error("asyncAnalyseReadExcelData wrapper={}", wrapper.jsonString(), e);
            }
        });
    }


    @Override
    public FileImportInfo analyseReadExcelData(FileImportInfoWrapper.FileImportInfo wrapper) {
        try {
            switch (wrapper.getDataType()) {
                case TENANT: // 课件导入
                    readTenantExcelData(wrapper);
                    break;
                default:
                    break;
            }

            // 数据入库完成，更新数据记录
            FileImportInfoWrapper.FileImportInfo importInfo = FileImportInfoWrapper.FileImportInfo
                    .builder()
                    .id(wrapper.getId())
                    .finishTime(DateTime.now().toDate())
                    .build();
            fileImportInfoService.update(importInfo);
            return fileImportInfoService.getById(wrapper.getId());

        }catch (NotOfficeXmlFileException e) {
            throw new BizException("文件名格式错误");
        } catch (Exception e) {
            log.error("asyncAnalyseReadExcelData wrapper={}", wrapper.jsonString(), e);
        }
        return null;
    }

    /**
     * 单元测验数据导入
     * @param wrapper FileImportInfoWrapper.FileImportInfo
     */
    private void readTenantExcelData(FileImportInfoWrapper.FileImportInfo wrapper) {

        // 解析excel文件，生成EchoInfoAnalysis对象
        TenantAccountRecordImportAnalysis analysis = TenantAccountRecordImportAnalysis.build(easyExcelService).start(wrapper.getImportUrl()).get();

        AnalysisContext context = analysis.getContext();
        // 生成导入数据记录
        createFileImportRecord(wrapper, context);

        // 入库业务数据
        List<TenantAccountRecordImport> collect = analysis.getTenantAccountRecordImports().stream()
                .filter(x -> !Optional.ofNullable(x.getId()).orElse("").equals("."))
                .collect(Collectors.toList());
        if (context.getFailure() > 0) {
            log.info("readExaminationExcelData collect.size={}", collect.size());
            return;
        }

        tenantAccountRecordService.updatePostStatus(collect);
    }

    /**
     * 生成导入数据记录
     *
     * @param wrapper FileImportInfoWrapper.FileImportInfo
     * @param context AnalysisContext
     */
    private void createFileImportRecord(FileImportInfoWrapper.FileImportInfo wrapper, AnalysisContext context) {
        // 上传本地文件到OSS服务器（可选）
        {
            String respPath = context.getRespfilePath();
            log.info("createFileImportRecord respPath = {}", respPath);
            if (StringUtils.isNotEmpty(respPath) && context.getFailure() > 0
                    && FileUtils.getFile(respPath).exists()) {

                // 上传本地文件到OSS服务器
                String uploadFile = ossPluginContext.getPluginService(TencentOssPlugin.PLUGIN_NAME)
                        .uploadFile("excel-analysis", new File(respPath));
                if (StringUtils.isNotEmpty(uploadFile)) {
                    context.setResp(uploadFile);
                }
                log.info("createFileImportRecord uploadFile={}, resp={}", uploadFile, context.getResp());
                // 删除本地缓存文件
                DownloadManager.getInstance().deleteOnExit(respPath);
            }
        }

        // 生成excel数据上传，解析记录（可选）
        {
            wrapper.totalRow(context.getTotal())
                    .invalidRow(context.getFailure())
                    .insertRow(context.getSuccess())
                    .importTime(DateTime.now().toDate())
                    .respUrl(context.getResp())
                    .setId(IdWorker.getId());

            log.info("createFileImportRecord wrapper= {}", wrapper.jsonString());
            // 生成入库记录
            fileImportInfoService.add(wrapper);
        }
    }

}