package yem.wmc.ydn.formplugin.dynamic;

import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.form.chart.*;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.sdk.plugin.Plugin;
import yem.base.common.utils.DateUtil;
import yem.base.common.utils.DynamicObjectUtil;

import java.math.BigDecimal;
import java.util.*;

/**
 * 动态表单插件
 */
public class PersonnelLineDynamic extends AbstractFormPlugin implements Plugin {
    @Override
    public void afterCreateNewData(EventObject e) {
        Long currUserId = RequestContext.get().getCurrUserId();
        this.getModel().setValue("yem_operator", currUserId);//默认当前人员  到项目设置默认
        Map<String, Map<String, BigDecimal>> data = getData(currUserId);
        drawChart(data);
    }

    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        String name = e.getProperty().getName();
        switch (name){
            case "yem_operator":
                DynamicObject yem_operator = (DynamicObject) this.getModel().getValue("yem_operator");
                Long currUserId = yem_operator != null ? yem_operator.getLong("id") : RequestContext.get().getCurrUserId();
                Map<String, Map<String, BigDecimal>> data = getData(currUserId);
                drawChart(data);
                break;

            default:
                break;
        }
    }

    private void drawChart(Map<String, Map<String, BigDecimal>> data) {
        PointLineChart chart = this.getControl("yem_personnelneedline");
        drawChart(chart, data, "", "");
    }

    /**
     * 点线图控件赋值
     * @param  pointLineChart 点线图控件实体
     * @param  data   数据
     *                key： x轴数据
     *                value： key：所属线条 类型/名称
     *                       value：所属线条的 y轴数据
     * @param  x_name x轴名称
     * @param  y_name y轴名称
     * */
    public void drawChart(PointLineChart pointLineChart, Map<String, Map<String, BigDecimal>> data
            , String x_name, String y_name) {
        pointLineChart.clearData();
        // 创建分类轴，X轴方式展现
        Axis categoryAxis = createCategoryAxis(pointLineChart, x_name, true);

        // 设置分类轴nametextstyle属性，
        Map<String, Object> nametextstyle = new HashMap<String, Object>();
        nametextstyle.put("color", "#000000");
        nametextstyle.put("fontSize", 15);
        categoryAxis.setPropValue("nameTextStyle", nametextstyle);

        // 设置分类轴名称位置属性，end表示在最后
        categoryAxis.setPropValue("nameLocation", new String("end"));

        // 设置分类轴分类值显示位置，bottom表示在下
        categoryAxis.setPropValue("position", "bottom");
        // 设置分类轴分类值liaxisLabel属性
        Map<String, Object> axislabel = new HashMap<>();
        Map<String, Object> textstyle = new HashMap<>();
        textstyle.put("color", "#000000");
        textstyle.put("fontSize", "16");
        axislabel.put("textStyle", textstyle);
        categoryAxis.setPropValue("axisLabel", axislabel);
        // 设置分类轴数据
        categoryAxis.setCategorys(contructCatetoryData(data));

        // 创建数据轴，name为其名字。
        Axis ValueAxis = createValueAxis(pointLineChart, y_name, false);
        // 设置数据轴的nameTextStyle属性
        Map<String, Object> yAxisnametextstyle = new HashMap<>();
        yAxisnametextstyle.put("color", "#000000");
        yAxisnametextstyle.put("fontSize", 15);
        ValueAxis.setPropValue("nameTextStyle", yAxisnametextstyle);

        // 创建折线并赋值
        List<String> titles = getTitles(data);
        // 创建颜色集合
        for (int i = 0; i < titles.size(); i++) {
            String color = "未完成".equals(titles.get(i)) ? "#FFC107" : "#1BC85E";
            // 创建折线
            createLineSeries(pointLineChart, titles.get(i), contructValueData(titles.get(i), data),
                    color);
        }

        // 设置图的边距
//        pointLineChart.setMargin(Position.left, "20px");

        // 设置图例的位置
        pointLineChart.setLegendPropValue("right", "8%");
        pointLineChart.setLegendPropValue("top", "8%");

        // 设置图例中文字的字体大小和颜色等
        Map<String, Object> legendtextstyle = new HashMap<>();
        legendtextstyle.put("fontSize", 18);
        legendtextstyle.put("color", "#000000");
        pointLineChart.setLegendPropValue("textStyle", legendtextstyle);
        // 刷新图标
        pointLineChart.refresh();
    }

    public static Axis createValueAxis(PointLineChart pointLineChart, String name, boolean isx) {
        Axis axis = null;
        if (isx)
            axis = pointLineChart.createXAxis(name, AxisType.value);
        else
            axis = pointLineChart.createYAxis(name, AxisType.value);

        // 创建一个map存储y轴的复杂属性的属性-值对
        Map<String, Object> axisTick = new HashMap<>();
        axisTick.put("show", true);
        axis.setPropValue("axisTick", axisTick);

        // 创建一个map存储y轴的复杂属性的属性-值对
        Map<String, Object> splitLine = new HashMap<>();
        Map<String, Object> lineStyle = new HashMap<>();
        lineStyle.put("type", "dotted");
        lineStyle.put("color", "#E2E2E2");
        splitLine.put("lineStyle", lineStyle);
        axis.setPropValue("splitLine", splitLine);
        pointLineChart.setShowTooltip(true);

        return axis;
    }

    public static Collection<BigDecimal> contructValueData(String title, Map<String, Map<String, BigDecimal>> data) {
        // 金额数据
        List<BigDecimal> valueDatas = new ArrayList<>();
        Collection<Map<String, BigDecimal>> values = data.values();
        for (Map<String, BigDecimal> map : values) {
            // 获取每月的不同费用项目所对应的总计金额
            BigDecimal totalPrice = map.get(title);
            if (totalPrice != null) {
                valueDatas.add(totalPrice);
            } else {
                // 如果某一月没有某一个费用项目时给零值
                valueDatas.add(BigDecimal.ZERO);
            }
        }
        return valueDatas;
    }

    public List<String> contructCatetoryData(Map<String, Map<String, BigDecimal>> data) {
        // 月份数据
        List<String> categoryData = new ArrayList<>(data.keySet());
//        Collections.sort(categoryData);
        Correctorder(categoryData);
        return categoryData;
    }

    public void Correctorder(List<String> keysList) {
        // 按月份顺序排序
        List<String> orderedMonths = Arrays.asList(
                "一月", "二月", "三月", "四月", "五月",
                "六月", "七月", "八月", "九月", "十月",
                "十一月", "十二月"
        );

        // 使用自定义排序
        keysList.sort(Comparator.comparingInt(month ->
                orderedMonths.indexOf(month) == -1 ? Integer.MAX_VALUE : orderedMonths.indexOf(month)
        ));
    }

    public static Axis createCategoryAxis(PointLineChart pointLineChart, String name, boolean isx) {
        Axis axis = null;
        if (isx)
            axis = pointLineChart.createXAxis(name, AxisType.category);
        else
            axis = pointLineChart.createYAxis(name, AxisType.category);

        // 创建一个map存储x轴的复杂属性的属性-值对
        Map<String, Object> axisTick = new HashMap<>();
        axisTick.put("interval", 0);

        axisTick.put("show", true);
        axisTick.put("grid", Position.left);
        axis.setPropValue("axisTick", axisTick);
        return axis;
    }

    public static void createLineSeries(PointLineChart chart, String name, Collection<BigDecimal> collection, String color) {
        // 折线的名字
        LineSeries expireSeries = chart.createSeries(name);

        // 设置折线上文本的相关属性
        Label label = new Label();
        label.setShow(false);
        label.setColor("#000000");
        expireSeries.setLabel(label);
        // 连线颜色
        expireSeries.setItemColor(color);
        // 动画效果
        expireSeries.setAnimationDuration(2000);
        // 该点纵坐标的值setData(Number[] data)
        expireSeries.setData((Number[]) collection.toArray(new Number[0]));
    }

    public static List<String> getTitles(Map<String, Map<String, BigDecimal>> data) {
        ArrayList<String> titles = new ArrayList<>();
        Collection<Map<String, BigDecimal>> values = data.values();
        for (Map<String, BigDecimal> map : values) {
            Set<String> keySet = map.keySet();
            for (String string : keySet) {
                if (!titles.contains(string)) {
                    titles.add(string);
                }
            }
        }
        return titles;
    }

    public Map<String, Map<String, BigDecimal>> getData(Long currUserId) {
        Date yearFirst = DateUtil.getCurrYearFirst();//本年第一天
        Date yearLast = DateUtil.getCurrYearLast();//本年最后一天
        List<QFilter> qFilters = new ArrayList<>();
        qFilters.add(new QFilter("yem_date", QCP.large_equals, yearFirst));
        qFilters.add(new QFilter("yem_date", QCP.less_equals, yearLast));
        qFilters.add(new QFilter("yem_operator", QCP.equals, currUserId));
        String[] monthNames = {"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"};
        String selectFields = DynamicObjectUtil.getSelectfields("yem_ca_homedate", false);
        DynamicObject[] ca_homedate = BusinessDataServiceHelper.load("yem_ca_homedate", selectFields,
                qFilters.toArray(new QFilter[0]), "yem_date");
        Map<String, Map<String, BigDecimal>> datas = new HashMap<>();

        for (DynamicObject homedate : ca_homedate) {
            Date yem_date = homedate.getDate("yem_date");
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(yem_date);
            int month = calendar.get(Calendar.MONTH); // 获取月份，0-11
            String monthName = monthNames[month];
            String type = homedate.getBoolean("yem_isfinish") ? "未完成" : "已完成";
            BigDecimal yem_qty = homedate.getBigDecimal("yem_qty");

            // 获取或创建该月的完成数量映射
            Map<String, BigDecimal> diggingsMap = datas.computeIfAbsent(monthName, k -> new HashMap<>());

            // 累加当前矿区的数量
            diggingsMap.put(type, diggingsMap.getOrDefault(type, BigDecimal.ZERO).add(yem_qty));

        }

        for (String key: monthNames) {
            if(!datas.keySet().contains(key)){
                Map<String, BigDecimal> map = new HashMap<>();
                map.put("未完成", BigDecimal.ZERO);
                map.put("已完成", BigDecimal.ZERO);
                datas.put(key, map);
            }
        }
        return datas;
    }
}