using CrazyStudio.Core.Common.Tools;
using HPPH;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core;

//public enum QuantizationAlgorithm { MedianCut, AdaptiveSpatial, NeuQuant }
//public enum QuantizationAlgorithm { MedianCut, AdaptiveSpatial }
public enum QuantizationAlgorithm { MedianCut }
public enum DitheringType { None, FloydSteinberg, Riemersma }

public class ColorVectorConverter
{
    private string _potraceExePath = "potrace.exe";
    private string _pngquantPath = "pngquant.exe"; // 需安装pngquant
    private string _pngnqPath = "pngnq.exe";       // 需安装pngnq
    private string _convertPath = "magick convert"; // ImageMagick的convert工具
    private bool _verbose = false;
    private int _colorCount = 16;                  // 目标颜色数量
    private QuantizationAlgorithm _quantAlgorithm = QuantizationAlgorithm.MedianCut;
    private DitheringType _dithering = DitheringType.None;
    private bool _stackTracing = true;             // 堆栈描摹
    private float _prescale = 1.0f;                // 预缩放比例（提升细节）
    private int maxHandleSize = 3072;
    public ColorVectorConverter(string potraceExePath, string pngquantPath, bool verbose = false)
    {
        _potraceExePath = potraceExePath;
        _pngquantPath = pngquantPath;
        _verbose = verbose;
    }

    public async Task ConvertToSvg(string inputFile, string outputFile, int colorCount = 16, float prescale = 1.0f,
                                        QuantizationAlgorithm quantAlgorithm = QuantizationAlgorithm.MedianCut,
                                        DitheringType dithering = DitheringType.None, bool stackTracing = false)
    {
        _colorCount = Math.Clamp(colorCount, 2, 256);
        //限制倍数到0.5-2倍
        _prescale = Math.Clamp(prescale, 0.5f, 2);
        _quantAlgorithm = quantAlgorithm;
        _dithering = dithering;
        _stackTracing = stackTracing;
        try
        {
            Image? originalImage = null;
            if (inputFile.StartsWith("https:") || inputFile.StartsWith("http:"))
            {
                originalImage = await HttpTool.GetImageFromUrlAsync(inputFile);
            }
            else
            {
#pragma warning disable CA1416 // 验证平台兼容性
                originalImage = Image.FromFile(inputFile);
#pragma warning restore CA1416 // 验证平台兼容性
            }
            using (originalImage)
            {
                Bitmap? scaledImage = null;
                int maxSize = Math.Max(originalImage.Width, originalImage.Height);
                if (maxSize * _prescale > maxHandleSize)
                {
                    int newWidth = 0, newHeight = 0;
                    if (originalImage.Width > originalImage.Height)
                    {
                        newWidth = maxHandleSize;
                        newHeight = (int)(originalImage.Height * (newWidth / (float)originalImage.Width));
                    }
                    else
                    {
                        newHeight = maxHandleSize;
                        newWidth = (int)(originalImage.Width * (newHeight / (float)originalImage.Height));
                    }
                    scaledImage = ResizeAndPreserveAlpha(originalImage, newWidth, newHeight);
                    _prescale = (float)(Math.Max(newWidth, newHeight)) / Math.Max(originalImage.Width, originalImage.Height);
                }
                else
                {
                    // 步骤1：预缩放并确保包含Alpha通道（关键：保留透明信息）
                    scaledImage = PrescaleAndPreserveAlpha(originalImage);
                }

                // 步骤2：颜色量化（保留透明通道）
                var quantizedImagePath = QuantizeImage(scaledImage!);
#pragma warning disable CA1416 // 验证平台兼容性
                var quantizedImage = new Bitmap(quantizedImagePath);
#pragma warning restore CA1416 // 验证平台兼容性
                // 步骤3：提取量化后的颜色表（排除透明色）
                var colorTable = ExtractColorTable(quantizedImage);

                if (_verbose)
                    Console.WriteLine($"量化完成，保留 {colorTable.Count} 种颜色（已排除透明）");

                // 步骤4：基于量化颜色表生成颜色段
                var colorSegments = CreateSegmentsFromColorTable(colorTable);
                // 步骤5：生成每个颜色段的掩码并矢量化（保留透明区域）
                var svgLayers = new List<string>();
                for (int i = 0; i < colorSegments.Count; i++)
                {
                    var segment = colorSegments[i];
                    var mask = CreateSegmentMask(quantizedImage, segment.Colors, colorSegments, i);
                    var svgLayer = VectorizeMask(mask, segment.AverageColor);
                    if (!string.IsNullOrEmpty(svgLayer))
                        svgLayers.Add(svgLayer);
                }

                quantizedImage.Dispose();
                if (File.Exists(quantizedImagePath)) File.Delete(quantizedImagePath);
                // 步骤6：合并图层并保存（确保SVG背景透明）

                float dpiX = scaledImage.HorizontalResolution;
                float dpiY = scaledImage.HorizontalResolution;

                SaveCombinedSvg(svgLayers, outputFile, scaledImage.Width, scaledImage.Height, dpiX, dpiY);
                scaledImage.Dispose();
                //Console.WriteLine($"SVG生成完成：{outputFile}");
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine($"转换失败：{ex.Message}");
            if (_verbose)
                Console.WriteLine(ex.StackTrace);
        }
    }

    #region 核心优化：保留透明通道

    /// <summary>
    /// 预缩放并确保Alpha通道存在（关键：保留原始透明信息）
    /// </summary>
    private Bitmap PrescaleAndPreserveAlpha(Image image)
    {
        int newWidth = (int)(image.Width * _prescale);
        int newHeight = (int)(image.Height * _prescale);
        // 强制使用带Alpha通道的格式
        var scaled = new Bitmap(newWidth, newHeight, PixelFormat.Format32bppArgb);
        using (var g = Graphics.FromImage(scaled))
        {
            // 初始化透明背景
            g.Clear(Color.Transparent);
            // 高质量缩放并保留透明度
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.DrawImage(image, 0, 0, newWidth, newHeight);
        }
        return scaled;
    }

    /// <summary>
    /// 预缩放并确保Alpha通道存在（关键：保留原始透明信息）
    /// </summary>
    private Bitmap ResizeAndPreserveAlpha(Image image, int newWidth, int newHeight)
    {
        // 强制使用带Alpha通道的格式
        var scaled = new Bitmap(newWidth, newHeight, PixelFormat.Format32bppArgb);
        using (var g = Graphics.FromImage(scaled))
        {
            // 初始化透明背景
            g.Clear(Color.Transparent);
            // 高质量缩放并保留透明度
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.DrawImage(image, 0, 0, newWidth, newHeight);
        }
        return scaled;
    }
    /// <summary>
    /// 颜色量化（保留透明通道，不量化透明像素）
    /// </summary>
    private string QuantizeImage(Bitmap image)
    {
        string tempInput = Path.GetTempFileName() + ".png";
        string tempOutput = Path.GetTempFileName() + ".png";
        // 保存时确保保留Alpha通道
        image.Save(tempInput, ImageFormat.Png);

        try
        {
            switch (_quantAlgorithm)
            {
                case QuantizationAlgorithm.MedianCut:
                    // pngquant默认保留透明通道
                    string ditherArg = _dithering == DitheringType.FloydSteinberg ? "" : "--nofs";
                    RunCommand($"{_pngquantPath} --force {ditherArg} {_colorCount} --output {tempOutput} {tempInput}");
                    break;
                    //case QuantizationAlgorithm.NeuQuant:
                    //    // pngnq需要特殊参数保留透明
                    //    string ditherNq = _dithering == DitheringType.FloydSteinberg ? "-Q f" : "";
                    //    RunCommand($"{_pngnqPath} -f {ditherNq} -n {_colorCount} -e .png -k transparent {tempInput}");
                    //    string nqOutput = Path.ChangeExtension(tempInput, "~quant.png");
                    //    if (File.Exists(nqOutput)) File.Move(nqOutput, tempOutput);
                    //    break;
                    //case QuantizationAlgorithm.AdaptiveSpatial:
                    //    // ImageMagick明确保留透明
                    //    string ditherIm = _dithering switch
                    //    {
                    //        DitheringType.FloydSteinberg => "-dither FloydSteinberg",
                    //        DitheringType.Riemersma => "-dither Riemersma",
                    //        _ => "-dither None"
                    //    };
                    //    RunCommand($"{_convertPath} {tempInput} {ditherIm} -colors {_colorCount} -channel RGBA -separate -combine {tempOutput}");
                    //    break;
            }
            return tempOutput;
        }
        finally
        {
            File.Delete(tempInput);
        }
    }

    /// <summary>
    /// 提取颜色表（排除透明色）
    /// </summary>
    private List<Color> ExtractColorTable(Bitmap image)
    {
        // 存储唯一颜色（排除透明）
        var uniqueColors = new HashSet<int>();
        Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);

        // 锁定像素数据以提高访问效率
        BitmapData data = image.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        try
        {
            IntPtr ptr = data.Scan0;
            int bytes = Math.Abs(data.Stride) * image.Height;
            byte[] argbValues = new byte[bytes];
            Marshal.Copy(ptr, argbValues, 0, bytes);

            // 遍历所有像素
            for (int i = 0; i < argbValues.Length; i += 4)
            {
                // 从ARGB数组中解析通道（注意：存储顺序是BGR而非RGB）
                byte blue = argbValues[i];
                byte green = argbValues[i + 1];
                byte red = argbValues[i + 2];
                byte alpha = argbValues[i + 3];

                // 跳过透明或接近透明的像素（Alpha <= 10）
                if (alpha <= 10)
                {
                    continue;
                }
                // 将颜色转换为ARGB整数并添加到哈希集（自动去重）
                int colorArgb = Color.FromArgb(alpha, red, green, blue).ToArgb();
                uniqueColors.Add(colorArgb);
            }
        }
        finally
        {
            // 解锁像素数据
            image.UnlockBits(data);
        }

        // 将哈希集中的ARGB值转换为Color对象并返回
        return uniqueColors.Distinct().Select(argb => Color.FromArgb(argb)).ToList();
    }

    #endregion

    #region 掩码生成与透明处理优化

    /// <summary>
    /// 创建颜色段掩码（严格保留透明区域）
    /// </summary>
    private Bitmap CreateSegmentMask(Bitmap image, List<Color> segmentColors, List<ColorSegment> allSegments, int currentIndex)
    {
        int width = image.Width;
        int height = image.Height;
        var mask = new Bitmap(width, height, PixelFormat.Format32bppArgb);

        Rectangle rect = new Rectangle(0, 0, width, height);
        BitmapData srcData = image.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        BitmapData destData = mask.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

        try
        {
            IntPtr srcPtr = srcData.Scan0;
            IntPtr destPtr = destData.Scan0;
            int stride = srcData.Stride;
            int bytesPerPixel = 4;

            // 当前颜色段的颜色集
            HashSet<int> currentColors = new HashSet<int>(segmentColors.Select(c => c.ToArgb()));
            // 堆栈描摹颜色集
            HashSet<int> stackColors = new HashSet<int>();
            if (_stackTracing && currentIndex < allSegments.Count - 1)
            {
                for (int i = currentIndex + 1; i < allSegments.Count; i++)
                    foreach (var c in allSegments[i].Colors)
                        stackColors.Add(c.ToArgb());
            }

            Parallel.For(0, height, y =>
            {
                unsafe
                {
                    byte* srcRow = (byte*)srcPtr + (y * stride);
                    byte* destRow = (byte*)destPtr + (y * stride);

                    for (int x = 0; x < width; x++)
                    {
                        // 读取原始像素的Alpha值（关键：判断透明）
                        byte a = srcRow[x * bytesPerPixel + 3];
                        byte b = srcRow[x * bytesPerPixel];
                        byte g = srcRow[x * bytesPerPixel + 1];
                        byte r = srcRow[x * bytesPerPixel + 2];
                        int argb = Color.FromArgb(a, r, g, b).ToArgb();

                        // 完全透明的像素（Alpha=0）在掩码中也保持透明
                        if (a <= 10) // 允许10的容差（接近透明）
                        {
                            //SetPixel(destRow, x, 0, 0, 0, 0); // 透明
                            SetPixel(destRow, x, 255, 255, 255, 255); // 背景（白）
                        }
                        // 非透明像素按颜色段处理
                        else if (currentColors.Contains(argb) || (_stackTracing && stackColors.Contains(argb)))
                        {
                            SetPixel(destRow, x, 0, 0, 0, 255); // 前景（黑）
                        }
                        else
                        {
                            SetPixel(destRow, x, 255, 255, 255, 255); // 背景（白）
                        }
                    }
                }
            });
        }
        finally
        {
            image.UnlockBits(srcData);
            mask.UnlockBits(destData);
        }

        return SmoothMask(mask);
    }

    #endregion

    #region 矢量化与SVG生成（确保透明背景）

    /// <summary>
    /// 矢量化（优化Potrace参数，保留细节）
    /// </summary>
    private string VectorizeMask(Bitmap mask, Color color)
    {
        if (!HasValidContent(mask)) return null;

        using (var stream = new MemoryStream())
        {
            // 临时文件存储掩码（避免内存流格式问题，Potrace对标准输入的BMP格式可能有严格要求）
            //string tempBmpPath = Path.GetTempFileName() + ".bmp";

            //mask.Save(@"F:\111.bmp", ImageFormat.Bmp);
            //mask.Save(@"F:\111.png", ImageFormat.Png);
            mask.Save(stream, ImageFormat.Bmp);
            stream.Position = 0;

            float dpiX = mask.HorizontalResolution;
            float dpiY = mask.VerticalResolution;

            // 生成Potrace命令（添加平滑参数，保留区域形态）
            string colorHex = $"#{color.R:X2}{color.G:X2}{color.B:X2}";
            var args = new List<string>
                {
                    "--svg",
                    $"-C {colorHex}",    // 应用颜色段的平均颜色
                    "-t 1",              // 轻微去噪，保留细节
                    "-a 1.0",            // 平滑转角
                    "-O 0.5",            // 适度优化路径
                    "-s",
                    $"-r {dpiX}",
                    $"--width {mask.Width /_prescale / dpiX}",//单位英寸，1英寸=像素数量/dpi
                    $"--height {mask.Height / _prescale / dpiY}",
                    "-"
                };

            mask.Dispose();
            // 调用Potrace矢量化
            using (var process = new Process())
            {
                process.StartInfo = new ProcessStartInfo
                {
                    FileName = _potraceExePath,
                    Arguments = string.Join(" ", args),
                    RedirectStandardInput = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    StandardOutputEncoding = Encoding.UTF8
                };

                process.Start();
                stream.CopyTo(process.StandardInput.BaseStream);
                process.StandardInput.Close();

                string svgOutput = process.StandardOutput.ReadToEnd();
                string error = process.StandardError.ReadToEnd();
                process.WaitForExit();

                if (process.ExitCode != 0)
                {
                    if (_verbose)
                        Console.WriteLine($"矢量化错误：{error}");
                    return string.Empty;
                }


                //File.WriteAllText(@$"F:\{Guid.NewGuid()}.svg", svgOutput);
                return ExtractSvgPath(svgOutput, color.A);
            }
        }
    }

    private string ExtractSvgPath(string rawSvg, byte alpha)
    {
        if (string.IsNullOrWhiteSpace(rawSvg)) return string.Empty;

        // 匹配原始<g>标签及其属性（非贪婪匹配）
        var gTagRegex = new System.Text.RegularExpressions.Regex(
            @"<g\s+([^>]*?)>",
            System.Text.RegularExpressions.RegexOptions.IgnoreCase
        );
        var gTagMatch = gTagRegex.Match(rawSvg);

        // 提取原始<g>标签内的所有属性
        string originalGAttributes = gTagMatch.Success ? gTagMatch.Groups[1].Value : "";

        // 提取所有path元素
        var pathRegex = new System.Text.RegularExpressions.Regex(
            @"<path\s+[^>]*?/>",
            System.Text.RegularExpressions.RegexOptions.IgnoreCase
        );
        var matches = pathRegex.Matches(rawSvg);
        if (matches.Count == 0) return string.Empty;

        // 计算透明度属性（如果需要）
        string opacityAttribute = alpha < 255 ? $"opacity=\"{alpha / 255.0:0.00}\"" : "";

        // 合并原始属性和新透明度属性（去重处理）
        var attributes = new List<string>();
        if (!string.IsNullOrWhiteSpace(originalGAttributes))
        {
            attributes.AddRange(originalGAttributes.Split(
                new[] { ' ' },
                StringSplitOptions.RemoveEmptyEntries
            ));
        }
        if (!string.IsNullOrWhiteSpace(opacityAttribute))
        {
            // 移除可能存在的旧opacity属性
            attributes.RemoveAll(a => a.StartsWith("opacity=", StringComparison.OrdinalIgnoreCase));
            attributes.Add(opacityAttribute);
        }

        // 构建新的<g>标签
        var result = new StringBuilder();
        result.Append($"<g {string.Join(" ", attributes)}>");

        // 添加所有path元素
        foreach (var match in matches)
            result.AppendLine(match.ToString());

        result.Append("</g>");
        return result.ToString();
    }

    /// <summary>
    /// 保存合并的SVG（明确设置透明背景）
    /// </summary>
    private void SaveCombinedSvg(List<string> layers, string outputPath, int width, int height, float dpiX, float dpiY)
    {
        //width = (int)(width / _prescale);
        //height = (int)(height / _prescale);
        int widthPx = (int)((width / _prescale) * (72 / dpiX));// $"{width / _prescale * 72 / dpiX}pt";
        int heightPx = (int)((height / _prescale) * (72 / dpiX));//$"{height / _prescale * 72 / dpiY}pt";

        var svg = new StringBuilder();
        svg.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        // 关键：SVG根元素不设置背景色，默认透明
        svg.AppendLine($"<svg xmlns=\"http://www.w3.org/2000/svg\" " +
                      $"width=\"{widthPx}\" height=\"{heightPx}\" " +
                      $"viewBox=\"0 0 {widthPx} {heightPx}\" " +
                      //$"style=\"transform: scale({1 / _prescale})\" " +
                      $"preserveAspectRatio=\"xMidYMid meet\">");

        // 添加透明背景提示（不影响实际显示，但明确意图）
        svg.AppendLine($"  <!-- 透明背景 -->");

        // 按亮度排序图层
        foreach (var layer in layers.OrderBy(l => GetLayerBrightness(l)))
            svg.AppendLine(layer);

        svg.AppendLine("</svg>");
        Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
        File.WriteAllText(outputPath, svg.ToString(), new UTF8Encoding(false));
    }

    #endregion

    #region 其他工具方法（保持不变）

    private string RunCommand(string command, bool returnOutput = false)
    {
        using (var process = new Process())
        {
            process.StartInfo = new ProcessStartInfo
            {
                FileName = "cmd.exe",
                Arguments = $"/c {command}",
                RedirectStandardOutput = returnOutput,
                RedirectStandardError = true,
                UseShellExecute = false,
                CreateNoWindow = true,
                StandardOutputEncoding = returnOutput ? Encoding.UTF8 : null
            };

            process.Start();
            string error = process.StandardError.ReadToEnd();
            process.WaitForExit();

            if (process.ExitCode != 0)
                throw new Exception($"命令执行失败：{command}\n错误：{error}");

            if (returnOutput)
            {
                string lastCommandOutput = process.StandardOutput.ReadToEnd();
                return lastCommandOutput;
            }
        }
        return string.Empty;
    }

    private unsafe bool IsWhite(byte* row, int x, int bytesPerPixel)
    {
        int idx = x * bytesPerPixel;
        return row[idx] == 255 && row[idx + 1] == 255 && row[idx + 2] == 255 && row[idx + 3] == 255;
    }

    private int CountBlackNeighbors(IntPtr srcPtr, int stride, int x, int y, int bytesPerPixel)
    {
        int count = 0;
        unsafe
        {
            for (int dy = -1; dy <= 1; dy++)
            {
                byte* neighborRow = (byte*)srcPtr + ((y + dy) * stride);
                for (int dx = -1; dx <= 1; dx++)
                {
                    if (dx == 0 && dy == 0) continue;
                    int nx = x + dx;
                    int idx = nx * bytesPerPixel;
                    if (neighborRow[idx] == 0 && neighborRow[idx + 1] == 0 &&
                        neighborRow[idx + 2] == 0 && neighborRow[idx + 3] == 255)
                        count++;
                }
            }
        }
        return count;
    }

    private unsafe void SetPixel(byte* row, int x, byte b, byte g, byte r, byte a)
    {
        int idx = x * 4;
        row[idx] = b;
        row[idx + 1] = g;
        row[idx + 2] = r;
        row[idx + 3] = a;
    }

    private bool HasValidContent(Bitmap mask)
    {
        Rectangle rect = new Rectangle(0, 0, mask.Width, mask.Height);
        BitmapData data = mask.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        try
        {
            IntPtr ptr = data.Scan0;
            int bytes = Math.Abs(data.Stride) * mask.Height;
            byte[] argb = new byte[bytes];
            Marshal.Copy(ptr, argb, 0, bytes);

            for (int i = 0; i < argb.Length; i += 4)
                if (argb[i] == 0 && argb[i + 1] == 0 && argb[i + 2] == 0 && argb[i + 3] == 255)
                    return true;
            return false;
        }
        finally { mask.UnlockBits(data); }
    }

    private double GetLayerBrightness(string svgLayer)
    {
        var match = System.Text.RegularExpressions.Regex.Match(svgLayer, @"#([0-9A-Fa-f]{6})");
        if (match.Success)
        {
            var color = ColorTranslator.FromHtml($"#{match.Groups[1].Value}");
            return (0.299 * color.R + 0.587 * color.G + 0.114 * color.B) / 255;
        }
        return 0.5;
    }

    /// <summary>
    /// 轻度平滑（仅修复微小空洞，保留边缘）
    /// </summary>
    private Bitmap SmoothMask(Bitmap mask)
    {
        int width = mask.Width;
        int height = mask.Height;
        var smoothed = new Bitmap(mask);

        Rectangle rect = new Rectangle(0, 0, width, height);
        BitmapData srcData = mask.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        BitmapData destData = smoothed.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

        try
        {
            IntPtr srcPtr = srcData.Scan0;
            IntPtr destPtr = destData.Scan0;
            int stride = srcData.Stride;
            int bytesPerPixel = 4;

            Parallel.For(1, height - 1, y =>
            {
                unsafe
                {
                    byte* srcRow = (byte*)srcPtr + (y * stride);
                    byte* destRow = (byte*)destPtr + (y * stride);

                    for (int x = 1; x < width - 1; x++)
                    {
                        // 仅修复完全孤立的1x1空洞（避免模糊边缘）
                        if (IsWhite(srcRow, x, bytesPerPixel))
                        {
                            int blackCount = CountBlackNeighbors(srcPtr, stride, x, y, bytesPerPixel);
                            if (blackCount == 8) // 被8个黑像素包围的白像素（空洞）
                                SetPixel(destRow, x, 0, 0, 0, 255);
                        }
                    }
                }
            });
        }
        finally
        {
            mask.UnlockBits(srcData);
            smoothed.UnlockBits(destData);
        }

        return smoothed;
    }

    /// <summary>
    /// 基于量化颜色表创建颜色段（确保每个颜色对应一个段）
    /// </summary>
    private List<ColorSegment> CreateSegmentsFromColorTable(List<Color> colorTable)
    {
        // 按亮度排序（避免图层覆盖错误）
        var sortedColors = colorTable.OrderBy(c => (0.299 * c.R + 0.587 * c.G + 0.114 * c.B)).ToList();
        return sortedColors.Select((color, idx) =>
            new ColorSegment(idx, new List<Color> { color })).ToList();
    }

    #endregion
}

public class ColorSegment
{
    public int Id { get; }
    public List<Color> Colors { get; }
    public Color AverageColor { get; }

    public ColorSegment(int id, List<Color> colors)
    {
        Id = id;
        Colors = colors;
        AverageColor = colors.Count == 1 ? colors[0] : CalculateAverageColor(colors);
    }

    private Color CalculateAverageColor(List<Color> colors)
    {
        int r = 0, g = 0, b = 0, a = 0;
        foreach (var c in colors)
        {
            r += c.R;
            g += c.G;
            b += c.B;
            a += c.A;
        }
        return Color.FromArgb(a / colors.Count, r / colors.Count, g / colors.Count, b / colors.Count);
    }
}