using System.Text;

namespace Zerolauncher.util
{
    class SpaceEncoder
    {
        const int mini_index = 48;
        const int max_index = 70;
        const int sec_index = 60;
        static readonly List<char> map = [
            (char)8192,
            (char)8194,
            (char)8196,
            (char)8197,
            (char)8198,
            (char)8199,
            (char)8200,
            (char)8201,
            (char)8202,
            (char)8239,
            (char)8287,
            (char)32
        ];

        public static string? Encode(string hex)
        {
            StringBuilder sb = new StringBuilder();
            foreach (char c in hex)
            {
                if (mini_index > c && max_index < c)
                {
                    return null;
                }
                if (c < sec_index)
                {
                    sb.Append(map[c - mini_index]);
                }
                else
                {
                    sb.Append(map[11]);
                    sb.Append(map[c - sec_index]);
                }
            }
            if (sb[1] == 8200)
            {
                StringBuilder sb1 = new StringBuilder();
                sb1.Append((char)8193);
                sb1.Append(sb);
                return sb1.ToString();
            }
            return sb.ToString();
        }

        public static string? Decode(string hex, out int counter)
        {
            StringBuilder sb = new StringBuilder();
            bool double_char = false;
            counter = 0;
            foreach (char c in hex)
            {
                if (sb.Length == 64) break;
                if (counter == 0 && c == 8193) continue;
                counter++;
                if (!map.Contains(c)) return null;
                if (c != map[11])
                {
                    int j = map.FindIndex(item => item.Equals(c));
                    if (double_char)
                    {
                        int k = j + sec_index;
                        if (k > max_index) return null;
                        sb.Append((char)k);
                        double_char = false;
                    }
                    else sb.Append((char)(j + mini_index));
                }
                else
                {
                    if (double_char) return null;
                    double_char = true;
                }
            }
            return sb.ToString();
        }
    }

	class UrlEncoder
	{
		static readonly Dictionary<char, char> map = new Dictionary<char, char> {
			{'0',  (char)8194},
			{'1',  (char)8196},
			{'2',  (char)8197},
			{'3',  (char)8198},
			{'4',  (char)8199},
			{'5',  (char)8200},
			{'6',  (char)8201},
			{'7',  (char)8202},
			{'8',  (char)8239},
			{'9',  (char)8287},
		};

		static readonly Dictionary<char, char> map1 = new Dictionary<char, char>
		{
			{'.',  (char)8192},
			{':',  (char)8194},
		};

		static readonly Dictionary<char, char> dmap1 = new Dictionary<char, char>
		{
			{(char)8192, '.'},
			{(char)8194, ':'},
		};

		static readonly Dictionary<char, char> dmap = new Dictionary<char, char> {
			{(char)8194, '0'},
			{(char)8196, '1'},
			{(char)8197, '2'},
			{(char)8198, '3'},
			{(char)8199, '4'},
			{(char)8200, '5'},
			{(char)8201, '6'},
			{(char)8202, '7'},
			{(char)8239, '8'},
			{(char)8287, '9'},
		};

		static readonly char end_line = (char)8193;

		static readonly char sec_char = (char)32;

		public static string? Encode(string url, out int counter)
		{
			var sb = new StringBuilder();
			sb.Append(end_line);
			counter = 0;
			foreach (var item in url)
			{
				if (map.ContainsKey(item)) sb.Append(map[item]);
				else if (map1.ContainsKey(item)) { sb.Append(sec_char); sb.Append(map1[item]); }
				else return null;
				counter++;
			}
			sb.Append(end_line);
			return sb.ToString();
		}

		public static string? Decode(string space, out int counter)
		{
			var sb = new StringBuilder();
			counter = 0;
			bool is_sec_char = false;
			foreach (var item in space)
			{
				if (counter != 0)
				{
					if (item == end_line) break;
					else if (is_sec_char)
					{
						if (!dmap1.ContainsKey(item)) return null;
						sb.Append(dmap1[item]);
						is_sec_char = false;
					}
					else if (item == sec_char) is_sec_char = true;
					else if (dmap.ContainsKey(item)) sb.Append(dmap[item]);
					else return null;
				}
				counter++;
			}
			return sb.ToString();
		}
	}


	class KeyUrlEncoder
	{
		static readonly string key = "TestKey123456";

		public static string XorEncryptDecrypt(string input)
		{
			char[] output = new char[input.Length];

			for (int i = 0; i < input.Length; i++)
			{
				output[i] = (char)(input[i] ^ key[i % key.Length]);
			}

			return new string(output);
		}

	}
}
