using System.Collections.ObjectModel;
using System.Runtime.InteropServices;

namespace testirovanie
{
    public class REG_MARK_LIB
    {
        public static List<int> regions = new List<int>([52, 77]);
        public static List<String> serias = new List<string>(["А", "В", "Е", "К", "М", "Н", "О", "Р", "С", "Т", "У", "Х"]);
        public static Boolean CheckMark(String mark)
        {
            if (mark.Length == 0) return false;
            int number;
            try
            {
                number = int.Parse(mark.Substring(1, 3));
            } catch (FormatException)
            {
                return false;
            }
            String seria = String.Concat(mark[0], mark.Substring(4, 2));
            int region = int.Parse(mark.Substring(6));
            Console.WriteLine(number);
            Console.WriteLine(seria);
            Console.WriteLine(region);
            if (!regions.Contains(region)) return false;
            if (!(serias.Contains(seria.Substring(0, 1)) && serias.Contains(seria.Substring(1, 1)) && serias.Contains(seria.Substring(2, 1)))) return false;
            return true;
        }
        private static String GetNextLetter(String letter)
        {
            String ans = String.Empty;
            if (!serias.Contains(letter)) return ans;
            int index = serias.IndexOf(letter);
            if (index == serias.Count - 1) return ans;
            return serias[index + 1];
        }
        public static String GetNextMarkAfter(String mark)
        {
            String res = String.Empty;
            if (!CheckMark(mark)) return res;
            int number = int.Parse(mark.Substring(1, 3));
            String seria = String.Concat(mark[0], mark.Substring(4, 2));
            int region = int.Parse(mark.Substring(6));
            if (number + 1 >= 1000)
            {
                int index = 2;
                while (index != -1)
                {
                    String next = GetNextLetter(seria[index].ToString());
                    if (next != String.Empty)
                    {
                        seria = seria.Remove(index).Insert(index, next);
                        break;
                    } else
                    {
                        index--;
                    }
                }
            } else
            {
                number++;
            }
            res += seria[0];
            res += number.ToString();
            res += seria.Substring(1, 2);
            res += region.ToString();
            return res;
        }
        public static String GetNextMarkAfterInRange(String prevMark, String rangeStart, String rangeEnd)
        {
            if (!(CheckMark(prevMark) && CheckMark(rangeStart) && CheckMark(rangeEnd)))
            {
                return "out of stock";
            }
            int numberStart = int.Parse(rangeStart.Substring(1, 3));
            String seriaStart = String.Concat(rangeStart[0], rangeStart.Substring(4, 2));
            int regionStart = int.Parse(rangeStart.Substring(6));
            int numberEnd = int.Parse(rangeEnd.Substring(1, 3));
            String seriaEnd = String.Concat(rangeEnd[0], rangeEnd.Substring(4, 2));
            int regionEnd = int.Parse(rangeEnd.Substring(6));
            int numberPrev = int.Parse(prevMark.Substring(1, 3));
            String seriaPrev = String.Concat(prevMark[0], prevMark.Substring(4, 2));
            int regionPrev = int.Parse(prevMark.Substring(6));
            int a = GetSeriaNumber(seriaPrev) * 1000 + numberPrev + 1;
            int b = GetSeriaNumber(seriaStart) * 1000 + numberStart + 1;
            int c = GetSeriaNumber(seriaEnd) * 1000 + numberEnd + 1;
            if (a >= b - 1 && a < c)
            {
                return GetNextMarkAfter(prevMark);        
            }
            return "out of stock";
        }
        public static int GetSeriaNumber(String serial)
        {
            int rez = 0;
            int j = 0;
            for (int i = 2; i >= 0; i--, j++)
            {
                rez += (int) (GetLetterNumber(serial[i].ToString()) * Math.Pow(serias.Count(), j));
            }
            return rez;
        }
        private static int GetLetterNumber(String letter)
        {
            if (!serias.Contains(letter)) return 0;
            return serias.IndexOf(letter); ; 
        }
        public static int GetCombinationsCountInRange(String mark1, String mark2) 
        {
            if (!CheckMark(mark1) || !CheckMark(mark2)) return 0;
            int number1 = int.Parse(mark1.Substring(1, 3));
            String seria1 = String.Concat(mark1[0], mark1.Substring(4, 2));
            int region1 = int.Parse(mark1.Substring(6));
            int number2 = int.Parse(mark2.Substring(1, 3));
            String seria2 = String.Concat(mark2[0], mark2.Substring(4, 2));
            int region2 = int.Parse(mark2.Substring(6));
            int a = GetSeriaNumber(seria1) * 1000 + number1 + 1;
            int b = GetSeriaNumber(seria2) * 1000 + number2 + 1;
            return Math.Abs(a - b);
        }
    }
}
