using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.Win32;

namespace AxCopilot.Services;

public static class MarkdownRenderer
{
	private static readonly Regex FilePathPattern = new Regex("(?<![\"'=/>])([A-Za-z]:\\\\[^\\s<>\"',;)]+|\\.{1,2}/[\\w\\-./]+(?:\\.[a-zA-Z]{1,10})?|[\\w\\-]+(?:/[\\w\\-\\.]+){1,}(?:\\.[a-zA-Z]{1,10})?|[\\w\\-]+\\.(?:cs|py|js|ts|tsx|jsx|json|xml|html|htm|css|md|txt|yml|yaml|toml|sh|bat|ps1|csproj|sln|docx|xlsx|pptx|pdf|csv|enc|skill))(?=[,\\s;)\"'<]|$)", RegexOptions.Compiled);

	private static readonly Brush KeywordBrush = new SolidColorBrush(Color.FromRgb(197, 134, 192));

	private static readonly Brush TypeBrush = new SolidColorBrush(Color.FromRgb(78, 201, 176));

	private static readonly Brush StringBrush = new SolidColorBrush(Color.FromRgb(206, 145, 120));

	private static readonly Brush CommentBrush = new SolidColorBrush(Color.FromRgb(106, 153, 85));

	private static readonly Brush NumberBrush = new SolidColorBrush(Color.FromRgb(181, 206, 168));

	private static readonly Brush MethodBrush = new SolidColorBrush(Color.FromRgb(220, 220, 170));

	private static readonly Brush DirectiveBrush = new SolidColorBrush(Color.FromRgb(156, 220, 254));

	private static readonly HashSet<string> CSharpKeywords = new HashSet<string>(StringComparer.Ordinal)
	{
		"abstract", "as", "async", "await", "base", "bool", "break", "byte", "case", "catch",
		"char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double",
		"else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for",
		"foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock",
		"long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private",
		"protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc",
		"static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint",
		"ulong", "unchecked", "unsafe", "ushort", "using", "var", "virtual", "void", "volatile", "while",
		"yield", "record", "init", "required", "get", "set", "value", "where", "when", "and",
		"or", "not"
	};

	private static readonly HashSet<string> PythonKeywords = new HashSet<string>(StringComparer.Ordinal)
	{
		"False", "None", "True", "and", "as", "assert", "async", "await", "break", "class",
		"continue", "def", "del", "elif", "else", "except", "finally", "for", "from", "global",
		"if", "import", "in", "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
		"return", "try", "while", "with", "yield"
	};

	private static readonly HashSet<string> JsKeywords = new HashSet<string>(StringComparer.Ordinal)
	{
		"abstract", "arguments", "async", "await", "boolean", "break", "byte", "case", "catch", "char",
		"class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum",
		"eval", "export", "extends", "false", "final", "finally", "float", "for", "from", "function",
		"goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "let", "long",
		"native", "new", "null", "of", "package", "private", "protected", "public", "return", "short",
		"static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try",
		"typeof", "undefined", "var", "void", "volatile", "while", "with", "yield"
	};

	private static readonly HashSet<string> JavaKeywords = new HashSet<string>(StringComparer.Ordinal)
	{
		"abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const",
		"continue", "default", "do", "double", "else", "enum", "extends", "false", "final", "finally",
		"float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long",
		"native", "new", "null", "package", "private", "protected", "public", "return", "short", "static",
		"strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try",
		"void", "volatile", "while", "var", "record", "sealed", "permits", "yield"
	};

	private static readonly HashSet<string> SqlKeywords = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
	{
		"SELECT", "FROM", "WHERE", "INSERT", "INTO", "UPDATE", "SET", "DELETE", "CREATE", "DROP",
		"ALTER", "TABLE", "INDEX", "VIEW", "JOIN", "INNER", "LEFT", "RIGHT", "OUTER", "FULL",
		"CROSS", "ON", "AND", "OR", "NOT", "IN", "IS", "NULL", "LIKE", "BETWEEN",
		"EXISTS", "HAVING", "GROUP", "BY", "ORDER", "ASC", "DESC", "LIMIT", "OFFSET", "UNION",
		"ALL", "DISTINCT", "AS", "CASE", "WHEN", "THEN", "ELSE", "END", "VALUES", "PRIMARY",
		"KEY", "FOREIGN", "REFERENCES", "CONSTRAINT", "UNIQUE", "CHECK", "DEFAULT", "COUNT", "SUM", "AVG",
		"MIN", "MAX", "CAST", "COALESCE", "IF", "BEGIN", "COMMIT", "ROLLBACK", "GRANT", "REVOKE",
		"TRUNCATE", "WITH", "RECURSIVE"
	};

	private static readonly Regex SyntaxPattern = new Regex("(//[^\\n]*|#[^\\n]*)|(\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*')|(\\b\\d+\\.?\\d*[fFdDmMlL]?\\b)|(\\b[A-Z]\\w*(?=\\s*[\\.<\\(]))|(\\b\\w+(?=\\s*\\())|(\\b\\w+\\b)", RegexOptions.Compiled);

	public static bool EnableFilePathHighlight { get; set; } = true;

	public static StackPanel Render(string markdown, Brush textColor, Brush secondaryColor, Brush accentColor, Brush codeBg)
	{
		StackPanel stackPanel = new StackPanel();
		if (string.IsNullOrEmpty(markdown))
		{
			return stackPanel;
		}
		string[] array = markdown.Replace("\r\n", "\n").Split('\n');
		int i = 0;
		while (i < array.Length)
		{
			string text = array[i];
			if (text.TrimStart().StartsWith("```"))
			{
				object obj;
				if (text.TrimStart().Length <= 3)
				{
					obj = "";
				}
				else
				{
					string text2 = text.TrimStart();
					obj = text2.Substring(3, text2.Length - 3).Trim();
				}
				string lang = (string)obj;
				StringBuilder stringBuilder = new StringBuilder();
				for (i++; i < array.Length && !array[i].TrimStart().StartsWith("```"); i++)
				{
					stringBuilder.AppendLine(array[i]);
				}
				if (i < array.Length)
				{
					i++;
				}
				Border element = CreateCodeBlock(stringBuilder.ToString().TrimEnd(), lang, textColor, codeBg, accentColor);
				stackPanel.Children.Add(element);
			}
			else if (string.IsNullOrWhiteSpace(text))
			{
				stackPanel.Children.Add(new Border
				{
					Height = 6.0
				});
				i++;
			}
			else if (Regex.IsMatch(text.Trim(), "^-{3,}$|^\\*{3,}$"))
			{
				stackPanel.Children.Add(new Border
				{
					Height = 1.0,
					Background = secondaryColor,
					Opacity = 0.3,
					Margin = new Thickness(0.0, 8.0, 0.0, 8.0)
				});
				i++;
			}
			else if (text.StartsWith('#'))
			{
				int j;
				for (j = 0; j < text.Length && text[j] == '#'; j++)
				{
				}
				string text2 = text;
				int num = j;
				string text3 = text2.Substring(num, text2.Length - num).Trim();
				if (1 == 0)
				{
				}
				double num2 = j switch
				{
					1 => 20.0, 
					2 => 17.0, 
					3 => 15.0, 
					_ => 14.0, 
				};
				if (1 == 0)
				{
				}
				double fontSize = num2;
				TextBlock textBlock = new TextBlock
				{
					FontSize = fontSize,
					FontWeight = FontWeights.Bold,
					Foreground = textColor,
					TextWrapping = TextWrapping.Wrap,
					Margin = new Thickness(0.0, (j == 1) ? 12 : 8, 0.0, 4.0)
				};
				AddInlines(textBlock.Inlines, text3, textColor, accentColor, codeBg);
				stackPanel.Children.Add(textBlock);
				i++;
			}
			else if (Regex.IsMatch(text, "^\\s*[-*]\\s") || Regex.IsMatch(text, "^\\s*\\d+\\.\\s"))
			{
				Match match = Regex.Match(text, "^(\\s*)([-*]|\\d+\\.)\\s(.*)");
				if (match.Success)
				{
					int num3 = match.Groups[1].Value.Length / 2;
					string value = match.Groups[2].Value;
					string value2 = match.Groups[3].Value;
					bool flag = ((value == "-" || value == "*") ? true : false);
					string text4 = (flag ? "•" : value);
					Grid grid = new Grid
					{
						Margin = new Thickness(12 + num3 * 16, 2.0, 0.0, 2.0)
					};
					grid.ColumnDefinitions.Add(new ColumnDefinition
					{
						Width = new GridLength(18.0)
					});
					grid.ColumnDefinitions.Add(new ColumnDefinition
					{
						Width = new GridLength(1.0, GridUnitType.Star)
					});
					TextBlock element2 = new TextBlock
					{
						Text = text4,
						FontSize = 13.5,
						Foreground = accentColor,
						VerticalAlignment = VerticalAlignment.Top
					};
					Grid.SetColumn(element2, 0);
					grid.Children.Add(element2);
					TextBlock textBlock2 = new TextBlock
					{
						FontSize = 13.5,
						Foreground = textColor,
						TextWrapping = TextWrapping.Wrap,
						VerticalAlignment = VerticalAlignment.Top
					};
					Grid.SetColumn(textBlock2, 1);
					AddInlines(textBlock2.Inlines, value2, textColor, accentColor, codeBg);
					grid.Children.Add(textBlock2);
					stackPanel.Children.Add(grid);
				}
				i++;
			}
			else if (text.TrimStart().StartsWith('>'))
			{
				List<string> list = new List<string>();
				for (; i < array.Length && array[i].TrimStart().StartsWith('>'); i++)
				{
					string text5 = array[i].TrimStart();
					object item;
					if (text5.Length <= 1)
					{
						item = "";
					}
					else
					{
						string text2 = text5;
						item = text2.Substring(1, text2.Length - 1).TrimStart();
					}
					list.Add((string)item);
				}
				Border border = new Border
				{
					BorderBrush = accentColor,
					BorderThickness = new Thickness(3.0, 0.0, 0.0, 0.0),
					Padding = new Thickness(12.0, 6.0, 8.0, 6.0),
					Margin = new Thickness(4.0, 4.0, 0.0, 4.0),
					Background = new SolidColorBrush(Color.FromArgb(16, byte.MaxValue, byte.MaxValue, byte.MaxValue))
				};
				TextBlock textBlock3 = new TextBlock
				{
					FontSize = 13.0,
					FontStyle = FontStyles.Italic,
					Foreground = secondaryColor,
					TextWrapping = TextWrapping.Wrap,
					LineHeight = 20.0
				};
				AddInlines(textBlock3.Inlines, string.Join("\n", list), textColor, accentColor, codeBg);
				border.Child = textBlock3;
				stackPanel.Children.Add(border);
			}
			else if (text.Contains('|') && text.Trim().StartsWith('|'))
			{
				List<string> list2 = new List<string>();
				for (; i < array.Length && array[i].Contains('|'); i++)
				{
					list2.Add(array[i]);
				}
				FrameworkElement frameworkElement = CreateMarkdownTable(list2, textColor, accentColor, codeBg);
				if (frameworkElement != null)
				{
					stackPanel.Children.Add(frameworkElement);
				}
			}
			else
			{
				TextBlock textBlock4 = new TextBlock
				{
					FontSize = 13.5,
					Foreground = textColor,
					TextWrapping = TextWrapping.Wrap,
					LineHeight = 22.0,
					Margin = new Thickness(0.0, 2.0, 0.0, 2.0)
				};
				AddInlines(textBlock4.Inlines, text, textColor, accentColor, codeBg);
				stackPanel.Children.Add(textBlock4);
				i++;
			}
		}
		return stackPanel;
	}

	private static void AddInlines(InlineCollection inlines, string text, Brush textColor, Brush accentColor, Brush codeBg)
	{
		string pattern = "(\\[([^\\]]+)\\]\\(([^)]+)\\)|~~(.+?)~~|\\*\\*(.+?)\\*\\*|\\*(.+?)\\*|`(.+?)`|([^*`~\\[]+))";
		MatchCollection matchCollection = Regex.Matches(text, pattern);
		foreach (Match item in matchCollection)
		{
			if (item.Groups[2].Success && item.Groups[3].Success)
			{
				string linkUrl = item.Groups[3].Value;
				Hyperlink hyperlink = new Hyperlink(new Run(item.Groups[2].Value))
				{
					Foreground = accentColor,
					TextDecorations = null,
					Cursor = Cursors.Hand
				};
				hyperlink.Click += delegate
				{
					try
					{
						Process.Start(new ProcessStartInfo(linkUrl)
						{
							UseShellExecute = true
						});
					}
					catch
					{
					}
				};
				inlines.Add(hyperlink);
			}
			else if (item.Groups[4].Success)
			{
				inlines.Add(new Run(item.Groups[4].Value)
				{
					TextDecorations = TextDecorations.Strikethrough,
					Foreground = new SolidColorBrush(Color.FromArgb(153, byte.MaxValue, byte.MaxValue, byte.MaxValue))
				});
			}
			else if (item.Groups[5].Success)
			{
				inlines.Add(new Run(item.Groups[5].Value)
				{
					FontWeight = FontWeights.Bold
				});
			}
			else if (item.Groups[6].Success)
			{
				inlines.Add(new Run(item.Groups[6].Value)
				{
					FontStyle = FontStyles.Italic
				});
			}
			else if (item.Groups[7].Success)
			{
				Border childUIElement = new Border
				{
					Background = codeBg,
					CornerRadius = new CornerRadius(4.0),
					Padding = new Thickness(5.0, 1.0, 5.0, 1.0),
					Margin = new Thickness(1.0, 0.0, 1.0, 0.0),
					Child = new TextBlock
					{
						Text = item.Groups[7].Value,
						FontFamily = new FontFamily("Cascadia Code, Consolas, monospace"),
						FontSize = 12.5,
						Foreground = accentColor
					}
				};
				inlines.Add(new InlineUIContainer(childUIElement)
				{
					BaselineAlignment = BaselineAlignment.Center
				});
			}
			else if (item.Groups[8].Success)
			{
				AddPlainTextWithFilePaths(inlines, item.Groups[8].Value);
			}
		}
	}

	private static void AddPlainTextWithFilePaths(InlineCollection inlines, string text)
	{
		if (!EnableFilePathHighlight)
		{
			inlines.Add(new Run(text));
			return;
		}
		MatchCollection matchCollection = FilePathPattern.Matches(text);
		if (matchCollection.Count == 0)
		{
			inlines.Add(new Run(text));
			return;
		}
		int num = 0;
		foreach (Match item in matchCollection)
		{
			if (item.Index > num)
			{
				int num2 = num;
				inlines.Add(new Run(text.Substring(num2, item.Index - num2)));
			}
			inlines.Add(new Run(item.Value)
			{
				Foreground = new SolidColorBrush(Color.FromRgb(59, 130, 246)),
				FontWeight = FontWeights.Medium
			});
			num = item.Index + item.Length;
		}
		if (num < text.Length)
		{
			int num2 = num;
			inlines.Add(new Run(text.Substring(num2, text.Length - num2)));
		}
	}

	private static FrameworkElement? CreateMarkdownTable(List<string> rows, Brush textColor, Brush accentColor, Brush codeBg)
	{
		if (rows.Count < 2)
		{
			return null;
		}
		string[] array = ParseRow(rows[0]);
		int num = array.Length;
		if (num == 0)
		{
			return null;
		}
		int num2 = 1;
		if (rows.Count > 1 && Regex.IsMatch(rows[1].Trim(), "^[\\|\\s:\\-]+$"))
		{
			num2 = 2;
		}
		Grid grid = new Grid
		{
			Margin = new Thickness(0.0, 6.0, 0.0, 6.0)
		};
		for (int i = 0; i < num; i++)
		{
			grid.ColumnDefinitions.Add(new ColumnDefinition
			{
				Width = new GridLength(1.0, GridUnitType.Star)
			});
		}
		int num3 = 0;
		grid.RowDefinitions.Add(new RowDefinition
		{
			Height = GridLength.Auto
		});
		for (int j = 0; j < num; j++)
		{
			Border border = new Border
			{
				Background = new SolidColorBrush(Color.FromArgb(32, byte.MaxValue, byte.MaxValue, byte.MaxValue)),
				BorderBrush = new SolidColorBrush(Color.FromArgb(48, byte.MaxValue, byte.MaxValue, byte.MaxValue)),
				BorderThickness = new Thickness(0.0, 0.0, (j < num - 1) ? 1 : 0, 1.0),
				Padding = new Thickness(8.0, 5.0, 8.0, 5.0)
			};
			TextBlock child = new TextBlock
			{
				Text = ((j < array.Length) ? array[j] : ""),
				FontSize = 12.0,
				FontWeight = FontWeights.SemiBold,
				Foreground = textColor,
				TextWrapping = TextWrapping.Wrap
			};
			border.Child = child;
			Grid.SetRow(border, num3);
			Grid.SetColumn(border, j);
			grid.Children.Add(border);
		}
		num3++;
		for (int k = num2; k < rows.Count; k++)
		{
			string[] array2 = ParseRow(rows[k]);
			grid.RowDefinitions.Add(new RowDefinition
			{
				Height = GridLength.Auto
			});
			for (int l = 0; l < num; l++)
			{
				Border border2 = new Border
				{
					Background = ((k % 2 == 0) ? new SolidColorBrush(Color.FromArgb(8, byte.MaxValue, byte.MaxValue, byte.MaxValue)) : Brushes.Transparent),
					BorderBrush = new SolidColorBrush(Color.FromArgb(24, byte.MaxValue, byte.MaxValue, byte.MaxValue)),
					BorderThickness = new Thickness(0.0, 0.0, (l < num - 1) ? 1 : 0, 1.0),
					Padding = new Thickness(8.0, 4.0, 8.0, 4.0)
				};
				TextBlock textBlock = new TextBlock
				{
					FontSize = 12.0,
					Foreground = textColor,
					TextWrapping = TextWrapping.Wrap
				};
				AddInlines(textBlock.Inlines, (l < array2.Length) ? array2[l] : "", textColor, accentColor, codeBg);
				border2.Child = textBlock;
				Grid.SetRow(border2, num3);
				Grid.SetColumn(border2, l);
				grid.Children.Add(border2);
			}
			num3++;
		}
		Border border3 = new Border
		{
			CornerRadius = new CornerRadius(6.0),
			BorderBrush = new SolidColorBrush(Color.FromArgb(48, byte.MaxValue, byte.MaxValue, byte.MaxValue)),
			BorderThickness = new Thickness(1.0),
			ClipToBounds = true,
			Margin = new Thickness(0.0, 4.0, 0.0, 4.0)
		};
		border3.Child = grid;
		return border3;
		static string[] ParseRow(string row)
		{
			string text = row.Trim().Trim('|');
			return (from c in text.Split('|')
				select c.Trim()).ToArray();
		}
	}

	private static Border CreateCodeBlock(string code, string lang, Brush textColor, Brush codeBg, Brush accentColor)
	{
		Border border = new Border
		{
			Background = codeBg,
			CornerRadius = new CornerRadius(10.0),
			Margin = new Thickness(0.0, 6.0, 0.0, 6.0),
			Padding = new Thickness(0.0)
		};
		StackPanel stackPanel = new StackPanel();
		Border border2 = new Border
		{
			Background = new SolidColorBrush(Color.FromArgb(30, byte.MaxValue, byte.MaxValue, byte.MaxValue)),
			CornerRadius = new CornerRadius(10.0, 10.0, 0.0, 0.0),
			Padding = new Thickness(14.0, 6.0, 8.0, 6.0)
		};
		Grid grid = new Grid();
		grid.Children.Add(new TextBlock
		{
			Text = (string.IsNullOrEmpty(lang) ? "code" : lang),
			FontSize = 11.0,
			Foreground = accentColor,
			FontWeight = FontWeights.SemiBold,
			VerticalAlignment = VerticalAlignment.Center
		});
		StackPanel stackPanel2 = new StackPanel
		{
			Orientation = Orientation.Horizontal,
			HorizontalAlignment = HorizontalAlignment.Right,
			VerticalAlignment = VerticalAlignment.Center
		};
		string capturedCode = code;
		string capturedLang = lang;
		Button button = CreateCodeHeaderButton("\ue74e", "저장", textColor);
		button.Click += delegate
		{
			try
			{
				string extensionForLang = GetExtensionForLang(capturedLang);
				SaveFileDialog saveFileDialog = new SaveFileDialog
				{
					FileName = "code" + extensionForLang,
					Filter = $"코드 파일 (*{extensionForLang})|*{extensionForLang}|모든 파일 (*.*)|*.*"
				};
				if (saveFileDialog.ShowDialog() == true)
				{
					File.WriteAllText(saveFileDialog.FileName, capturedCode);
				}
			}
			catch
			{
			}
		};
		stackPanel2.Children.Add(button);
		Button button2 = CreateCodeHeaderButton("\ue740", "확대", textColor);
		button2.Click += delegate
		{
			ShowCodeFullScreen(capturedCode, capturedLang, codeBg, textColor);
		};
		stackPanel2.Children.Add(button2);
		Button button3 = CreateCodeHeaderButton("\ue8c8", "복사", textColor);
		button3.Click += delegate
		{
			try
			{
				Clipboard.SetText(capturedCode);
			}
			catch
			{
			}
		};
		stackPanel2.Children.Add(button3);
		grid.Children.Add(stackPanel2);
		border2.Child = grid;
		stackPanel.Children.Add(border2);
		Grid grid2 = new Grid
		{
			Margin = new Thickness(0.0, 0.0, 0.0, 4.0)
		};
		grid2.ColumnDefinitions.Add(new ColumnDefinition
		{
			Width = GridLength.Auto
		});
		grid2.ColumnDefinitions.Add(new ColumnDefinition
		{
			Width = new GridLength(1.0, GridUnitType.Star)
		});
		string[] array = code.Split('\n');
		TextBlock element = new TextBlock
		{
			FontFamily = new FontFamily("Cascadia Code, Consolas, monospace"),
			FontSize = 12.5,
			Foreground = new SolidColorBrush(Color.FromArgb(80, byte.MaxValue, byte.MaxValue, byte.MaxValue)),
			Padding = new Thickness(10.0, 10.0, 6.0, 14.0),
			LineHeight = 20.0,
			TextAlignment = TextAlignment.Right,
			Text = string.Join("\n", Enumerable.Range(1, array.Length))
		};
		Grid.SetColumn(element, 0);
		grid2.Children.Add(element);
		TextBlock textBlock = new TextBlock
		{
			FontFamily = new FontFamily("Cascadia Code, Consolas, monospace"),
			FontSize = 12.5,
			Foreground = textColor,
			TextWrapping = TextWrapping.Wrap,
			Padding = new Thickness(8.0, 10.0, 14.0, 14.0),
			LineHeight = 20.0
		};
		ApplySyntaxHighlighting(textBlock, code, lang, textColor);
		Grid.SetColumn(textBlock, 1);
		grid2.Children.Add(textBlock);
		stackPanel.Children.Add(grid2);
		border.Child = stackPanel;
		return border;
	}

	private static Button CreateCodeHeaderButton(string mdlIcon, string label, Brush fg)
	{
		return new Button
		{
			Background = Brushes.Transparent,
			BorderThickness = new Thickness(0.0),
			Cursor = Cursors.Hand,
			VerticalAlignment = VerticalAlignment.Center,
			Padding = new Thickness(5.0, 2.0, 5.0, 2.0),
			Margin = new Thickness(2.0, 0.0, 0.0, 0.0),
			Content = new StackPanel
			{
				Orientation = Orientation.Horizontal,
				Children = 
				{
					(UIElement)new TextBlock
					{
						Text = mdlIcon,
						FontFamily = new FontFamily("Segoe MDL2 Assets"),
						FontSize = 10.0,
						Foreground = fg,
						Opacity = 0.6,
						VerticalAlignment = VerticalAlignment.Center,
						Margin = new Thickness(0.0, 0.0, 3.0, 0.0)
					},
					(UIElement)new TextBlock
					{
						Text = label,
						FontSize = 10.0,
						Foreground = fg,
						Opacity = 0.6
					}
				}
			}
		};
	}

	private static string GetExtensionForLang(string lang)
	{
		string text = (lang ?? "").ToLowerInvariant();
		if (1 == 0)
		{
		}
		string result;
		switch (text)
		{
		case "csharp":
		case "cs":
			result = ".cs";
			break;
		case "python":
		case "py":
			result = ".py";
			break;
		case "javascript":
		case "js":
			result = ".js";
			break;
		case "typescript":
		case "ts":
			result = ".ts";
			break;
		case "java":
			result = ".java";
			break;
		case "html":
			result = ".html";
			break;
		case "css":
			result = ".css";
			break;
		case "json":
			result = ".json";
			break;
		case "xml":
			result = ".xml";
			break;
		case "sql":
			result = ".sql";
			break;
		case "bash":
		case "sh":
		case "shell":
			result = ".sh";
			break;
		case "powershell":
		case "ps1":
			result = ".ps1";
			break;
		case "bat":
		case "cmd":
			result = ".bat";
			break;
		case "yaml":
		case "yml":
			result = ".yml";
			break;
		case "markdown":
		case "md":
			result = ".md";
			break;
		case "cpp":
		case "c++":
			result = ".cpp";
			break;
		case "c":
			result = ".c";
			break;
		case "go":
			result = ".go";
			break;
		case "rust":
		case "rs":
			result = ".rs";
			break;
		default:
			result = ".txt";
			break;
		}
		if (1 == 0)
		{
		}
		return result;
	}

	private static void ShowCodeFullScreen(string code, string lang, Brush codeBg, Brush textColor)
	{
		Window window = new Window();
		window.Title = "코드 — " + (string.IsNullOrEmpty(lang) ? "code" : lang);
		window.Width = 900.0;
		window.Height = 650.0;
		window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
		window.Background = ((codeBg is SolidColorBrush solidColorBrush) ? new SolidColorBrush(solidColorBrush.Color) : Brushes.Black);
		Window window2 = window;
		Grid grid = new Grid();
		grid.ColumnDefinitions.Add(new ColumnDefinition
		{
			Width = GridLength.Auto
		});
		grid.ColumnDefinitions.Add(new ColumnDefinition
		{
			Width = new GridLength(1.0, GridUnitType.Star)
		});
		string[] array = code.Split('\n');
		TextBlock element = new TextBlock
		{
			FontFamily = new FontFamily("Cascadia Code, Consolas, monospace"),
			FontSize = 13.0,
			LineHeight = 22.0,
			Foreground = new SolidColorBrush(Color.FromArgb(80, byte.MaxValue, byte.MaxValue, byte.MaxValue)),
			Padding = new Thickness(16.0, 16.0, 8.0, 16.0),
			TextAlignment = TextAlignment.Right,
			Text = string.Join("\n", Enumerable.Range(1, array.Length))
		};
		Grid.SetColumn(element, 0);
		grid.Children.Add(element);
		TextBlock textBlock = new TextBlock
		{
			FontFamily = new FontFamily("Cascadia Code, Consolas, monospace"),
			FontSize = 13.0,
			LineHeight = 22.0,
			Foreground = textColor,
			TextWrapping = TextWrapping.Wrap,
			Padding = new Thickness(8.0, 16.0, 16.0, 16.0)
		};
		ApplySyntaxHighlighting(textBlock, code, lang, textColor);
		Grid.SetColumn(textBlock, 1);
		grid.Children.Add(textBlock);
		ScrollViewer content = new ScrollViewer
		{
			VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
			HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
			Content = grid
		};
		window2.Content = content;
		window2.Show();
	}

	private static HashSet<string> GetKeywordsForLang(string lang)
	{
		string text = lang.ToLowerInvariant();
		if (1 == 0)
		{
		}
		HashSet<string> result;
		switch (text)
		{
		case "csharp":
		case "cs":
		case "c#":
			result = CSharpKeywords;
			break;
		case "python":
		case "py":
			result = PythonKeywords;
			break;
		case "javascript":
		case "js":
		case "jsx":
			result = JsKeywords;
			break;
		case "typescript":
		case "ts":
		case "tsx":
			result = JsKeywords;
			break;
		case "java":
		case "kotlin":
		case "kt":
			result = JavaKeywords;
			break;
		case "sql":
		case "mysql":
		case "postgresql":
		case "sqlite":
			result = SqlKeywords;
			break;
		case "go":
		case "golang":
			result = new HashSet<string>(StringComparer.Ordinal)
			{
				"break", "case", "chan", "const", "continue", "default", "defer", "else", "fallthrough", "for",
				"func", "go", "goto", "if", "import", "interface", "map", "package", "range", "return",
				"select", "struct", "switch", "type", "var", "nil", "true", "false", "append", "len",
				"cap", "make", "new", "panic", "recover"
			};
			break;
		case "rust":
		case "rs":
			result = new HashSet<string>(StringComparer.Ordinal)
			{
				"as", "async", "await", "break", "const", "continue", "crate", "dyn", "else", "enum",
				"extern", "false", "fn", "for", "if", "impl", "in", "let", "loop", "match",
				"mod", "move", "mut", "pub", "ref", "return", "self", "Self", "static", "struct",
				"super", "trait", "true", "type", "unsafe", "use", "where", "while", "yield", "Box",
				"Vec", "String", "Option", "Result", "Some", "None", "Ok", "Err", "println", "macro_rules"
			};
			break;
		case "cpp":
		case "c++":
		case "c":
		case "h":
		case "hpp":
			result = new HashSet<string>(StringComparer.Ordinal)
			{
				"auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else",
				"enum", "extern", "float", "for", "goto", "if", "inline", "int", "long", "register",
				"return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned",
				"void", "volatile", "while", "class", "namespace", "using", "public", "private", "protected", "virtual",
				"override", "template", "typename", "nullptr", "true", "false", "new", "delete", "throw", "try",
				"catch", "const_cast", "dynamic_cast", "static_cast", "reinterpret_cast", "bool", "string", "include", "define", "ifdef",
				"ifndef", "endif"
			};
			break;
		default:
			result = CSharpKeywords;
			break;
		}
		if (1 == 0)
		{
		}
		return result;
	}

	private static void ApplySyntaxHighlighting(TextBlock tb, string code, string lang, Brush defaultColor)
	{
		if (string.IsNullOrEmpty(lang) || string.IsNullOrEmpty(code))
		{
			tb.Text = code;
			return;
		}
		HashSet<string> keywordsForLang = GetKeywordsForLang(lang);
		bool flag;
		switch (lang.ToLowerInvariant())
		{
		case "python":
		case "py":
		case "bash":
		case "sh":
		case "shell":
		case "ruby":
		case "rb":
		case "yaml":
		case "yml":
		case "toml":
		case "powershell":
		case "ps1":
			flag = true;
			break;
		default:
			flag = false;
			break;
		}
		bool flag2 = flag;
		foreach (Match item in SyntaxPattern.Matches(code))
		{
			if (item.Groups[1].Success)
			{
				string value = item.Groups[1].Value;
				if (value.StartsWith('#') && !flag2)
				{
					tb.Inlines.Add(new Run(value)
					{
						Foreground = defaultColor
					});
				}
				else
				{
					tb.Inlines.Add(new Run(value)
					{
						Foreground = CommentBrush,
						FontStyle = FontStyles.Italic
					});
				}
			}
			else if (item.Groups[2].Success)
			{
				tb.Inlines.Add(new Run(item.Groups[2].Value)
				{
					Foreground = StringBrush
				});
			}
			else if (item.Groups[3].Success)
			{
				tb.Inlines.Add(new Run(item.Groups[3].Value)
				{
					Foreground = NumberBrush
				});
			}
			else if (item.Groups[4].Success)
			{
				string value2 = item.Groups[4].Value;
				tb.Inlines.Add(new Run(value2)
				{
					Foreground = (keywordsForLang.Contains(value2) ? KeywordBrush : TypeBrush)
				});
			}
			else if (item.Groups[5].Success)
			{
				string value3 = item.Groups[5].Value;
				if (keywordsForLang.Contains(value3))
				{
					tb.Inlines.Add(new Run(value3)
					{
						Foreground = KeywordBrush
					});
				}
				else
				{
					tb.Inlines.Add(new Run(value3)
					{
						Foreground = MethodBrush
					});
				}
			}
			else if (item.Groups[6].Success)
			{
				string value4 = item.Groups[6].Value;
				if (keywordsForLang.Contains(value4))
				{
					tb.Inlines.Add(new Run(value4)
					{
						Foreground = KeywordBrush
					});
				}
				else
				{
					tb.Inlines.Add(new Run(value4)
					{
						Foreground = defaultColor
					});
				}
			}
		}
		tb.Inlines.Clear();
		int num = 0;
		foreach (Match item2 in SyntaxPattern.Matches(code))
		{
			if (item2.Index > num)
			{
				InlineCollection inlines = tb.Inlines;
				int num2 = num;
				inlines.Add(new Run(code.Substring(num2, item2.Index - num2))
				{
					Foreground = defaultColor
				});
			}
			if (item2.Groups[1].Success)
			{
				string value5 = item2.Groups[1].Value;
				if (value5.StartsWith('#') && !flag2)
				{
					tb.Inlines.Add(new Run(value5)
					{
						Foreground = defaultColor
					});
				}
				else
				{
					tb.Inlines.Add(new Run(value5)
					{
						Foreground = CommentBrush,
						FontStyle = FontStyles.Italic
					});
				}
			}
			else if (item2.Groups[2].Success)
			{
				tb.Inlines.Add(new Run(item2.Groups[2].Value)
				{
					Foreground = StringBrush
				});
			}
			else if (item2.Groups[3].Success)
			{
				tb.Inlines.Add(new Run(item2.Groups[3].Value)
				{
					Foreground = NumberBrush
				});
			}
			else if (item2.Groups[4].Success)
			{
				string value6 = item2.Groups[4].Value;
				tb.Inlines.Add(new Run(value6)
				{
					Foreground = (keywordsForLang.Contains(value6) ? KeywordBrush : TypeBrush)
				});
			}
			else if (item2.Groups[5].Success)
			{
				string value7 = item2.Groups[5].Value;
				tb.Inlines.Add(new Run(value7)
				{
					Foreground = (keywordsForLang.Contains(value7) ? KeywordBrush : MethodBrush)
				});
			}
			else if (item2.Groups[6].Success)
			{
				string value8 = item2.Groups[6].Value;
				tb.Inlines.Add(new Run(value8)
				{
					Foreground = (keywordsForLang.Contains(value8) ? KeywordBrush : defaultColor)
				});
			}
			num = item2.Index + item2.Length;
		}
		if (num < code.Length)
		{
			InlineCollection inlines2 = tb.Inlines;
			int num2 = num;
			inlines2.Add(new Run(code.Substring(num2, code.Length - num2))
			{
				Foreground = defaultColor
			});
		}
	}
}
