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

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lowagie.text.*;
import com.tuoheng.admin.entity.*;
import com.tuoheng.admin.enums.InspectionTypeEnum;
import com.tuoheng.admin.mapper.*;
import com.tuoheng.admin.service.report.query.GetInspectionFileStatusList;
import com.tuoheng.admin.utils.WordUtils;
import com.tuoheng.common.core.config.common.CommonConfig;
import com.tuoheng.common.core.utils.DateUtils;
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.core.io.UrlResource;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class GenerateReportWordService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private ChannelMapper channelMapper;

    @Autowired
    private QuestionTypeMapper questionTypeMapper;

    @Autowired
    private InspectionFileMapper inspectionFileMapper;

    /**
     * 创建word
     *
     * @param filepath
     * @param report
     * @param inspectionFileList
     * @return
     */
    public JsonResult buildWord(String filepath, String titleName, Report report, List<InspectionFile> inspectionFileList, List<InspectionFileHandle> inspectionFileHandleList) {
        WordUtils wordUtils = new WordUtils();
        wordUtils.getDocument().setPageSize(PageSize.A4);
        wordUtils.getDocument().setMargins(71f, 71f, 72f, 72f);
        try {
            wordUtils.openDocument(filepath);

            // 标题
            wordUtils.insertTitlePattern(titleName, wordUtils.rtfGsBt1);
            wordUtils.insertContext("报告编号：" + report.getReportCode(), 10, Font.NORMAL, Element.ALIGN_RIGHT, 20, 0, 0);

            wordUtils.insertTitlePatternThird("巡检信息", wordUtils.rtfGsBt3);
            Table inspectionTableTable = this.buildInspectionTable(report);
            wordUtils.getDocument().add(inspectionTableTable);

            wordUtils.insertTitlePatternThird("巡检结果", wordUtils.rtfGsBt3);
            Table inspectionResultTable = this.buildInspectionResultTable(report);
            wordUtils.getDocument().add(inspectionResultTable);

            wordUtils.insertTitlePatternThird("问题清单", wordUtils.rtfGsBt3);
            Table inspectionFileTable = this.buildInspectionFileTable(inspectionFileList, inspectionFileHandleList);
            wordUtils.getDocument().add(inspectionFileTable);
        } catch (DocumentException e) {
            log.info("生成报告word异常");
            throw new RuntimeException(e);
        } catch (IOException e) {
            log.info("生成报告word异常");
            throw new RuntimeException(e);
        } finally {
            try {
                wordUtils.closeDocument();
            } catch (DocumentException e) {
                throw new RuntimeException(e);
            }
        }
        return JsonResult.success();
    }

    /**
     * 构建巡检信息
     */
    private Table buildInspectionTable(Report report) throws DocumentException {
        Table table = new Table(2);//生成一表格
        table.setOffset(1f);
        int width2[] = {1, 1};
        table.setWidths(width2);//设置系列所占比例
        table.setWidth(100);
        table.setAutoFillEmptyCells(true);
        table.setAlignment(Element.ALIGN_CENTER);   //居中显示
        table.setAlignment(Element.ALIGN_MIDDLE);   //垂直居中显示

        Font font = new Font();
        font.setSize(10.5f);
        font.setStyle(Font.NORMAL);
        for (int i = 0; i < 18; i++) {
            Cell cell = new Cell();
            String str = null;
            cell.setVerticalAlignment(Element.ALIGN_LEFT);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);

            if (i == 0) {
                str = "任务编号";
            } else if (i == 1) {
                str = report.getInspectionCode();
            } else  if (i == 2) {
                str = "任务名称";
            } else if (i == 3) {
                str = report.getInspectionName();
            } /*else if (i == 4) {
                str = "气象信息";
            } else if (i == 5) {
                str = report.getWeather();
            } */else if (i == 4) {
                str = "巡检部门";
            } else if (i == 5) {
                str = this.getDeptName(report.getDeptId());
            } else if (i == 6) {
                str = "巡检方式";
            } else if (i == 7) {
                if (report.getInspectionType() == 1) {
                    str = "无人机";
                } else if (report.getInspectionType() == 2) {
                    str = "机场巡逻";
                } else if (report.getInspectionType() == 3) {
                    str = "飞手执飞";
                }
            } else if (i == 8) {
                str = "巡查设备";
            } else if (i == 9) {
                // 机场任务没有设备名称，暂定使用机场名称作为设备名称
                if (InspectionTypeEnum.AIRPORT.getCode() == report.getInspectionType()) {
                    str = report.getAirportName();
                } else {
                    str = report.getEquipmentName();
                }
            } else if (i == 10) {
                str = "巡查开始时间";
            } else if (i == 11) {
                str = report.getExecutionStartTime() == null ? "" : DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, report.getExecutionStartTime());
            } else if (i == 12) {
                str = "巡查结束时间";
            } else if (i == 13) {
                str = report.getExecutionEndTime() == null ? "" : DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, report.getExecutionEndTime());
            } else if (i == 14) {
                str = "巡检片区";
            } else if (i == 15) {
                str = this.getRoadName(report.getChannelId());
            }
            Paragraph p = new Paragraph(str, font);
            cell.add(p);
            table.addCell(cell);
        }
        return table;
    }

    /**
     * 获取部门路名称
     */
    private String getDeptName(String deptId) {
        if (StringUtils.isEmpty(deptId)) {
            return "";
        }
        Dept dept = deptMapper.selectOne(new LambdaQueryWrapper<Dept>()
                .eq(Dept::getId, deptId)
                .eq(Dept::getMark, 1));
        if (null != dept) {
            return dept.getName();
        }
        return "";
    }

    /**
     * 获取航道名称
     */
    private String getRoadName(String channelId) {
        if (StringUtils.isEmpty(channelId)) {
            return "";
        }
        Channel channel = channelMapper.selectOne(new LambdaQueryWrapper<Channel>()
                .eq(Channel::getId, channelId)
                .eq(Channel::getMark, 1));
        if (null != channel) {
            return channel.getName();
        }
        return "";
    }

    /**
     * 构建巡检信息
     */
    private Table buildInspectionResultTable(Report report) throws DocumentException {
        List<QuestionType> questionTypeList = questionTypeMapper.selectList(new LambdaQueryWrapper<QuestionType>()
                .eq(QuestionType::getMark, 1));

        Table table = new Table(2); //生成一表格
        table.setOffset(1f);
        int width[] = {1, 1};
        table.setWidths(width); //设置系列所占比例
        table.setWidth(100);
        table.setAutoFillEmptyCells(true);
        table.setAlignment(Element.ALIGN_CENTER);   //居中显示
        table.setAlignment(Element.ALIGN_MIDDLE);   //垂直居中显示

        Font font = new Font();
        font.setSize(10.5f);
        font.setStyle(Font.NORMAL);

        Cell cell1 = this.getCell(font, "巡检内容");
        Cell cell2 = this.getCell(font, "巡检监测结果");

        table.addCell(cell1);
        table.addCell(cell2);

        QuestionType questionType;
        Cell questionTypeContentCell;
        Cell questionTypeCell;
        for (int i = 0; i < questionTypeList.size(); i++) {
            questionType = questionTypeList.get(i);
            String count = this.getCount(report.getInspectionId(), questionType.getCode());
            questionTypeContentCell = this.getCell(font, questionType.getContent());
            questionTypeCell = this.getCell(font, count);
            table.addCell(questionTypeContentCell);
            table.addCell(questionTypeCell);
        }
        return table;
    }

    private Cell getCell(Font font, String str) {
        Cell cell = new Cell();
        cell.setVerticalAlignment(Element.ALIGN_CENTER);    // 设置单元格的垂直对齐方式 ： 居中
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);   // 设置单元格的水平对齐方式 ：居中对齐
        cell.add(new Paragraph(str, font));
        return cell;
    }

    private String getCount(String inspectionId, String questionCode) {
        Integer count = inspectionFileMapper.selectCount(new LambdaQueryWrapper<InspectionFile>()
                .eq(InspectionFile::getInspectionId, inspectionId)
                .in(InspectionFile::getStatus, GetInspectionFileStatusList.getStatusList())
                .eq(InspectionFile::getQuestionCode, questionCode)
                .eq(InspectionFile::getMark, 1));
        return Integer.toString(count);
    }

    /**
     * 构建巡检问题信息
     */
    private Table buildInspectionFileTable(List<InspectionFile> inspectionFileList, List<InspectionFileHandle> inspectionFileHandleList) throws DocumentException, IOException {
        Table table = new Table(2); //生成一表格
        table.setOffset(1f);
        int width2[] = {1, 1};
        table.setWidths(width2);    //设置系列所占比例
        table.setWidth(100);
        table.setAutoFillEmptyCells(true);

        InspectionFile inspectionFile;
        Font font = new Font();
        font.setSize(10.5f);
        for (int i = 0; i < inspectionFileList.size(); i++) {
            inspectionFile = inspectionFileList.get(i);
            for (int j = 0; j < 7; j++) {
                font.setStyle(Font.NORMAL);
                Cell cell = new Cell();
                cell.setVerticalAlignment(Element.ALIGN_CENTER);    // 设置单元格的垂直对齐方式 ： 居中
                cell.setHorizontalAlignment(Element.ALIGN_CENTER);   // 设置单元格的水平对齐方式 ：居中对齐
                String str = "";
                if (j == 0) {
                    cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                    font.setSize(12);
                    str = "问题" + (i + 1);
                    cell.add(new Paragraph(str, font));
                    cell.setColspan(2);
                    font.setStyle(Font.BOLD);
                } else if (j == 1) {
                    str = "坐标";
                    cell.add(new Paragraph(str, font));
                } else if (j == 2) {
                    if (!StringUtils.isEmpty(inspectionFile.getLongitude())) {
                        str += inspectionFile.getLongitude();
                    }
                    if (StringUtils.isEmpty(str)) {
                        if (!StringUtils.isEmpty(inspectionFile.getLatitude())) {
                            str += inspectionFile.getLatitude();
                        }
                    } else {
                        if (!StringUtils.isEmpty(inspectionFile.getLatitude())) {
                            str += "," + inspectionFile.getLatitude();
                        }
                    }
                    cell.add(new Paragraph(str, font));
                } else if (j == 3) {
                    str = "问题描述";
                    cell.add(new Paragraph(str, font));
                } else if (j == 4) {
                    str = inspectionFile.getQuestionName();
                    cell.add(new Paragraph(str, font));
                } else if (j == 5) {
                    str = "问题图片";
                    cell.add(new Paragraph(str, font));
                } else if (j == 6) {
                    String imageUrl = inspectionFile.getFileImage();
                    cell = this.getImageCell(imageUrl);
                }
                table.addCell(cell);
            }

            if (CollectionUtil.isEmpty(inspectionFileHandleList)) {
                continue;
            }

            this.buildInspectionFileHandleTable(table, font, inspectionFile.getId(), inspectionFileHandleList);
        }
        return table;
    }

    private void buildInspectionFileHandleTable(Table table, Font font, String inspectionFileId, List<InspectionFileHandle> inspectionFileHandleList) throws MalformedURLException {
        Map<String, User> handleUserMap = this.getInspectionFileHandleUserMap(inspectionFileHandleList);
        Map<String, InspectionFileHandle> inspectionFileHandleMap = inspectionFileHandleList.stream().collect(Collectors.toMap(InspectionFileHandle::getInspectionFileId, Function.identity()));
        InspectionFileHandle inspectionFileHandle = inspectionFileHandleMap.get(inspectionFileId);
        if (null != inspectionFileHandle) {
            Cell handlerUserTitleCell = this.getCell(font, "处理人");
            User user = handleUserMap.get(inspectionFileHandle.getHandlerUser());
            Cell handlerUserDataCell;
            if (null != user) {
                handlerUserDataCell = this.getCell(font, user.getRealname());
            } else {
                handlerUserDataCell = this.getCell(font, "");
            }

            Cell handlerResultCell = this.getCell(font, "处理结果");
            Cell handlerResultDataCell = this.getCell(font, inspectionFileHandle.getHandlerResult());

            Cell handlerTimeCell = this.getCell(font, "处理时间");
            Cell handlerTimeDataCell = this.getCell(font, inspectionFileHandle.getHandlerTime() == null ? "" : DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, inspectionFileHandle.getHandlerTime()));

            table.addCell(handlerUserTitleCell);
            table.addCell(handlerUserDataCell);

            table.addCell(handlerResultCell);
            table.addCell(handlerResultDataCell);

            table.addCell(handlerTimeCell);
            table.addCell(handlerTimeDataCell);

            if (!StringUtils.isEmpty(inspectionFileHandle.getHandlerImage())) {
                String[] arr = inspectionFileHandle.getHandlerImage().split(",");
                List<String> list = Arrays.stream(arr).map(String::toString).collect(Collectors.toList());
                String imageUrl;
                for (int i = 0; i < list.size(); i++) {
                    Cell imageTileCell;
                    if (1 == list.size()) {
                       imageTileCell = this.getCell(font, "处理图片");
                    } else {
                       imageTileCell = this.getCell(font, "处理图片" + (i+1));
                    }
                    imageUrl = list.get(i);
                    Cell imageCell = this.getImageCell(imageUrl);
                    table.addCell(imageTileCell);
                    table.addCell(imageCell);
                }
            }
        }
    }

    /**
     *
     * 生成报告word表格处理图片
     *
     * @param imageUrl
     * @return
     * @throws MalformedURLException
     */
    private Cell getImageCell(String imageUrl) throws MalformedURLException {
        Cell imageCell = new Cell();
        imageCell.setVerticalAlignment(Element.ALIGN_CENTER);    // 设置单元格的垂直对齐方式 ： 居中
        imageCell.setHorizontalAlignment(Element.ALIGN_CENTER);   // 设置单元格的水平对齐方式 ：居中对齐

        String url = CommonConfig.imageURL +  imageUrl;
        if (new UrlResource(url).exists()) {
            try {
                Image image = Image.getInstance(url);
                image.setAlignment(Image.ALIGN_CENTER);
                image.scalePercent(100); //依照比例缩放
                image.setAbsolutePosition(200, 200);
                image.scaleToFit(200, 200);//自定义大
                imageCell.add(image);
            } catch (BadElementException e) {
                log.info("生成报告word表格处理图片异常");
                throw new RuntimeException(e);
            } catch (IOException e) {
                log.info("生成报告word表格处理图片异常");
                throw new RuntimeException(e);
            }
        } else {
            log.error("图片不存在！" + url);
            imageCell.add(new Paragraph(""));
        }
        return imageCell;
    }

    /**
     *
     * 获取问题处理人map
     *
     * @param inspectionFileHandleList
     * @return
     */
    private Map<String, User> getInspectionFileHandleUserMap(List<InspectionFileHandle> inspectionFileHandleList) {
        List<String> userIdList = inspectionFileHandleList.stream().map(o -> o.getHandlerUser()).collect(Collectors.toList());
        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>()
                .in(User::getId, userIdList)
                .eq(User::getMark, 1));

        Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
        return userMap;
    }
}
