package com.xydl.cac.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.xydl.cac.entity.ModevTypePoint;
import com.xydl.cac.entity.NSensor;
import com.xydl.cac.excel.CacExcelListener;
import com.xydl.cac.excel.CacLine;
import com.xydl.cac.model.SensorDetail;
import com.xydl.cac.repository.ModevTypePointRepository;
import com.xydl.cac.service.ModevTypeService;
import com.xydl.cac.service.N103SensorService;
import com.xydl.cac.service.NSensorService;
import com.xydl.cac.service.ReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class ReportServiceImpl implements ReportService {

    @Resource
    NSensorService sensorService;
    @Resource
    ModevTypeService modevTypeService;
    @Resource
    ModevTypePointRepository typePointRepository;

    @Override
    public void exportSensor(SensorDetail<Map<String, Object>> detail, OutputStream output) throws Exception {

        // 导出Excel
        ExcelWriter excelWriter = EasyExcel.write(output).inMemory(true)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();

        this.writerSheet(excelWriter, 0, detail);

        excelWriter.finish();
    }

    @Override
    public void exportSensorList(List<SensorDetail<Map<String, Object>>> detailList, OutputStream output) throws Exception {
        // 导出Excel
        ExcelWriter excelWriter = EasyExcel.write(output).inMemory(true)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();

        for (int i = 0; i < detailList.size(); i++) {
            SensorDetail<Map<String, Object>> detail = detailList.get(i);
            this.writerSheet(excelWriter, i, detail);
        }

        excelWriter.finish();
    }

    private void writerSheet(ExcelWriter excelWriter, int idx, SensorDetail<Map<String, Object>> detail) throws Exception {
        // 表头
        List<List<String>> heads = new ArrayList<>();
        List<String> head = new ArrayList<>();
        head.add("时间");
        heads.add(head);
        for (ModevTypePoint point : detail.getPoints()) {
            head = new ArrayList<>();
            head.add(point.getFieldDesc() + "(" + point.getUnit() + ")");
            heads.add(head);
        }

        // 内容
        List<List<String>> list = new ArrayList<>();
        for (Map<String, Object> map : detail.getContent()) {
            List<String> line = new ArrayList<>();
            Object data = map.get("acquisitionTime");
            line.add(String.valueOf(data));
            for (ModevTypePoint point : detail.getPoints()) {
                data = map.get(point.getField());
                if (data == null) {
                    data = "";
                }
                line.add(String.valueOf(data));
            }
            list.add(line);
        }

        WriteSheet writeSheet = EasyExcel.writerSheet(idx, detail.getSensor().getName())
                .head(heads)
                .build();
        excelWriter.write(list, writeSheet);
    }

    @Override
    public void importCac(InputStream input) throws Exception {
        CacExcelListener listener = new CacExcelListener(sensorService, typePointRepository,
                modevTypeService.listAll());
        EasyExcel.read(input, CacLine.class, listener)
                .sheet(0)
                .doRead();
    }

    @Override
    public void exportLatest(Map<Integer, List<NSensor>> map, OutputStream output) throws Exception {

        // 导出Excel
        ExcelWriter excelWriter = EasyExcel.write(output).inMemory(true)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();


        int idx = 0;
        for (Integer key : map.keySet()) {
            List<NSensor> nSensors = map.get(key);

            this.writerSheetLatest(excelWriter, idx, nSensors);

            idx++;
        }

        excelWriter.finish();
    }

    public void writerSheetLatest(ExcelWriter excelWriter, int idx, List<NSensor> nSensors) {
        // 表头
        List<List<String>> heads = new ArrayList<>();
        List<String> head = new ArrayList<>();
        head.add("主设备名称");
        heads.add(head);
        head = new ArrayList<>();
        head.add("装置名称");
        heads.add(head);
        head = new ArrayList<>();
        head.add("时间");
        heads.add(head);
        for (ModevTypePoint point : nSensors.get(0).getTypePoints()) {
            head = new ArrayList<>();
            head.add(point.getFieldDesc() + "(" + point.getUnit() + ")");
            heads.add(head);
        }

        // 内容
        List<List<String>> list = new ArrayList<>();
        for (NSensor nSensor : nSensors) {
            List<String> line = new ArrayList<>();
            line.add(nSensor.getZsbName());
            line.add(nSensor.getName());
            HashMap<String, String> lastData = nSensor.getLastData();
            if (null != lastData) {
                String acquisitionTime = lastData.get("acquisitionTime");
                line.add(acquisitionTime);
                for (ModevTypePoint typePoint : nSensor.getTypePoints()) {
                    line.add(lastData.get(typePoint.getField()));
                }
            }
            list.add(line);
        }

        WriteSheet writeSheet = EasyExcel.writerSheet(idx, nSensors.get(0).getTypeName())
                .head(heads)
                .build();

        excelWriter.write(list, writeSheet);
    }

}
