package com.tashow.cloud.sdk.feishu.util;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import org.springframework.stereotype.Component;

/**
 * 图表生成工具类
 * 用于生成监控数据图表
 */
@Component
public class ChartImageGenerator {

    /**
     * 监控数据点类
     */
    public static class MonitoringDataPoint {
        private String timestamp; // 时间戳，格式如 "13:54"
        private int successCount; // 成功数量
        private int failureCount; // 失败数量

        public MonitoringDataPoint(String timestamp, int successCount, int failureCount) {
            this.timestamp = timestamp;
            this.successCount = successCount;
            this.failureCount = failureCount;
        }

        public String getTimestamp() {
            return timestamp;
        }

        public int getSuccessCount() {
            return successCount;
        }

        public int getFailureCount() {
            return failureCount;
        }
    }

    /**
     * 生成监控仪表盘图像
     * @param outputFile 输出文件
     * @param monitoringData 监控数据
     * @throws IOException 如果图像创建失败
     */
    public void generateDashboardImage(File outputFile, List<MonitoringDataPoint> monitoringData) throws IOException {
        generateDashboardImage(outputFile, monitoringData, null);
    }
    
    /**
     * 生成监控仪表盘图像（带错误信息）
     * @param outputFile 输出文件
     * @param monitoringData 监控数据
     * @param errorMessage 错误信息，如为null则不显示
     * @throws IOException 如果图像创建失败
     */
    public void generateDashboardImage(File outputFile, List<MonitoringDataPoint> monitoringData, String errorMessage) throws IOException {
        int width = 850;
        int height = 350; // 减小高度，原来是550
        int padding = 70;
        int topPadding = 30; // 减少顶部空白，使用单独的顶部padding值

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = image.createGraphics();

        // 启用抗锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

        // 设置背景为白色
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, width, height);
        
        // 添加科技感背景网格
        drawTechBackground(g2d, width, height);

        // 计算图表区域
        int chartWidth = width - padding * 2;
        int chartHeight = height - padding - topPadding; // 调整图表高度计算

        // 绘制水平网格线
        Font labelFont = new Font("Microsoft YaHei", Font.PLAIN, 12);
        g2d.setFont(labelFont);
        FontMetrics metrics = g2d.getFontMetrics(labelFont);

        // 找出最大值以确定y轴的刻度
        int maxValue = 0;
        for (MonitoringDataPoint point : monitoringData) {
            maxValue = Math.max(maxValue, Math.max(point.getSuccessCount(), point.getFailureCount()));
        }

        // 向上调整10%，确保有足够空间显示数据
        maxValue = (int)(maxValue * 1.1);
        
        // 如果最大值太小，设置一个最小值确保图表可读性
        if (maxValue < 10) {
            maxValue = 10;
        }

        // 向上取整到合适的刻度
        if (maxValue <= 100) {
            // 小于100时，取整到10的倍数
            maxValue = ((maxValue + 9) / 10) * 10;
        } else if (maxValue <= 1000) {
            // 100-1000时，取整到50的倍数
            maxValue = ((maxValue + 49) / 50) * 50;
        } else {
            // 大于1000时，取整到100的倍数
            maxValue = ((maxValue + 99) / 100) * 100;
        }

        // 动态计算y轴刻度
        int yDivisions = 5; // Y轴分段数
        int yStep = maxValue / yDivisions;

        // 绘制水平网格线
        for (int i = 0; i <= yDivisions; i++) {
            int y = height - padding - (i * chartHeight / yDivisions);
            
            // 科技感网格线
            g2d.setColor(new Color(220, 220, 240, 100));
            g2d.setStroke(new BasicStroke(0.8f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 0, new float[]{3}, 0));
            g2d.drawLine(padding, y, width - padding, y);

            // 添加y轴标签
            String yLabel = String.format("%d", i * yStep);
            int labelWidth = metrics.stringWidth(yLabel);
            g2d.setColor(new Color(80, 80, 120));
            g2d.drawString(yLabel, padding - labelWidth - 10, y + metrics.getHeight() / 2 - 2);
        }

        // 绘制垂直网格线和X轴标签
        int totalPoints = monitoringData.size();
        for (int i = 0; i < totalPoints; i++) {
            int x = padding + (i * chartWidth / (totalPoints - 1));
            
            // 科技感垂直网格线
            g2d.setColor(new Color(220, 220, 240, 100));
            g2d.setStroke(new BasicStroke(0.8f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 0, new float[]{3}, 0));
            g2d.drawLine(x, topPadding, x, height - padding); // 调整网格线顶部起点

            // 添加每个点对应的时间标签
            if (i % 2 == 0 || i == totalPoints - 1) { // 每隔1个点显示标签，减少拥挤感
                String timeLabel = monitoringData.get(i).getTimestamp();
                int labelWidth = metrics.stringWidth(timeLabel);
                g2d.setColor(new Color(80, 80, 120));
                g2d.drawString(timeLabel, x - labelWidth / 2, height - padding + 20);
            }
        }

        // 绘制成功线（荧光蓝色）- 使用带标签的方法替代原方法
        drawGlowingLineWithLabels(g2d, 
            calculateXPoints(totalPoints, padding, chartWidth), 
            calculateSuccessYPoints(monitoringData, totalPoints, height, padding, chartHeight, yDivisions, yStep),
            new Color(0, 191, 255), new Color(0, 120, 215), 4.0f,
            monitoringData, true);

        // 绘制失败线（荧光红色）- 使用带标签的方法替代原方法
        drawGlowingLineWithLabels(g2d, 
            calculateXPoints(totalPoints, padding, chartWidth), 
            calculateFailureYPoints(monitoringData, totalPoints, height, padding, chartHeight, yDivisions, yStep),
            new Color(255, 50, 100), new Color(200, 30, 80), 4.0f,
            monitoringData, false);

        // 绘制图表边框
        g2d.setColor(new Color(210, 210, 230));
        g2d.setStroke(new BasicStroke(1.5f));
        g2d.drawRect(padding, topPadding, chartWidth, chartHeight); // 调整边框位置
        
        // 释放资源
        g2d.dispose();

        // 在底部添加错误信息
        // 重新获取图像的Graphics2D对象
        g2d = image.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setColor(new Color(100, 100, 130));
        g2d.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
        
        // 使用动态传入的错误信息，而非硬编码
        if (errorMessage != null && !errorMessage.trim().isEmpty()) {
            g2d.drawString(errorMessage, 70, height - 10);
        }
        
        g2d.dispose();

        // 保存图像
        ImageIO.write(image, "png", outputFile);
    }
    
    /**
     * 添加科技感背景
     */
    private void drawTechBackground(Graphics2D g2d, int width, int height) {
        g2d.setColor(new Color(240, 240, 250, 120));
        g2d.setStroke(new BasicStroke(0.5f));
        
        // 小网格
        int smallGridSize = 15;
        for (int x = 0; x < width; x += smallGridSize) {
            g2d.drawLine(x, 0, x, height);
        }
        for (int y = 0; y < height; y += smallGridSize) {
            g2d.drawLine(0, y, width, y);
        }
    }
    
    /**
     * 绘制发光线条
     */
    private void drawGlowingLine(Graphics2D g2d, int[] xPoints, int[] yPoints, Color mainColor, Color glowColor, float thickness) {
        int totalPoints = xPoints.length;
        
        // 绘制发光效果（外层）
        g2d.setColor(new Color(glowColor.getRed(), glowColor.getGreen(), glowColor.getBlue(), 80));
        g2d.setStroke(new BasicStroke(thickness + 4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        for (int i = 0; i < totalPoints - 1; i++) {
            g2d.drawLine(xPoints[i], yPoints[i], xPoints[i + 1], yPoints[i + 1]);
        }
        
        // 绘制发光效果（中层）
        g2d.setColor(new Color(glowColor.getRed(), glowColor.getGreen(), glowColor.getBlue(), 120));
        g2d.setStroke(new BasicStroke(thickness + 2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        for (int i = 0; i < totalPoints - 1; i++) {
            g2d.drawLine(xPoints[i], yPoints[i], xPoints[i + 1], yPoints[i + 1]);
        }
        
        // 绘制主线
        g2d.setColor(mainColor);
        g2d.setStroke(new BasicStroke(thickness, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        for (int i = 0; i < totalPoints - 1; i++) {
            g2d.drawLine(xPoints[i], yPoints[i], xPoints[i + 1], yPoints[i + 1]);
        }
        
        // 绘制高亮数据点
        for (int i = 0; i < totalPoints; i++) {
            // 外发光
            g2d.setColor(new Color(glowColor.getRed(), glowColor.getGreen(), glowColor.getBlue(), 80));
            g2d.fillOval(xPoints[i] - 6, yPoints[i] - 6, 12, 12);
            
            // 中发光
            g2d.setColor(new Color(mainColor.getRed(), mainColor.getGreen(), mainColor.getBlue(), 150));
            g2d.fillOval(xPoints[i] - 4, yPoints[i] - 4, 8, 8);
            
            // 内部点
            g2d.setColor(Color.WHITE);
            g2d.fillOval(xPoints[i] - 2, yPoints[i] - 2, 4, 4);
        }
    }
    
    /**
     * 绘制带有数值标签的发光线条
     */
    private void drawGlowingLineWithLabels(Graphics2D g2d, int[] xPoints, int[] yPoints, 
                                              Color mainColor, Color glowColor, float thickness,
                                              List<MonitoringDataPoint> data, boolean isSuccess) {
        // 先绘制基本的发光线条
        drawGlowingLine(g2d, xPoints, yPoints, mainColor, glowColor, thickness);
        // 添加数值标签 - 使用普通字体而非粗体
        g2d.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
        FontMetrics metrics = g2d.getFontMetrics();
        
        for (int i = 0; i < xPoints.length; i++) {
            // 获取当前值
            int currentValue = isSuccess ? data.get(i).getSuccessCount() : data.get(i).getFailureCount();
            
            // 始终显示所有数据点的数值标签
            String label = String.valueOf(currentValue);
            int labelWidth = metrics.stringWidth(label);
            
            // 设置标签文本
            g2d.setColor(mainColor.darker());
            g2d.drawString(label, xPoints[i] - labelWidth/2, yPoints[i] - 5);
        }
    }
    
    /**
     * 计算X坐标点
     */
    private int[] calculateXPoints(int totalPoints, int padding, int chartWidth) {
        int[] points = new int[totalPoints];
        for (int i = 0; i < totalPoints; i++) {
            points[i] = padding + (i * chartWidth / (totalPoints - 1));
        }
        return points;
    }
    
    /**
     * 计算成功线的Y坐标点
     */
    private int[] calculateSuccessYPoints(List<MonitoringDataPoint> data, int totalPoints, int height, 
                                      int padding, int chartHeight, int yDivisions, int yStep) {
        int[] points = new int[totalPoints];
        for (int i = 0; i < totalPoints; i++) {
            int successScaled = (int)((double)data.get(i).getSuccessCount() * chartHeight / (yDivisions * yStep));
            points[i] = height - padding - successScaled;
        }
        return points;
    }
    
    /**
     * 计算失败线的Y坐标点
     */
    private int[] calculateFailureYPoints(List<MonitoringDataPoint> data, int totalPoints, int height, 
                                      int padding, int chartHeight, int yDivisions, int yStep) {
        int[] points = new int[totalPoints];
        for (int i = 0; i < totalPoints; i++) {
            int failureScaled = (int)((double)data.get(i).getFailureCount() * chartHeight / (yDivisions * yStep));
            points[i] = height - padding - failureScaled;
        }
        return points;
    }
} 