using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace AxCopilot.Services.Agent;

public class ChartSkill : IAgentTool
{
	private sealed class Dataset
	{
		public string Name { get; init; } = "";

		public List<double> Values { get; init; } = new List<double>();

		public string Color { get; init; } = "#4B5EFC";
	}

	private static readonly string[] Palette = new string[10] { "#4B5EFC", "#10B981", "#F59E0B", "#EF4444", "#8B5CF6", "#06B6D4", "#EC4899", "#84CC16", "#F97316", "#6366F1" };

	private const string ChartCss = "\n/* Vertical Bar Chart */\n.vbar-chart { margin: 16px 0; }\n.vbar-bars { display: flex; align-items: flex-end; gap: 8px; height: 220px; padding: 0 8px; border-bottom: 2px solid #E5E7EB; }\n.vbar-group { flex: 1; display: flex; gap: 3px; align-items: flex-end; position: relative; }\n.vbar-bar { flex: 1; min-width: 18px; border-radius: 4px 4px 0 0; transition: opacity 0.2s; cursor: default; }\n.vbar-bar:hover { opacity: 0.8; }\n.vbar-label { text-align: center; font-size: 11px; color: #6B7280; margin-top: 6px; position: absolute; bottom: -24px; left: 0; right: 0; }\n\n/* Horizontal Bar Chart */\n.hbar-chart { margin: 12px 0; }\n.hbar-row { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }\n.hbar-label { min-width: 80px; text-align: right; font-size: 12px; color: #374151; font-weight: 500; }\n.hbar-track { flex: 1; height: 22px; background: #F3F4F6; border-radius: 6px; overflow: hidden; }\n.hbar-fill { height: 100%; border-radius: 6px; transition: width 0.6s ease; }\n.hbar-value { min-width: 50px; font-size: 12px; color: #6B7280; font-weight: 600; }\n\n/* Line/Area Chart */\n.line-chart-svg { width: 100%; max-width: 600px; height: auto; }\n\n/* Legend */\n.chart-legend { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 12px; padding-top: 8px; border-top: 1px solid #F3F4F6; }\n.legend-item { display: flex; align-items: center; gap: 6px; font-size: 12px; color: #374151; }\n.legend-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }\n\n/* Pie Legend */\n.pie-legend { display: flex; flex-direction: column; gap: 6px; }\n.pie-legend-item { display: flex; align-items: center; gap: 8px; font-size: 13px; color: #374151; }\n";

	public string Name => "chart_create";

	public string Description => "Create a styled HTML chart document with CSS/SVG-based charts. Supports chart types: bar, horizontal_bar, stacked_bar, line, area, pie, donut, radar, progress, comparison. Multiple charts can be placed in one document using the 'charts' array. Applies design mood from TemplateService (modern, professional, creative, etc.).";

	public ToolParameterSchema Parameters
	{
		get
		{
			ToolParameterSchema obj = new ToolParameterSchema
			{
				Properties = new Dictionary<string, ToolProperty>
				{
					["path"] = new ToolProperty
					{
						Type = "string",
						Description = "Output file path (.html). Relative to work folder."
					},
					["title"] = new ToolProperty
					{
						Type = "string",
						Description = "Document title"
					},
					["charts"] = new ToolProperty
					{
						Type = "array",
						Description = "Array of chart objects. Each chart: {\"type\": \"bar|horizontal_bar|stacked_bar|line|area|pie|donut|radar|progress|comparison\", \"title\": \"Chart Title\", \"labels\": [\"A\",\"B\",\"C\"], \"datasets\": [{\"name\": \"Series1\", \"values\": [10,20,30], \"color\": \"#4B5EFC\"}], \"unit\": \"%\"}",
						Items = new ToolProperty
						{
							Type = "object"
						}
					},
					["mood"] = new ToolProperty
					{
						Type = "string",
						Description = "Design mood: modern, professional, creative, dark, dashboard, etc. Default: dashboard"
					},
					["layout"] = new ToolProperty
					{
						Type = "string",
						Description = "Chart layout: 'single' (one per row) or 'grid' (2-column grid). Default: single"
					}
				}
			};
			int num = 3;
			List<string> list = new List<string>(num);
			CollectionsMarshal.SetCount(list, num);
			Span<string> span = CollectionsMarshal.AsSpan(list);
			span[0] = "path";
			span[1] = "title";
			span[2] = "charts";
			obj.Required = list;
			return obj;
		}
	}

	public async Task<ToolResult> ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct)
	{
		string path = args.GetProperty("path").GetString() ?? "chart.html";
		string title = args.GetProperty("title").GetString() ?? "Chart";
		JsonElement m;
		string mood = (args.TryGetProperty("mood", out m) ? (m.GetString() ?? "dashboard") : "dashboard");
		JsonElement l;
		string layout = (args.TryGetProperty("layout", out l) ? (l.GetString() ?? "single") : "single");
		string fullPath = FileReadTool.ResolvePath(path, context.WorkFolder);
		if (context.ActiveTab == "Cowork")
		{
			fullPath = AgentContext.EnsureTimestampedPath(fullPath);
		}
		if (!fullPath.EndsWith(".html", StringComparison.OrdinalIgnoreCase))
		{
			fullPath += ".html";
		}
		if (!context.IsPathAllowed(fullPath))
		{
			return ToolResult.Fail("경로 접근 차단: " + fullPath);
		}
		if (!(await context.CheckWritePermissionAsync(Name, fullPath)))
		{
			return ToolResult.Fail("쓰기 권한 거부: " + fullPath);
		}
		string dir = Path.GetDirectoryName(fullPath);
		if (!string.IsNullOrEmpty(dir))
		{
			Directory.CreateDirectory(dir);
		}
		if (!args.TryGetProperty("charts", out var chartsEl) || chartsEl.ValueKind != JsonValueKind.Array)
		{
			return ToolResult.Fail("charts 파라미터가 필요합니다 (배열 형식).");
		}
		int chartCount = chartsEl.GetArrayLength();
		StringBuilder body = new StringBuilder();
		StringBuilder stringBuilder = body;
		StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(9, 1, stringBuilder);
		handler.AppendLiteral("<h1>");
		handler.AppendFormatted(Escape(title));
		handler.AppendLiteral("</h1>");
		stringBuilder.AppendLine(ref handler);
		if (layout == "grid" && chartCount > 1)
		{
			body.AppendLine("<div class=\"grid-2\">");
		}
		int chartIdx = 0;
		foreach (JsonElement chartEl in chartsEl.EnumerateArray())
		{
			string chartHtml = RenderChart(chartEl, chartIdx);
			body.AppendLine("<div class=\"card\" style=\"margin-bottom:20px;\">");
			body.AppendLine(chartHtml);
			body.AppendLine("</div>");
			chartIdx++;
		}
		if (layout == "grid" && chartCount > 1)
		{
			body.AppendLine("</div>");
		}
		string css = TemplateService.GetCss(mood) + "\n\n/* Vertical Bar Chart */\n.vbar-chart { margin: 16px 0; }\n.vbar-bars { display: flex; align-items: flex-end; gap: 8px; height: 220px; padding: 0 8px; border-bottom: 2px solid #E5E7EB; }\n.vbar-group { flex: 1; display: flex; gap: 3px; align-items: flex-end; position: relative; }\n.vbar-bar { flex: 1; min-width: 18px; border-radius: 4px 4px 0 0; transition: opacity 0.2s; cursor: default; }\n.vbar-bar:hover { opacity: 0.8; }\n.vbar-label { text-align: center; font-size: 11px; color: #6B7280; margin-top: 6px; position: absolute; bottom: -24px; left: 0; right: 0; }\n\n/* Horizontal Bar Chart */\n.hbar-chart { margin: 12px 0; }\n.hbar-row { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }\n.hbar-label { min-width: 80px; text-align: right; font-size: 12px; color: #374151; font-weight: 500; }\n.hbar-track { flex: 1; height: 22px; background: #F3F4F6; border-radius: 6px; overflow: hidden; }\n.hbar-fill { height: 100%; border-radius: 6px; transition: width 0.6s ease; }\n.hbar-value { min-width: 50px; font-size: 12px; color: #6B7280; font-weight: 600; }\n\n/* Line/Area Chart */\n.line-chart-svg { width: 100%; max-width: 600px; height: auto; }\n\n/* Legend */\n.chart-legend { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 12px; padding-top: 8px; border-top: 1px solid #F3F4F6; }\n.legend-item { display: flex; align-items: center; gap: 6px; font-size: 12px; color: #374151; }\n.legend-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }\n\n/* Pie Legend */\n.pie-legend { display: flex; flex-direction: column; gap: 6px; }\n.pie-legend-item { display: flex; align-items: center; gap: 8px; font-size: 13px; color: #374151; }\n";
		string html = $"<!DOCTYPE html>\n<html lang=\"ko\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>{Escape(title)}</title>\n<style>\n{css}\n</style>\n</head>\n<body>\n<div class=\"container\">\n{body}\n</div>\n</body>\n</html>";
		await File.WriteAllTextAsync(fullPath, html, Encoding.UTF8, ct);
		return ToolResult.Ok($"차트 문서 생성 완료: {fullPath} ({chartCount}개 차트)", fullPath);
	}

	private string RenderChart(JsonElement chart, int idx)
	{
		JsonElement value;
		string text = (chart.TryGetProperty("type", out value) ? (value.GetString() ?? "bar") : "bar");
		JsonElement value2;
		string text2 = (chart.TryGetProperty("title", out value2) ? (value2.GetString() ?? "") : "");
		JsonElement value3;
		string unit = (chart.TryGetProperty("unit", out value3) ? (value3.GetString() ?? "") : "");
		List<string> labels = ParseStringArray(chart, "labels");
		List<Dataset> list = ParseDatasets(chart);
		StringBuilder stringBuilder = new StringBuilder();
		if (!string.IsNullOrEmpty(text2))
		{
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(37, 1, stringBuilder2);
			handler.AppendLiteral("<h3 style=\"margin-bottom:12px;\">");
			handler.AppendFormatted(Escape(text2));
			handler.AppendLiteral("</h3>");
			stringBuilder3.AppendLine(ref handler);
		}
		switch (text)
		{
		case "bar":
			stringBuilder.Append(RenderBarChart(labels, list, unit, horizontal: false));
			break;
		case "horizontal_bar":
			stringBuilder.Append(RenderBarChart(labels, list, unit, horizontal: true));
			break;
		case "stacked_bar":
			stringBuilder.Append(RenderStackedBar(labels, list, unit));
			break;
		case "line":
		case "area":
			stringBuilder.Append(RenderLineChart(labels, list, unit, text == "area"));
			break;
		case "pie":
		case "donut":
			stringBuilder.Append(RenderPieChart(labels, list, text == "donut"));
			break;
		case "progress":
			stringBuilder.Append(RenderProgressChart(labels, list, unit));
			break;
		case "comparison":
			stringBuilder.Append(RenderComparisonChart(labels, list, unit));
			break;
		case "radar":
			stringBuilder.Append(RenderRadarChart(labels, list));
			break;
		default:
			stringBuilder.Append(RenderBarChart(labels, list, unit, horizontal: false));
			break;
		}
		if (list.Count > 1)
		{
			stringBuilder.AppendLine("<div class=\"chart-legend\">");
			foreach (Dataset item in list)
			{
				StringBuilder stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder4 = stringBuilder2;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(85, 2, stringBuilder2);
				handler.AppendLiteral("<span class=\"legend-item\"><span class=\"legend-dot\" style=\"background:");
				handler.AppendFormatted(item.Color);
				handler.AppendLiteral("\"></span>");
				handler.AppendFormatted(Escape(item.Name));
				handler.AppendLiteral("</span>");
				stringBuilder4.AppendLine(ref handler);
			}
			stringBuilder.AppendLine("</div>");
		}
		return stringBuilder.ToString();
	}

	private static string RenderBarChart(List<string> labels, List<Dataset> datasets, string unit, bool horizontal)
	{
		double num = datasets.SelectMany((Dataset d) => d.Values).DefaultIfEmpty(1.0).Max();
		if (num <= 0.0)
		{
			num = 1.0;
		}
		StringBuilder stringBuilder = new StringBuilder();
		if (horizontal)
		{
			stringBuilder.AppendLine("<div class=\"hbar-chart\">");
			for (int num2 = 0; num2 < labels.Count; num2++)
			{
				double num3 = ((datasets.Count > 0 && num2 < datasets[0].Values.Count) ? datasets[0].Values[num2] : 0.0);
				int value = (int)(num3 / num * 100.0);
				string value2 = ((datasets.Count > 0) ? datasets[0].Color : Palette[0]);
				StringBuilder stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder3 = stringBuilder2;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(54, 1, stringBuilder2);
				handler.AppendLiteral("<div class=\"hbar-row\"><span class=\"hbar-label\">");
				handler.AppendFormatted(Escape(labels[num2]));
				handler.AppendLiteral("</span>");
				stringBuilder3.AppendLine(ref handler);
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder4 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(88, 2, stringBuilder2);
				handler.AppendLiteral("<div class=\"hbar-track\"><div class=\"hbar-fill\" style=\"width:");
				handler.AppendFormatted(value);
				handler.AppendLiteral("%;background:");
				handler.AppendFormatted(value2);
				handler.AppendLiteral(";\"></div></div>");
				stringBuilder4.AppendLine(ref handler);
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder5 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(38, 2, stringBuilder2);
				handler.AppendLiteral("<span class=\"hbar-value\">");
				handler.AppendFormatted(num3, "G");
				handler.AppendFormatted(unit);
				handler.AppendLiteral("</span></div>");
				stringBuilder5.AppendLine(ref handler);
			}
			stringBuilder.AppendLine("</div>");
		}
		else
		{
			stringBuilder.AppendLine("<div class=\"vbar-chart\">");
			stringBuilder.AppendLine("<div class=\"vbar-bars\">");
			for (int num4 = 0; num4 < labels.Count; num4++)
			{
				stringBuilder.AppendLine("<div class=\"vbar-group\">");
				StringBuilder stringBuilder2;
				StringBuilder.AppendInterpolatedStringHandler handler;
				foreach (Dataset dataset in datasets)
				{
					double num5 = ((num4 < dataset.Values.Count) ? dataset.Values[num4] : 0.0);
					int value3 = (int)(num5 / num * 100.0);
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder6 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(67, 4, stringBuilder2);
					handler.AppendLiteral("<div class=\"vbar-bar\" style=\"height:");
					handler.AppendFormatted(value3);
					handler.AppendLiteral("%;background:");
					handler.AppendFormatted(dataset.Color);
					handler.AppendLiteral(";\" title=\"");
					handler.AppendFormatted(num5, "G");
					handler.AppendFormatted(unit);
					handler.AppendLiteral("\"></div>");
					stringBuilder6.AppendLine(ref handler);
				}
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder7 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(30, 1, stringBuilder2);
				handler.AppendLiteral("<div class=\"vbar-label\">");
				handler.AppendFormatted(Escape(labels[num4]));
				handler.AppendLiteral("</div>");
				stringBuilder7.AppendLine(ref handler);
				stringBuilder.AppendLine("</div>");
			}
			stringBuilder.AppendLine("</div></div>");
		}
		return stringBuilder.ToString();
	}

	private static string RenderStackedBar(List<string> labels, List<Dataset> datasets, string unit)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("<div class=\"hbar-chart\">");
		int i;
		for (i = 0; i < labels.Count; i++)
		{
			double num = datasets.Sum((Dataset ds) => (i < ds.Values.Count) ? ds.Values[i] : 0.0);
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(54, 1, stringBuilder2);
			handler.AppendLiteral("<div class=\"hbar-row\"><span class=\"hbar-label\">");
			handler.AppendFormatted(Escape(labels[i]));
			handler.AppendLiteral("</span>");
			stringBuilder3.AppendLine(ref handler);
			stringBuilder.AppendLine("<div class=\"hbar-track\" style=\"display:flex;\">");
			foreach (Dataset dataset in datasets)
			{
				double num2 = ((i < dataset.Values.Count) ? dataset.Values[i] : 0.0);
				int value = ((num > 0.0) ? ((int)(num2 / num * 100.0)) : 0);
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder4 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(63, 5, stringBuilder2);
				handler.AppendLiteral("<div style=\"width:");
				handler.AppendFormatted(value);
				handler.AppendLiteral("%;background:");
				handler.AppendFormatted(dataset.Color);
				handler.AppendLiteral(";height:100%;\" title=\"");
				handler.AppendFormatted(dataset.Name);
				handler.AppendLiteral(": ");
				handler.AppendFormatted(num2, "G");
				handler.AppendFormatted(unit);
				handler.AppendLiteral("\"></div>");
				stringBuilder4.AppendLine(ref handler);
			}
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder5 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(44, 2, stringBuilder2);
			handler.AppendLiteral("</div><span class=\"hbar-value\">");
			handler.AppendFormatted(num, "G");
			handler.AppendFormatted(unit);
			handler.AppendLiteral("</span></div>");
			stringBuilder5.AppendLine(ref handler);
		}
		stringBuilder.AppendLine("</div>");
		return stringBuilder.ToString();
	}

	private static string RenderLineChart(List<string> labels, List<Dataset> datasets, string unit, bool isArea)
	{
		List<double> source = datasets.SelectMany((Dataset d) => d.Values).ToList();
		double num = source.DefaultIfEmpty(1.0).Max();
		double num2 = source.DefaultIfEmpty(0.0).Min();
		if (num <= num2)
		{
			num = num2 + 1.0;
		}
		int num3 = 600;
		int num4 = 300;
		int num5 = 50;
		int num6 = 20;
		int num7 = 20;
		int num8 = 40;
		int num9 = num3 - num5 - num6;
		int num10 = num4 - num7 - num8;
		int count = labels.Count;
		StringBuilder stringBuilder = new StringBuilder();
		StringBuilder stringBuilder2 = stringBuilder;
		StringBuilder stringBuilder3 = stringBuilder2;
		StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(80, 2, stringBuilder2);
		handler.AppendLiteral("<svg viewBox=\"0 0 ");
		handler.AppendFormatted(num3);
		handler.AppendLiteral(" ");
		handler.AppendFormatted(num4);
		handler.AppendLiteral("\" class=\"line-chart-svg\" preserveAspectRatio=\"xMidYMid meet\">");
		stringBuilder3.AppendLine(ref handler);
		for (int num11 = 0; num11 <= 4; num11++)
		{
			double num12 = (double)(num7 + num10) - (double)(num10 * num11) / 4.0;
			double value = num2 + (num - num2) * (double)num11 / 4.0;
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(65, 4, stringBuilder2);
			handler.AppendLiteral("<line x1=\"");
			handler.AppendFormatted(num5);
			handler.AppendLiteral("\" y1=\"");
			handler.AppendFormatted(num12, "F0");
			handler.AppendLiteral("\" x2=\"");
			handler.AppendFormatted(num3 - num6);
			handler.AppendLiteral("\" y2=\"");
			handler.AppendFormatted(num12, "F0");
			handler.AppendLiteral("\" stroke=\"#E5E7EB\" stroke-width=\"1\"/>");
			stringBuilder4.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder5 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(71, 4, stringBuilder2);
			handler.AppendLiteral("<text x=\"");
			handler.AppendFormatted(num5 - 8);
			handler.AppendLiteral("\" y=\"");
			handler.AppendFormatted(num12 + 4.0, "F0");
			handler.AppendLiteral("\" text-anchor=\"end\" fill=\"#6B7280\" font-size=\"11\">");
			handler.AppendFormatted(value, "G3");
			handler.AppendFormatted(unit);
			handler.AppendLiteral("</text>");
			stringBuilder5.AppendLine(ref handler);
		}
		for (int num13 = 0; num13 < count; num13++)
		{
			double value2 = (double)num5 + ((count > 1) ? ((double)(num9 * num13) / (double)(count - 1)) : ((double)num9 / 2.0));
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder6 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(74, 3, stringBuilder2);
			handler.AppendLiteral("<text x=\"");
			handler.AppendFormatted(value2, "F0");
			handler.AppendLiteral("\" y=\"");
			handler.AppendFormatted(num4 - 8);
			handler.AppendLiteral("\" text-anchor=\"middle\" fill=\"#6B7280\" font-size=\"11\">");
			handler.AppendFormatted(Escape(labels[num13]));
			handler.AppendLiteral("</text>");
			stringBuilder6.AppendLine(ref handler);
		}
		foreach (Dataset dataset in datasets)
		{
			List<(double, double)> list = new List<(double, double)>();
			for (int num14 = 0; num14 < Math.Min(count, dataset.Values.Count); num14++)
			{
				double item = (double)num5 + ((count > 1) ? ((double)(num9 * num14) / (double)(count - 1)) : ((double)num9 / 2.0));
				double item2 = (double)(num7 + num10) - (dataset.Values[num14] - num2) / (num - num2) * (double)num10;
				list.Add((item, item2));
			}
			string text = string.Join(" ", list.Select<(double, double), string>(((double x, double y) p, int i) => $"{((i == 0) ? "M" : "L")}{p.x:F1},{p.y:F1}"));
			if (isArea && list.Count > 1)
			{
				string value3 = text + $" L{list.Last().Item1:F1},{num7 + num10} L{list.First().Item1:F1},{num7 + num10} Z";
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder7 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(35, 2, stringBuilder2);
				handler.AppendLiteral("<path d=\"");
				handler.AppendFormatted(value3);
				handler.AppendLiteral("\" fill=\"");
				handler.AppendFormatted(dataset.Color);
				handler.AppendLiteral("\" opacity=\"0.15\"/>");
				stringBuilder7.AppendLine(ref handler);
			}
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder8 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(100, 2, stringBuilder2);
			handler.AppendLiteral("<path d=\"");
			handler.AppendFormatted(text);
			handler.AppendLiteral("\" fill=\"none\" stroke=\"");
			handler.AppendFormatted(dataset.Color);
			handler.AppendLiteral("\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>");
			stringBuilder8.AppendLine(ref handler);
			foreach (var item5 in list)
			{
				double item3 = item5.Item1;
				double item4 = item5.Item2;
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder9 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(67, 3, stringBuilder2);
				handler.AppendLiteral("<circle cx=\"");
				handler.AppendFormatted(item3, "F1");
				handler.AppendLiteral("\" cy=\"");
				handler.AppendFormatted(item4, "F1");
				handler.AppendLiteral("\" r=\"4\" fill=\"");
				handler.AppendFormatted(dataset.Color);
				handler.AppendLiteral("\" stroke=\"white\" stroke-width=\"2\"/>");
				stringBuilder9.AppendLine(ref handler);
			}
		}
		stringBuilder.AppendLine("</svg>");
		return stringBuilder.ToString();
	}

	private static string RenderPieChart(List<string> labels, List<Dataset> datasets, bool isDonut)
	{
		List<double> list = ((datasets.Count > 0) ? datasets[0].Values : new List<double>());
		double num = list.Sum();
		if (num <= 0.0)
		{
			num = 1.0;
		}
		int num2 = 150;
		int num3 = 150;
		int num4 = 120;
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("<div style=\"display:flex;align-items:center;gap:24px;flex-wrap:wrap;\">");
		stringBuilder.AppendLine("<svg viewBox=\"0 0 300 300\" width=\"260\" height=\"260\">");
		double num5 = -90.0;
		for (int i = 0; i < Math.Min(list.Count, labels.Count); i++)
		{
			double num6 = list[i] / num;
			double num7 = num6 * 360.0;
			double num8 = num5 + num7;
			double value = (double)num2 + (double)num4 * Math.Cos(num5 * Math.PI / 180.0);
			double value2 = (double)num3 + (double)num4 * Math.Sin(num5 * Math.PI / 180.0);
			double value3 = (double)num2 + (double)num4 * Math.Cos(num8 * Math.PI / 180.0);
			double value4 = (double)num3 + (double)num4 * Math.Sin(num8 * Math.PI / 180.0);
			int value5 = ((num7 > 180.0) ? 1 : 0);
			string value6 = ((i < Palette.Length) ? Palette[i] : Palette[i % Palette.Length]);
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(37, 10, stringBuilder2);
			handler.AppendLiteral("<path d=\"M");
			handler.AppendFormatted(num2);
			handler.AppendLiteral(",");
			handler.AppendFormatted(num3);
			handler.AppendLiteral(" L");
			handler.AppendFormatted(value, "F1");
			handler.AppendLiteral(",");
			handler.AppendFormatted(value2, "F1");
			handler.AppendLiteral(" A");
			handler.AppendFormatted(num4);
			handler.AppendLiteral(",");
			handler.AppendFormatted(num4);
			handler.AppendLiteral(" 0 ");
			handler.AppendFormatted(value5);
			handler.AppendLiteral(",1 ");
			handler.AppendFormatted(value3, "F1");
			handler.AppendLiteral(",");
			handler.AppendFormatted(value4, "F1");
			handler.AppendLiteral(" Z\" fill=\"");
			handler.AppendFormatted(value6);
			handler.AppendLiteral("\"/>");
			stringBuilder3.AppendLine(ref handler);
			num5 = num8;
		}
		if (isDonut)
		{
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(39, 3, stringBuilder2);
			handler.AppendLiteral("<circle cx=\"");
			handler.AppendFormatted(num2);
			handler.AppendLiteral("\" cy=\"");
			handler.AppendFormatted(num3);
			handler.AppendLiteral("\" r=\"");
			handler.AppendFormatted((double)num4 * 0.55);
			handler.AppendLiteral("\" fill=\"white\"/>");
			stringBuilder4.AppendLine(ref handler);
		}
		stringBuilder.AppendLine("</svg>");
		stringBuilder.AppendLine("<div class=\"pie-legend\">");
		for (int j = 0; j < Math.Min(list.Count, labels.Count); j++)
		{
			string value7 = ((j < Palette.Length) ? Palette[j] : Palette[j % Palette.Length]);
			double value8 = list[j] / num * 100.0;
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder5 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(142, 3, stringBuilder2);
			handler.AppendLiteral("<div class=\"pie-legend-item\"><span class=\"legend-dot\" style=\"background:");
			handler.AppendFormatted(value7);
			handler.AppendLiteral("\"></span>");
			handler.AppendFormatted(Escape(labels[j]));
			handler.AppendLiteral(" <span style=\"color:#6B7280;font-size:12px;\">(");
			handler.AppendFormatted(value8, "F1");
			handler.AppendLiteral("%)</span></div>");
			stringBuilder5.AppendLine(ref handler);
		}
		stringBuilder.AppendLine("</div></div>");
		return stringBuilder.ToString();
	}

	private static string RenderProgressChart(List<string> labels, List<Dataset> datasets, string unit)
	{
		List<double> list = ((datasets.Count > 0) ? datasets[0].Values : new List<double>());
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < Math.Min(labels.Count, list.Count); i++)
		{
			double value = Math.Clamp(list[i], 0.0, 100.0);
			string value2 = ((i < Palette.Length) ? Palette[i] : Palette[i % Palette.Length]);
			if (datasets.Count > 0 && !string.IsNullOrEmpty(datasets[0].Color))
			{
				value2 = datasets[0].Color;
			}
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(218, 3, stringBuilder2);
			handler.AppendLiteral("<div style=\"margin-bottom:12px;\"><div style=\"display:flex;justify-content:space-between;margin-bottom:4px;\"><span style=\"font-size:13px;font-weight:600;\">");
			handler.AppendFormatted(Escape(labels[i]));
			handler.AppendLiteral("</span><span style=\"font-size:13px;color:#6B7280;\">");
			handler.AppendFormatted(list[i], "G");
			handler.AppendFormatted(unit);
			handler.AppendLiteral("</span></div>");
			stringBuilder3.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(96, 2, stringBuilder2);
			handler.AppendLiteral("<div class=\"progress\"><div class=\"progress-fill\" style=\"width:");
			handler.AppendFormatted(value);
			handler.AppendLiteral("%;background:");
			handler.AppendFormatted(value2);
			handler.AppendLiteral(";\"></div></div></div>");
			stringBuilder4.AppendLine(ref handler);
		}
		return stringBuilder.ToString();
	}

	private static string RenderComparisonChart(List<string> labels, List<Dataset> datasets, string unit)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("<table style=\"width:100%;border-collapse:collapse;\">");
		stringBuilder.AppendLine("<tr><th style=\"text-align:left;padding:8px 12px;\">항목</th>");
		foreach (Dataset dataset in datasets)
		{
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(60, 2, stringBuilder2);
			handler.AppendLiteral("<th style=\"text-align:center;padding:8px 12px;color:");
			handler.AppendFormatted(dataset.Color);
			handler.AppendLiteral(";\">");
			handler.AppendFormatted(Escape(dataset.Name));
			handler.AppendLiteral("</th>");
			stringBuilder3.AppendLine(ref handler);
		}
		stringBuilder.AppendLine("</tr>");
		for (int i = 0; i < labels.Count; i++)
		{
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(93, 1, stringBuilder2);
			handler.AppendLiteral("<tr style=\"border-top:1px solid #E5E7EB;\"><td style=\"padding:8px 12px;font-weight:500;\">");
			handler.AppendFormatted(Escape(labels[i]));
			handler.AppendLiteral("</td>");
			stringBuilder4.Append(ref handler);
			foreach (Dataset dataset2 in datasets)
			{
				double value = ((i < dataset2.Values.Count) ? dataset2.Values[i] : 0.0);
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder5 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(53, 2, stringBuilder2);
				handler.AppendLiteral("<td style=\"text-align:center;padding:8px 12px;\">");
				handler.AppendFormatted(value, "G");
				handler.AppendFormatted(unit);
				handler.AppendLiteral("</td>");
				stringBuilder5.Append(ref handler);
			}
			stringBuilder.AppendLine("</tr>");
		}
		stringBuilder.AppendLine("</table>");
		return stringBuilder.ToString();
	}

	private static string RenderRadarChart(List<string> labels, List<Dataset> datasets)
	{
		int cx = 150;
		int cy = 150;
		int r = 110;
		int n = labels.Count;
		if (n < 3)
		{
			return "<p>레이더 차트는 최소 3개 항목이 필요합니다.</p>";
		}
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("<svg viewBox=\"0 0 300 300\" width=\"300\" height=\"300\">");
		for (int i = 1; i <= 4; i++)
		{
			double lr = (double)(r * i) / 4.0;
			string value = string.Join(" ", Enumerable.Range(0, n).Select(delegate(int num5)
			{
				double num4 = (360.0 / (double)n * (double)num5 - 90.0) * Math.PI / 180.0;
				return $"{(double)cx + lr * Math.Cos(num4):F1},{(double)cy + lr * Math.Sin(num4):F1}";
			}));
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(66, 1, stringBuilder2);
			handler.AppendLiteral("<polygon points=\"");
			handler.AppendFormatted(value);
			handler.AppendLiteral("\" fill=\"none\" stroke=\"#E5E7EB\" stroke-width=\"1\"/>");
			stringBuilder3.AppendLine(ref handler);
		}
		for (int num = 0; num < n; num++)
		{
			double num2 = (360.0 / (double)n * (double)num - 90.0) * Math.PI / 180.0;
			double value2 = (double)cx + (double)r * Math.Cos(num2);
			double value3 = (double)cy + (double)r * Math.Sin(num2);
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(65, 4, stringBuilder2);
			handler.AppendLiteral("<line x1=\"");
			handler.AppendFormatted(cx);
			handler.AppendLiteral("\" y1=\"");
			handler.AppendFormatted(cy);
			handler.AppendLiteral("\" x2=\"");
			handler.AppendFormatted(value2, "F1");
			handler.AppendLiteral("\" y2=\"");
			handler.AppendFormatted(value3, "F1");
			handler.AppendLiteral("\" stroke=\"#D1D5DB\" stroke-width=\"1\"/>");
			stringBuilder4.AppendLine(ref handler);
			double value4 = (double)cx + (double)(r + 16) * Math.Cos(num2);
			double num3 = (double)cy + (double)(r + 16) * Math.Sin(num2);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder5 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(74, 3, stringBuilder2);
			handler.AppendLiteral("<text x=\"");
			handler.AppendFormatted(value4, "F0");
			handler.AppendLiteral("\" y=\"");
			handler.AppendFormatted(num3 + 4.0, "F0");
			handler.AppendLiteral("\" text-anchor=\"middle\" fill=\"#374151\" font-size=\"11\">");
			handler.AppendFormatted(Escape(labels[num]));
			handler.AppendLiteral("</text>");
			stringBuilder5.AppendLine(ref handler);
		}
		double maxVal = datasets.SelectMany((Dataset d) => d.Values).DefaultIfEmpty(1.0).Max();
		if (maxVal <= 0.0)
		{
			maxVal = 1.0;
		}
		foreach (Dataset ds in datasets)
		{
			string value5 = string.Join(" ", Enumerable.Range(0, n).Select(delegate(int num5)
			{
				double num4 = ((num5 < ds.Values.Count) ? ds.Values[num5] : 0.0);
				double num6 = (double)r * num4 / maxVal;
				double num7 = (360.0 / (double)n * (double)num5 - 90.0) * Math.PI / 180.0;
				return $"{(double)cx + num6 * Math.Cos(num7):F1},{(double)cy + num6 * Math.Sin(num7):F1}";
			}));
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder6 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(74, 3, stringBuilder2);
			handler.AppendLiteral("<polygon points=\"");
			handler.AppendFormatted(value5);
			handler.AppendLiteral("\" fill=\"");
			handler.AppendFormatted(ds.Color);
			handler.AppendLiteral("\" fill-opacity=\"0.2\" stroke=\"");
			handler.AppendFormatted(ds.Color);
			handler.AppendLiteral("\" stroke-width=\"2\"/>");
			stringBuilder6.AppendLine(ref handler);
		}
		stringBuilder.AppendLine("</svg>");
		return stringBuilder.ToString();
	}

	private static List<string> ParseStringArray(JsonElement parent, string prop)
	{
		if (!parent.TryGetProperty(prop, out var value) || value.ValueKind != JsonValueKind.Array)
		{
			return new List<string>();
		}
		return (from e in value.EnumerateArray()
			select e.GetString() ?? "").ToList();
	}

	private List<Dataset> ParseDatasets(JsonElement chart)
	{
		if (!chart.TryGetProperty("datasets", out var value) || value.ValueKind != JsonValueKind.Array)
		{
			double value6;
			if (chart.TryGetProperty("values", out var value2) && value2.ValueKind == JsonValueKind.Array)
			{
				return new List<Dataset>
				{
					new Dataset
					{
						Name = "Data",
						Values = (from v in value2.EnumerateArray()
							select v.TryGetDouble(out value6) ? value6 : 0.0).ToList(),
						Color = Palette[0]
					}
				};
			}
			return new List<Dataset>();
		}
		List<Dataset> list = new List<Dataset>();
		int num = 0;
		foreach (JsonElement item in value.EnumerateArray())
		{
			JsonElement value3;
			string name = (item.TryGetProperty("name", out value3) ? (value3.GetString() ?? $"Series{num + 1}") : $"Series{num + 1}");
			JsonElement value4;
			string color = (item.TryGetProperty("color", out value4) ? (value4.GetString() ?? Palette[num % Palette.Length]) : Palette[num % Palette.Length]);
			List<double> values = new List<double>();
			if (item.TryGetProperty("values", out var value5) && value5.ValueKind == JsonValueKind.Array)
			{
				values = (from e in value5.EnumerateArray()
					select e.TryGetDouble(out var value6) ? value6 : 0.0).ToList();
			}
			list.Add(new Dataset
			{
				Name = name,
				Values = values,
				Color = color
			});
			num++;
		}
		return list;
	}

	private static string Escape(string s)
	{
		return s.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;")
			.Replace("\"", "&quot;");
	}

	private static string FormatSize(long bytes)
	{
		if (1 == 0)
		{
		}
		string result = ((bytes < 1024) ? $"{bytes}B" : ((bytes >= 1048576) ? $"{(double)bytes / 1048576.0:F1}MB" : $"{(double)bytes / 1024.0:F1}KB"));
		if (1 == 0)
		{
		}
		return result;
	}
}
