package com.tuoheng.admin.service.airData.report;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tuoheng.admin.entity.domain.AirData;
import com.tuoheng.admin.entity.domain.AirDataExport;
import com.tuoheng.admin.entity.domain.AirDataType;
import com.tuoheng.admin.entity.domain.Inspection;
import com.tuoheng.admin.entity.request.report.ExportReportRequest;
import com.tuoheng.admin.enums.MarkEnum;
import com.tuoheng.admin.mapper.AirDataExportMapper;
import com.tuoheng.admin.mapper.AirDataMapper;
import com.tuoheng.admin.mapper.AirDataTypeMapper;
import com.tuoheng.admin.mapper.InspectionMapper;
import com.tuoheng.admin.utils.AliyunOSSUtil;
import com.tuoheng.admin.utils.CurrentUserUtil;
import com.tuoheng.common.core.config.UploadFileConfig;
import com.tuoheng.common.core.exception.ServiceException;
import com.tuoheng.common.core.utils.DateUtils;
import com.tuoheng.common.core.utils.FileUtils;
import com.tuoheng.common.core.utils.JsonResult;
import com.tuoheng.common.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

@Slf4j
@Service
public class ExportReportService {

    @Autowired
    private InspectionMapper inspectionMapper;

    @Autowired
    private AirDataMapper airDataMapper;

    @Autowired
    private AirDataTypeMapper airDataTypeMapper;

    @Autowired
    private AirDataExportMapper airDataExportMapper;

    @Autowired
    private GenerateReportWordService generateReportWordService;

    @Autowired
    private AliyunOSSUtil aliyunOSSUtil;

    public JsonResult exportReport(ExportReportRequest request) {
        JsonResult result = this.check(request);
        if (0 != result.getCode()) {
            log.info("导出报告：校验失败：{}", result.getMsg());
            return result;
        }

        AirDataExport airDataExport = this.checkAirDataExport(request);
        if (ObjectUtil.isNotEmpty(airDataExport)) {
            return JsonResult.success( airDataExport.getOssUrl(), "导出成功");
        }

        Inspection inspection = (Inspection) result.getData();
        AirDataType airDataType = airDataTypeMapper.selectById(request.getAirDataTypeId());

        String filename = inspection.getName() + "-" + inspection.getCode()  + "-" + airDataType.getDataType() + ".doc";
        String filePath = UploadFileConfig.uploadFolder + "/report/" + filename;
        File fd = new File(UploadFileConfig.uploadFolder + "/report");
        if (!fd.exists()) {
            fd.mkdirs();
        }

        AirData beginAirData = airDataMapper.selectOne(new LambdaQueryWrapper<AirData>()
                .eq(AirData::getInspectionId, request.getInspectionId())
                .eq(AirData::getMark, MarkEnum.VALID.getCode())
                .orderByDesc(AirData::getCUtcTime)
                .last(" limit 1"));

        AirData endAirData = airDataMapper.selectOne(new LambdaQueryWrapper<AirData>()
                .eq(AirData::getInspectionId, request.getInspectionId())
                .eq(AirData::getMark, MarkEnum.VALID.getCode())
                .orderByAsc(AirData::getCUtcTime)
                .last(" limit 1"));

        // 生成word
        File f = new File(filePath);
        if (!f.exists() || f.length() < 1000) {
            String detectionTime = "";
            if (ObjectUtil.isNotEmpty(beginAirData)) {
                detectionTime += beginAirData.getCUtcTime();
            }
            detectionTime += "至";
            if (ObjectUtil.isNotEmpty(endAirData)) {
                detectionTime += endAirData.getCUtcTime();
            }
            result = generateReportWordService.buildWord(filePath, request, airDataType, detectionTime, inspection.getEquipmentMountCode());
            if (0 != result.getCode()) {
                log.info("导出报告业务：生成word失败：{}", result.getMsg());
                return result;
            }
        }

        // 上传到oss
        String ossUrl = this.uploadOss(filePath, filename);

        // 记录
        this.insertAirDataExport(request, inspection, airDataType, ossUrl);

        // 删除原文件
        FileUtils.deleteFile(filePath);

        return JsonResult.success(ossUrl, "导出成功");
    }

    /**
     * 检查参数
     *
     * @param request
     * @return
     */
    private JsonResult check(ExportReportRequest request) {
        if (StringUtils.isEmpty(request.getInspectionId())) {
            log.info("导出报告，任务ID为空，inspectionId={}", request.getInspectionId());
            throw new ServiceException("任务ID为空");
        }
        if (StringUtils.isEmpty(request.getAirDataTypeId())) {
            log.info("导出报告，大气数据类型为空，airDataType={}", request.getAirDataTypeId());
            throw new ServiceException("大气数据类型为空");
        }
        if (StringUtils.isEmpty(request.getOssUrl())) {
            log.info("导出报告，大气数据图片为空，ossUrl={}", request.getOssUrl());
            throw new ServiceException("大气数据图片为空");
        }
        Inspection inspection = inspectionMapper.selectById(request.getInspectionId());
        if (ObjectUtil.isEmpty(inspection)) {
            log.info("导出报告，任务不存在，inspectionId={}", request.getInspectionId());
            throw new ServiceException("任务不存在");
        }
        return JsonResult.success(inspection);
    }

    private AirDataExport checkAirDataExport(ExportReportRequest request) {
        AirDataExport airDataExport = airDataExportMapper.selectOne(new LambdaQueryWrapper<AirDataExport>()
                .eq(AirDataExport::getInspectionId, request.getInspectionId())
                .eq(AirDataExport::getAirDataTypeId, request.getAirDataTypeId())
                .eq(AirDataExport::getExportType, "report")
                .eq(AirDataExport::getGridSize, request.getGridSize())
                .eq(AirDataExport::getMark, MarkEnum.VALID.getCode()));
        return airDataExport;
    }

    private String uploadOss(String filePath, String filename) {
        File file = new File(filePath);
        InputStream in = null;
        String fileUrl = "";
        try {
            in = new FileInputStream(file);
            aliyunOSSUtil.uploadFile2OSS(in, filename);
            fileUrl = aliyunOSSUtil.getFileUrl(filename);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        return fileUrl;
    }

    /**
     * @param request
     * @param inspection
     * @param airDataType
     * @param ossUrl
     */
    private void insertAirDataExport(ExportReportRequest request, Inspection inspection, AirDataType airDataType, String ossUrl) {
        // 记录
        AirDataExport airDataExport = new AirDataExport();
        airDataExport.setTenantId(inspection.getTenantId());
        airDataExport.setInspectionId(request.getInspectionId());
        airDataExport.setExportType("report");
        airDataExport.setAirDataTypeId(airDataType.getId());
        airDataExport.setGridSize(request.getGridSize());
        airDataExport.setOssUrl(ossUrl);
        airDataExport.setCreateUser(CurrentUserUtil.getUserId());
        airDataExport.setCreateTime(DateUtils.now());
        Integer count = airDataExportMapper.insert(airDataExport);
        if (count <= 0) {
            log.info("添加大气数据报告导出记录失败");
        }
    }
}
