package com.tuoheng.admin.service.inspectionfile.export;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tuoheng.admin.dto.InspectionFileExportExcelDto;
import com.tuoheng.admin.entity.*;
import com.tuoheng.admin.enums.InspectionFileStatusEnum;
import com.tuoheng.admin.enums.MarkEnum;
import com.tuoheng.admin.mapper.InspectionFileMapper;
import com.tuoheng.admin.mapper.InspectionMapper;
import com.tuoheng.admin.mapper.RoadInformationMapper;
import com.tuoheng.admin.mapper.SectionMapper;
import com.tuoheng.admin.request.inspectionfile.ExportInspectionFileRequest;
import com.tuoheng.admin.utils.CurrentUserUtil;
import com.tuoheng.admin.utils.DownloadUtil;
import com.tuoheng.admin.utils.excel.CustomCellWriteWidthHandler;
import com.tuoheng.admin.utils.excel.ImageModifyHandler;
import com.tuoheng.admin.utils.excel.StyleUtils;
import com.tuoheng.common.core.config.UploadFileConfig;
import com.tuoheng.common.core.config.common.CommonConfig;
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.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 导出任务问题清单业务层处理
 *
 * @author wanjing
 * @team tuoheng
 * @date 2023-11-23
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ExportInspectionFileByIdListService {

    private final InspectionMapper inspectionMapper;

    private final InspectionFileMapper inspectionFileMapper;

    private final RoadInformationMapper roadInformationMapper;

    private final SectionMapper sectionMapper;

    /**
     * 修改任务问题类型
     *
     * @return
     */
    public JsonResult exportExcle(HttpServletResponse response, ExportInspectionFileRequest request) {
        log.info("进入导出任务问题清单接口, request={}", request);
        User user = CurrentUserUtil.getUserInfo();
        JsonResult result = this.check(request);
        if (0 != result.getCode()) {
            log.info("导出任务问题清单：校验失败：{}", result.getMsg());
            return result;
        }
        List<InspectionFile> inspectionFileList = inspectionFileMapper.selectList(Wrappers.<InspectionFile>lambdaQuery()
                .eq(InspectionFile::getTenantId, user.getTenantId())
                .eq(InspectionFile::getInspectionId, request.getInspectionId())
                .eq(StringUtils.isNotEmpty(request.getQuestionCode()), InspectionFile::getQuestionCode, request.getQuestionCode())
                .eq(ObjectUtil.isNotEmpty(request.getStatus()), InspectionFile::getStatus, request.getStatus())
                .eq(InspectionFile::getMark, MarkEnum.VALID.getCode()));
        if (CollectionUtil.isEmpty(inspectionFileList)) {
            log.info("问题列表不存在， request={}", request);
            return JsonResult.success();
        }
        InspectionFile inspectionFile = inspectionFileList.get(0);
        Inspection inspection = inspectionMapper.selectById(inspectionFile.getInspectionId());
        if (ObjectUtil.isEmpty(inspection)) {
            log.info("该任务不存在， inspectionId={}", inspection.getId());
            return JsonResult.success();
        }

        String fileName = "疑似问题清单 - " + inspection.getCode() + ".xlsx";
        String filePath = UploadFileConfig.uploadFolder + "inspection_file/" + fileName;
        File fd = new File(UploadFileConfig.uploadFolder + "inspection_file");
        if (!fd.exists()) {
            fd.mkdirs();
        }

        List<InspectionFileExportExcelDto> inspectionFileExportExcelDtoList = this.buildInspectionFileExportExcelDto(inspection, inspectionFileList);

        this.easyExcel(inspection, inspectionFileExportExcelDtoList, filePath);

        DownloadUtil.download(response, filePath, fileName);

        FileUtils.deleteFile(filePath);

        return JsonResult.success();
    }

    /**
     * 检查参数
     *
     * @param request
     * @return
     */
    private JsonResult check(ExportInspectionFileRequest request) {
        if (StringUtils.isEmpty(request.getInspectionId())) {
            throw new ServiceException("问题ID为空");
        }
        return JsonResult.success();
    }

    private List<InspectionFileExportExcelDto> buildInspectionFileExportExcelDto(Inspection inspection, List<InspectionFile> inspectionFileList) {
        RoadInformation road = roadInformationMapper.selectById(inspection.getRoadId());
        Section section = sectionMapper.selectById(inspection.getSectionId());

        List<InspectionFileExportExcelDto> inspectionFileExportExcelDtoList = new ArrayList<>();
        InspectionFile inspectionFile;
        InspectionFileExportExcelDto inspectionFileExportExcelDto;
        for (int i = 0; i < inspectionFileList.size(); i++) {
            inspectionFile = inspectionFileList.get(i);
            inspectionFileExportExcelDto = new InspectionFileExportExcelDto();
            inspectionFileExportExcelDto.setSequence(i + 1);
            inspectionFileExportExcelDto.setQuestionName(inspectionFile.getQuestionName());
            try {
                inspectionFileExportExcelDto.setFileOriginal(new URL(CommonConfig.imageURL + inspectionFile.getFileOriginal()));
                inspectionFileExportExcelDto.setFileImage(new URL(CommonConfig.imageURL + inspectionFile.getFileImage()));
            } catch (MalformedURLException e) {
                throw new RuntimeException(e);
            }
            inspectionFileExportExcelDto.setLocation(inspectionFile.getLongitude() + "," + inspectionFile.getLatitude());
            if (ObjectUtil.isNotEmpty(road)) {
                inspectionFileExportExcelDto.setRoadName(road.getName());
            }
            if (ObjectUtil.isNotEmpty(section)) {
                inspectionFileExportExcelDto.setSectionName(section.getSectionRange());
            }
            if (InspectionFileStatusEnum.WAIT_CONFIRMED.getCode() == inspectionFile.getStatus()) {
                inspectionFileExportExcelDto.setStatus("待确认");
            } else if (InspectionFileStatusEnum.IGNORED.getCode() == inspectionFile.getStatus()) {
                inspectionFileExportExcelDto.setStatus("已忽略");
            } else if (InspectionFileStatusEnum.CONFIRMED.getCode() == inspectionFile.getStatus()) {
                inspectionFileExportExcelDto.setStatus("已确认");
            } else if (InspectionFileStatusEnum.GENERATE_ORDER.getCode() == inspectionFile.getStatus()) {
                inspectionFileExportExcelDto.setStatus("已生成工单");
            } else if (InspectionFileStatusEnum.PROCESSED.getCode() == inspectionFile.getStatus()) {
                inspectionFileExportExcelDto.setStatus("已处理");
            }
            inspectionFileExportExcelDtoList.add(inspectionFileExportExcelDto);
        }
        return inspectionFileExportExcelDtoList;
    }

    /**
     * 生成excel表格
     *
     * @param inspection
     * @param inspectionFileExportExcelDtoList
     * @param filePath
     * @return
     */
    private JsonResult easyExcel(Inspection inspection, List<InspectionFileExportExcelDto> inspectionFileExportExcelDtoList, String filePath) {
        log.info("文件输出目录及格式：filePathName={}", filePath);
        List<List<String>> heads = new ArrayList<>();
        String titleTable = "疑似问题清单";
        String titleTable2 = "巡检任务：" + inspection.getName() + "   巡检时间：" + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, inspection.getInspectionTime());
        String[] nameString = {"序号", "问题类型", "问题图片", "标注图片", "位置", "所属高速", "所属路段", "状态"};
        for (String excelName : nameString) {
            heads.add(Arrays.asList(titleTable, titleTable2, excelName));
        }
        //需要写出的表格（对应实体类）
        try {
            HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(StyleUtils.getHeadStyle(), StyleUtils.getContentStyle());
            EasyExcel.write(filePath, InspectionFileExportExcelDto.class).sheet("问题清单数据")
                    .head(heads)
                    .registerWriteHandler(new CustomCellWriteWidthHandler())
//                    .registerWriteHandler(new CustomCellWriteHeightConfig())
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    .registerWriteHandler(new ImageModifyHandler())
                    .doWrite(inspectionFileExportExcelDtoList); // 数据源
        } catch (Exception e) {
            log.info("生成问题清单excel异常");
            throw new RuntimeException(e);
        }
        log.info("生成问题清单excel成功");
        return JsonResult.success();
    }
}
