package com.ruoyi.common.utils.asPose;

import cn.hutool.core.util.ObjectUtil;
import com.aspose.words.Shape;
import com.aspose.words.*;

import java.awt.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;

/**
 * @Author fuzhilin
 * @Date 2021/11/30 0030 16:05
 * @Description
 */
public class BarPercentStackedChart implements IReplacingCallback {

    private String key;
    private GenerateChartVO chartVO;

    public BarPercentStackedChart(String key, GenerateChartVO chartVO) {
        this.key = key;
        this.chartVO = chartVO;
    }

    @Override
    public int replacing(ReplacingArgs e) throws Exception {
        //获取当前节点
        Node currentNode = e.getMatchNode();
        //节点拆分处理当前匹配字段
        splitRun(currentNode, e.getMatchOffset());
        //获取当前文档
        Document document = (Document) currentNode.getDocument();
        DocumentBuilder builder = new DocumentBuilder(document);
        //将光标移动到指定节点
        builder.moveTo(currentNode);
        // 统计图标题
        String[] title = chartVO.getTitle();
        String name = chartVO.getName();
        // 统计图类型(参考：ChartType)
        int chartType = chartVO.getChartType();
        // 统计图字段
        String[] categories = chartVO.getCategories();
        // 统计图字段数据（二维数组支持多折线）
        double[][] values = chartVO.getValues();

        //设置统计图宽和高
        double height = chartVO.getHeight();
        if (ObjectUtil.isNull(height)) {
            height = 415;
        }
        double width = chartVO.getWidth();
        if (ObjectUtil.isNull(width)) {
            width = 415;
        }
        Boolean showTitle = chartVO.getShowTitle();
        Boolean dataPercent = chartVO.getDataPercent();
        Boolean coordinatePercent = chartVO.getCoordinatePercent();
        Boolean showLegendKey = chartVO.getShowLegendKey();
        //插入
        addChart(builder, chartType, name, title, categories, values, height, width,dataPercent, coordinatePercent,showLegendKey,showTitle);

       /* // 创建一个百分比堆叠条形图
        Shape chartShape = builder.insertChart(ChartType.BAR_PERCENT_STACKED, 400, 300);
        Chart chart = chartShape.getChart();
        // 设置图表标题
        ChartTitle title = chart.getTitle();

        title.setText(chartVO.getTitle());
        // 设置图表数据
        chart.getSeries().clear();
        List<BarPercentStackedVO.BarPercentStackedData> dataList = chartVO.getDataList();
        List<String> series = chartVO.getSeries();
        for (BarPercentStackedVO.BarPercentStackedData barPercentStackedData : dataList) {
            //chart.getSeries().add(barPercentStackedData.getSeries(), barPercentStackedData.getCategories(), barPercentStackedData.getValues());
        }*/
        return ReplaceAction.SKIP;
    }

    /**
     * 加载统计图
     *
     * @param builder
     * @param chatType   统计图类型
     * @param title      统计图标题
     * @param categories 统计图字段
     * @param values     统计图字段数据
     */
    private static void addChart(DocumentBuilder builder, int chatType, String title, String[] series, String[] categories, double[][] values, double height, double width,Boolean dataPercent, Boolean coordinatePercent,Boolean showLegendKey,Boolean showTitle) {
        //设置首行缩进
       /* builder.getParagraphFormat().setFirstLineIndent(0);
        builder.writeln("");*/
        try {
            Shape shape = builder.insertChart(chatType, width, height);
            shape.setVerticalAlignment(VerticalAlignment.CENTER);
            shape.setHorizontalAlignment(HorizontalAlignment.CENTER);
            // 不覆盖
            shape.setAllowOverlap(false);
            Chart chart = shape.getChart();
            ChartSeriesCollection seriesCollection = chart.getSeries();
            // 清除默认
            seriesCollection.clear();

            // 显示在下面
            chart.getLegend().setPosition(LegendPosition.BOTTOM);
            // 添加数据
            ChartTitle ct = chart.getTitle();
            ct.setText(title);
            ct.setOverlay(false);
            ct.setShow(showTitle);
            ChartLegend cl = chart.getLegend();
            cl.setOverlay(false);
            if (ChartType.COLUMN == chatType) {
                if (!coordinatePercent){
                    chart.getAxisY().getScaling().setMinimum(new AxisBound(1));
                }
            }
            if (coordinatePercent){
                chart.getAxisY().getNumberFormat().setFormatCode("0.00%");
                chart.getAxisX().getNumberFormat().setFormatCode("0.00%");
            }
            Color[] customColors=new Color[]{new Color(147,205,221),new Color(250,192,144),new Color(25 ,202 ,173 ) ,new Color(214  ,213  ,183 ),new Color(209   ,186   ,116 ),new Color(230   ,206   ,172 ),new Color(236   ,173   ,158 )
                    ,new Color(244   ,96   ,108 ),new Color(190    ,237    ,199 ),new Color(140    ,199    ,181 ),new Color(160   ,238    ,225 ),new Color(230,224,236)
            };
            String[] categoriesNew=new String[categories.length];
            for (int i = 0; i < categories.length; i++) {
                categoriesNew[i]="";
            }
            for (int i = 0; i < series.length; i++) {
                if(i==0){
                    ChartSeries chatSeries = seriesCollection.add(series[i], categories, values[i]);
                    chatSeries.getFormat().getFill().setForeColor(customColors[i%10]);
                }else{
                    if(i>10){
                        ChartSeries chatSeries = seriesCollection.add(series[i], categoriesNew, values[i]);
                        chatSeries.getFormat().getFill().setForeColor(AsposeUtil.getColor());
                    }else{
                        ChartSeries chatSeries = seriesCollection.add(series[i], categoriesNew, values[i]);
                        chatSeries.getFormat().getFill().setForeColor(customColors[i%10]);
                    }
                }

            }
            Iterator<ChartSeries> iterator = seriesCollection.iterator();
            int i=0;
            while (iterator.hasNext()) {
                ChartSeries seriesNew = iterator.next();
                //将图表中的折现设置为平滑
                seriesNew.setSmooth(true);
                // 设置数据显示
                ChartDataLabelCollection dataLabelCollection = seriesNew.getDataLabels();
                // 根据参数 showPercent 决定是否显示百分比，如果为 true，则显示百分比；否则，显示Y轴值。
                if (dataPercent){
                    dataLabelCollection.getNumberFormat().setFormatCode("0.00%");
                }
                // 所有参数为0不展示值
                if (!allValueIsZero(values[i])) {
                    dataLabelCollection.setShowValue(true);
                }
                // 设置数据标签的分隔符为换行符，即每个标签显示在一行。
                dataLabelCollection.setSeparator("\r\n");
                dataLabelCollection.setShowLegendKey(showLegendKey);   // 是否显示图例
                dataLabelCollection.setShowCategoryName(false);//是否显示系列的名称在系列旁边
                dataLabelCollection.setShowLeaderLines(false);
                dataLabelCollection.setShowSeriesName(false);//是否将图形标题显示在系列名称中
                dataLabelCollection.setShowBubbleSize(false);
                i++;
            }
            /*builder.writeln("");
            builder.getParagraphFormat().setFirstLineIndent(0);*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void createChart3(DocumentBuilder builder, String caption, String title1, String title2, String name1, String name2,String name3,
                                    String name4, double[] valueArr1, double[] valueArr2)throws Exception {
        Color[] customColors=new Color[]{new Color(147,205,221),new Color(250,192,144),new Color(25 ,202 ,173 ) ,new Color(214  ,213  ,183 ),new Color(209   ,186   ,116 ),new Color(230   ,206   ,172 ),new Color(236   ,173   ,158 )
                ,new Color(244   ,96   ,108 ),new Color(190    ,237    ,199 ),new Color(140    ,199    ,181 ),new Color(160   ,238    ,225 ),new Color(230,224,236)
        };
        Shape shape = builder.insertChart(ChartType.COLUMN_STACKED, 432, 252);
        Chart chart = shape.getChart();
        chart.getTitle().setText(caption);
        ChartSeriesCollection seriesColl = chart.getSeries();
        seriesColl.clear();
        seriesColl.add(title1,new String[]{name1,name2,name3,name4},valueArr1);
        seriesColl.add(title2,new String[]{"","","",""},valueArr2);
        Iterator<ChartSeries> iterator = seriesColl.iterator();
        int i=0;
        while (iterator.hasNext()) {
            ChartSeries series = iterator.next();
            //将图表中的折现设置为平滑
            series.setSmooth(true);
            ChartDataLabelCollection dataLabelCollection = series.getDataLabels();
            dataLabelCollection.setShowValue(true);
            Iterator<ChartDataLabel> iterator1 = dataLabelCollection.iterator();
            while (iterator1.hasNext()) {
                ChartDataLabel chartDataLabel = iterator1.next();
                chartDataLabel.setShowValue(true);
                chartDataLabel.setShowPercentage(true);
                chartDataLabel.setShowPercentage(true);
            }
            series.getFormat().getFill().setForeColor(customColors[i%10]);
            i++;
        }
        //数据标签显示在顶上
        chart.getLegend().setPosition(LegendPosition.TOP);
        chart.getTitle().setShow(true);
        chart.getTitle().setText(caption);
        //不覆盖 选择数据标题不覆盖在图形标题上 不然会字体重合
        chart.getTitle().setOverlay(false);
        chart.getLegend().setOverlay(false);
        builder.getParagraphFormat().setFirstLineIndent(2);
    }

    private void splitRun(Node currentNode, int position) {
        String text = currentNode.getText();
        Node newNode = currentNode.deepClone(true);
        if (text.length() >= position + this.key.length()) {
            ((Run) currentNode).setText(text.substring(position + this.key.length()));
        } else {
            int morlength = position + this.key.length() - text.length();
            ((Run) currentNode).setText("");
            Node tmpnode = currentNode;
            for (int i = 0; i < this.key.length(); i++) {
//                System.out.println(i);
                tmpnode = tmpnode.getNextSibling();
                String tmptext = tmpnode.getText();
//                System.out.println(tmptext);
//                System.out.println(morlength);
//                System.out.println("--------" + (tmptext.length() >= morlength));

                if (tmptext.length() >= morlength) {
                    ((Run) tmpnode).setText(tmptext.substring(morlength));
                    break;
                } else {
                    morlength = morlength - tmptext.length();
                    ((Run) tmpnode).setText("");
                }
            }
        }
        if (position > 0) {
            ((Run) newNode).setText(text.substring(0, position));
            currentNode.getParentNode().insertBefore(newNode, currentNode);
        }
    }

    /**
     * 判断图形（柱状图）所有值为0
     *
     * @param value
     * @return
     */
    public static boolean allValueIsZero(double[] value) {
        boolean res = true;
        for (double tmp : value) {
            if (tmp > 0) {
                res = false;
                break;
            }
        }
        return res;
    }

    public static void main(String[] args) throws Exception {
        // 创建文档对象
//        Document doc = new Document();
//        DocumentBuilder builder = new DocumentBuilder(doc);
//
//        // 统计图标题
//
//        String[] title = {"教育方式良好","教育方式基本适当","教育方式急需改善"};
//
//        // 统计图字段
//        String[] categories = {""};
//        // 统计图字段数据（二维数组支持多折线）
//        double[][] values = {
//                {2.2},  // 第一个数据系列的值
//                {3.1},
//                {3.2}// 第二个数据系列的值
//        };
//
//        addChart(builder, ChartType.COLUMN_STACKED, null, title, categories, values,215,316,true,true);
//
//        // 保存文档
//        doc.save("D://saveFile//test//StackedLineChart.docx");


        //通过Document空的构造函数，创建一个新的空的文档,如果有参数则是根据模板加载文档。
//        Document doc = new Document("D://12312.docx");
//        //动态增加内容 获取光标，这里面的`builder`相当于一个画笔，提前给他规定样式，然后他就能根据你的要求画出你想画的Word。这里的画笔使用的是就近原则，当上面没有定义了builder的时候，会使用默认的格式，当上面定义了某个格式的时候，使用最近的一个（即最后一个改变的样式）
//        DocumentBuilder builder = new DocumentBuilder(doc);
//        //将光标移动到文档末端
//        builder.moveToDocumentEnd();
//        //分页
//        builder.insertBreak(BreakType.PAGE_BREAK);
//        //换行
//        builder.insertParagraph();
//
//        //将数据转换为图表接受的格式
//        double[] thisMonths =  new double[]{78.36,98.14,56.25,68.24};
//        double[] lastMonths =  new double[]{98.51,14.74,57.25,78.24};
//        String[] names = {"三方协议","实习保险","专业匹配率","上岗率"};
//        //多维柱状图
//        createChart3(
//                builder,"备案过程数据统计","11月","12月",
//                names[0],names[1],names[2],names[3],thisMonths,lastMonths
//        );
//
//        //文件命名
//        String fileName = "D://AsposeWord1"+new SimpleDateFormat("MMddHHmmss").format(new Date())+".docx";
//        //文件保存
//        doc.save(fileName);
        Document doc = new Document();
        DocumentBuilder builder = new DocumentBuilder(doc);
        Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0);
        Chart chart = shape.getChart();
        chart.getTitle().setText("Data Labels With Different Number Format");

//删除默认生成的系列。
        chart.getSeries().clear();

//添加带有数据和数据标签的系列。
        ChartSeries series1 = chart.getSeries().add("Aspose Series 1",
                new String[] { "Category 1", "Category 2", "Category 3" },
                new double[] { 2.5, 1.5, 3.5 });

        series1.hasDataLabels(true);
        series1.getDataLabels().setShowValue(true);
        series1.getDataLabels().get(0).getNumberFormat().setFormatCode("\"$\"#,##0.00");
        series1.getDataLabels().get(1).getNumberFormat().setFormatCode("dd/mm/yyyy");
        series1.getDataLabels().get(2).getNumberFormat().setFormatCode("0.00%");

//或者将格式代码链接到源单元格。
        series1.getDataLabels().get(2).getNumberFormat().isLinkedToSource(true);
        String fileName = "D://AsposeWord1"+new SimpleDateFormat("MMddHHmmss").format(new Date())+".docx";
        //文件保存
        doc.save(fileName);

    }
}
